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

+3


source to share


1 answer


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.

+5


source







All Articles