I'm currently disassembling some small C programs made in Visual Studio 2012 Express, and I’ve noticed a trend amongst the binaries.
The first set of instructions executed in the main function are always:
SUB ESP,154 ; Doesn't have to be 0x154.
.....
.....
.....
LEA EDI,DWORD PTR SS:[EBP-154]
MOV ECX,55 ; Also doesn't have to be 0x55.
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
So, why does the machine fill the stack with this 0xCCCCCCCC? I've read that it is used by VC++, or something, as a mark for uninitialized space?
Then let's say I am going to put something inside my buffer... The compiler or processor decides to put it at some random point inside this space, but I can't see why it would put it there...
EBP-90 > CCCCCCCC ÌÌÌÌ
EBP-8C > CCCCCCCC ÌÌÌÌ
EBP-88 > CCCCCCCC ÌÌÌÌ
EBP-84 > 00000001 ... ; Why this place?
EBP-80 > CCCCCCCC ÌÌÌÌ
EBP-7C > CCCCCCCC ÌÌÌÌ
EBP-78 > 41414141 AAAA ; Why this far from both the top and bottom of the stack?
EBP-74 > CCCCCC00 .ÌÌÌ
EBP-70 > CCCCCCCC ÌÌÌÌ
EBP-6C > CCCCCCCC ÌÌÌÌ
And...
EBP-14 > CCCCCCCC ÌÌÌÌ
EBP-10 > CCCCCCCC ÌÌÌÌ
EBP-C > 00000000 .... ; Why here?
EBP-8 > CCCCCCCC ÌÌÌÌ
EBP-4 > 7EA7D069 iЧ~ ; I think this is some stack cookie stuff.
EBP ==> >/0017FEA8 ¨þ. ; Saved EBP.
Granted, the 1 and 0 dwords are stored here is because of some if statements, but I’m simply wondering why they are placed where they are. If there is any logic behind it.
You are just seeing the code that's generated by the MSVC compiler when you use the /RTC option. Which enables runtime checks, turned on by default in the debug build. The value 0xcccccccc is magical, it is very good at crashing your program when you use an uninitialized pointer. Or generate a weird int value. Or crash your code when it goes bananas and start to execute data as though it is code. 0xcc is the x86 instruction for INT 3, it invokes a debugger break.
The "why this place" is part of the diagnostics you get from /RTC. It make the compiler allocate local variables with extra space between them. Filled by that magical value. Which makes it very simple to diagnose stack corruption caused by buffer overruns, it just needs to check if the magic values are still there when the function returns.