X86 asm - 12 bytes subtracted from esp. Total 8
I have compiled this code with gcc (gcc -ggdb -mpreferred-stack-border = 2 -o demo demo.c) and decompiled it to look at the assembly (I know this with unsafe functions, this was for an exercise in buffer overflow) :
#include<stdio.h>
CanNeverExecute()
{
printf("I can never execute\n");
exit(0);
}
GetInput()
{
char buffer[8];
gets(buffer);
puts(buffer);
}
main()
{
GetInput();
return 0;
}
Here is the assembly for the GetInput () function:
(gdb) disas GetInput
Dump of assembler code for function GetInput:
0x08048432 <+0>: push ebp
0x08048433 <+1>: mov ebp,esp
0x08048435 <+3>: sub esp,0xc
=> 0x08048438 <+6>: lea eax,[ebp-0x8]
0x0804843b <+9>: mov DWORD PTR [esp],eax
0x0804843e <+12>: call 0x8048320 <gets@plt>
0x08048443 <+17>: lea eax,[ebp-0x8]
0x08048446 <+20>: mov DWORD PTR [esp],eax
0x08048449 <+23>: call 0x8048340 <puts@plt>
0x0804844e <+28>: leave
0x0804844f <+29>: ret
End of assembler dump.
Here is the assembly for the Main () function:
(gdb) disas main
Dump of assembler code for function main:
0x08048450 <+0>: push ebp
0x08048451 <+1>: mov ebp,esp
0x08048453 <+3>: call 0x8048432 <GetInput>
0x08048458 <+8>: mov eax,0x0
0x0804845d <+13>: pop ebp
0x0804845e <+14>: ret
End of assembler dump.
I set a breakpoint on line 13 (gets (buffer))
From Main (), I can see that the ebp value is pushed onto the stack. Then, when the GetInput () function is called, the ret address is also pushed onto the stack. After the GetInput function is entered, the ebp value is pushed onto the stack again. Now I am confused:
0x08048435 <+3>: sub esp,0xc
The buffer variable is only 8 bytes, so 8 bytes must be subtracted from esp to resolve the local buffer variable.
Stack:
(gdb) x/8xw $esp
0xbffff404: 0x08048360 0x0804847b 0x002c3ff4 0xbffff418
0xbffff414: 0x08048458 0xbffff498 0x00147d36 0x00000001
(gdb) x/x &buffer
0xbffff408: 0x0804847b
0x08048458 is the ret address, 0xbffff418 is the old ebp value, and the 4 bytes of the buffer variable are at 0x0804847b, so I think the other 4 bytes are 0x002c3ff4. But it looks like there are 4 more bytes on the stack.
So my question is, why does it subtract 12 bytes when only 8 bytes are required? What are the extra 4 bytes for?
thank
source to share
This is due
mov DWORD PTR [esp],eax
Apparently, your implementation puts
and gets
requires that the argument has shifted to the stack.
The meaning [ebp-0xc]
is actually [esp]
now, so this one is dword
reserved in advance.
Why is that? Doing this is more efficient because you don't need pop
and push
, but just move eax
to [esp]
so that you spare at least one instruction. However, I think this code went through some optimization because this one is smart.
source to share