I’m researching buffer overflows (on IA32 architecture) and I would like to clarify one particular thing with this example program:
int main(int argc, char **argv) {
char array[512];
if(argc > 1)
strcpy(array, argv[1]);
}
I followed the ebp,esp register change during execution of the assembly code:
Dump of assembler code for function main:
0x080483c4 <+0>: push ebp
0x080483c5 <+1>: mov ebp,esp
0x080483c7 <+3>: sub esp,0x208
0x080483cd <+9>: cmp DWORD PTR [ebp+0x8],0x1
0x080483d1 <+13>: jle 0x80483ed <main+41>
0x080483d3 <+15>: mov eax,DWORD PTR [ebp+0xc]
0x080483d6 <+18>: add eax,0x4
0x080483d9 <+21>: mov eax,DWORD PTR [eax]
0x080483db <+23>: mov DWORD PTR [esp+0x4],eax
0x080483df <+27>: lea eax,[ebp-0x200]
0x080483e5 <+33>: mov DWORD PTR [esp],eax
0x080483e8 <+36>: call 0x80482f4 <strcpy@plt>
0x080483ed <+41>: leave
0x080483ee <+42>: ret
The esp,ebp register values were:
program start
esp: 0xbffff24c
ebp: 0xbffff2c8
push ebp
esp: 0xbffff248
ebp: 0xbffff2c8
mov ebp,esp
esp: 0xbffff248
ebp: 0xbffff248
sub esp,0x208
esp: 0xbffff040
ebp: 0xbffff248
strcpy call (ebp is overwritten)
esp: 0xbffff250
ebp: 0x41414141
when I inputed 520 characters ‘a’, which resulted in EBP, EIP being overflown. And the memory looks like this:
Lower Memory Addresses
0xbffff070: 0xbffff078 0xbffff492 0xaaaaaaaa 0xaaaaaaaa
0xbffff080: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff090: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff0a0: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
0xbffff0b0: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
...
0xbffff270: 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa
Higher Memory Addresses
The thing that interests me is: Why do buffer start at address 0xbffff078, if the ESP points at address 0xbffff040 (when the place for local variable – buffer – is reserved on the stack). The buffer should have been saved at 0xbffff040 address. Can anybody explain why it is not?
The compiler decided to allocate space for both the local variable and the parameters passed to
strcpy()on the stack at the same time.So the array is actually at
esp+8(orebp-0x200, as the compiler refers to it).Edit:
espis different between invocations of the program, especially depending on the number of arguments.0xbffff040or0xbffff070.The buffer is at
0xbffff048, not0xbffff040. Or at0xbffff078, not0xbffff070. Ask the debugger where it is to check.In the memory dump the buffer has
0xaa(I guess this is uninitialized memory before the call). In front of this you can see the two pointers that are passed tostrcpy().