Saturday, January 28, 2012

Analyzing DUMP for stack corruption because of string overflow

Today i am going to show an example on how to analyze the DMP file where it is showing the stack corruption.
So, here is my test code:


void fun(int argc, char** argv)
{
if (argc != 2)
{
cout << "Incorrect param" << endl;
return;
}

char str[4];
strcpy(str, argv[1]);

cout << "String passed : " << str << endl;
}

int main(int argc, char** argv)
{
fun(argc, argv);

return 0;
}


And this is how i executed this,

test.exe abcdefghijklmnopqrstuvwxyz
String passed : abcdefghijklmnopqrstuvwxyz
<Program crashed here>


Ofcourse, i am passing a big string (more than the space avialble) and this will cause stack coupption, now look at dump and see how we can get it from DMP

I use kvn command and this is what i got...


0:000> kvn
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0012f95c 00412d9c 0041156b 00000001 00000002 ntdll!DbgBreakPoint
01 0012fd84 00412095 0041156b 00411598 0012fe8c test!_RTC_StackFailure+0x10c (FPO: [Non-Fpo]) (CONV: cdecl)
02 0012fda4 0041156b 10574ac8 10574ac8 0012ff68 test!_RTC_CheckStackVars+0x45 (FPO: [Non-Fpo]) (CONV: fastcall)
03 0012fe8c 706f6e6d 74737271 78777675 3a007a79 test!fun+0xab (FPO: [Non-Fpo]) (CONV: cdecl) [c:\documents and settings\tapesh.maheshwari\my documents\visual studio 2005\projects\test\test\test.cpp @ 28]
04 0012ff68 00412596 00000002 00365778 003633e0 0x706f6e6d
05 0012ffb8 004123dd 0012fff0 7c817077 3a0cf126 test!__tmainCRTStartup+0x1a6 (FPO: [Non-Fpo]) (CONV: cdecl) [f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 597]
06 0012ffc0 7c817077 3a0cf126 01ccddaf 7ffd7000 test!mainCRTStartup+0xd (FPO: [Non-Fpo]) (CONV: cdecl) [f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 414]
07 0012fff0 00000000 00411177 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo])


Please note the BOLD part, this is where WinDBG failed to get the correct function. It means corruption has happened till this point and 'return address' has been overwritten. Let's choose the ChieldEBP of one above and use DD command (because we all know that return address is just before EBP).


0:000> dds 0012fe8c 
0012fe8c  6c6b6a69
0012fe90  706f6e6d
0012fe94  74737271 msctf!TF_CreateCicLoadMutex+0x286
0012fe98  78777675
0012fe9c  3a007a79
0012fea0  01ccddaf
0012fea4  7ffd7000
0012fea8  cccccccc
0012feac  cccccccc
0012feb0  cccccccc
0012feb4  cccccccc
0012feb8  cccccccc
0012febc  cccccccc
0012fec0  cccccccc
0012fec4  cccccccc
0012fec8  cccccccc
0012fecc  cccccccc
0012fed0  cccccccc
0012fed4  cccccccc
0012fed8  cccccccc
0012fedc  cccccccc
0012fee0  cccccccc
0012fee4  cccccccc
0012fee8  cccccccc
0012feec  cccccccc
0012fef0  cccccccc
0012fef4  cccccccc
0012fef8  cccccccc
0012fefc  cccccccc
0012ff00  cccccccc
0012ff04  cccccccc
0012ff08  cccccccc

So, it means the BOLD part should actually contains the 'return address', which is having '706f6e6d' and stack is also pointing to this address. So, it's clear that return address has been overwritten by value 706f6e6d

But, there could be more memory which is overwritten (hopefully), so we can actually try to see 50 more and 50 less address also

0:000> dds 0012fe90-50 0012fe90+50
0012fe40  cccccccc
0012fe44  cccccccc
0012fe48  cccccccc
0012fe4c  cccccccc
0012fe50  cccccccc
0012fe54  cccccccc
0012fe58  cccccccc
0012fe5c  cccccccc
0012fe60  cccccccc
0012fe64  cccccccc
0012fe68  cccccccc
0012fe6c  cccccccc
0012fe70  cccccccc
0012fe74  cccccccc
0012fe78  cccccccc
0012fe7c  cccccccc
0012fe80  cccccccc
0012fe84  64636261
0012fe88  68676665
0012fe8c  6c6b6a69
0012fe90  706f6e6d
0012fe94  74737271 msctf!TF_CreateCicLoadMutex+0x286
0012fe98  78777675
0012fe9c  3a007a79
0012fea0  01ccddaf
0012fea4  7ffd7000
0012fea8  cccccccc
0012feac  cccccccc
0012feb0  cccccccc
0012feb4  cccccccc
0012feb8  cccccccc
0012febc  cccccccc
0012fec0  cccccccc
0012fec4  cccccccc
0012fec8  cccccccc
0012fecc  cccccccc
0012fed0  cccccccc
0012fed4  cccccccc
0012fed8  cccccccc
0012fedc  cccccccc
0012fee0  cccccccc

Please note the BOLD part, this is part which seems to be overwritten. Let's try the DA command (show the memory as string) on the beginning of the potential overwritten data...

0:000> da 0012fe84  
0012fe84  "abcdefghijklmnopqrstuvwxyz"

WOW !! we got the same string which got overwritten (started from address 0012fe84 and goes to 0012fea4 ) over EBP and return address.... corrupting everything :)


No comments: