2

I'm re-working through the initial assembly section of Hacking: The Art of Exploitation and am having trouble understanding what the function epilogue is doing in this program. Am I correct in assuming this is re-pointing the stack frame and moving 0 into EAX for the return?

A break down from 80491b8 onward would be useful. Thank you.

#include <stdio.h>

int main()
{
  int i;
  for(i=0; i < 10; i++)
  {
    printf("Hello World!\n");
  }
}

Forgive the annotations, this is me working through it.

######################### FUNCION PROLOGUE ############################
08049176 <main>:
 8049176:   8d 4c 24 04             lea    ecx,[esp+0x4]
 804917a:   83 e4 f0                and    esp,0xfffffff0
 804917d:   ff 71 fc                push   DWORD PTR [ecx-0x4]
 8049180:   55                      push   ebp
 8049181:   89 e5                   mov    ebp,esp
 8049183:   53                      push   ebx
 8049184:   51                      push   ecx
 8049185:   83 ec 10                sub    esp,0x10
 8049188:   e8 23 ff ff ff          call   80490b0 <__x86.get_pc_thunk.bx>
 804918d:   81 c3 47 20 00 00       add    ebx,0x2047
########################################################################
# 1. Move 0 into variable i
 8049193:   c7 45 f4 00 00 00 00    mov    DWORD PTR [ebp-0xc],0x0
# 2. Jump to initial comparison
 804919a:   eb 16                   jmp    80491b2 <main+0x3c>
# 4. Loop body - subtract 12 from stack pointer (in 32 bit compatibility mode 4 + 8)
 804919c:   83 ec 0c                sub    esp,0xc
# 5. Load the address of "Hello World!" into eax
 804919f:   8d 83 34 ee ff ff       lea    eax,[ebx-0x11cc]
# 6. Push eax onto the stack (C calling convention, arguments are pushed in reverse order)
 80491a5:   50                      push   eax
# 7. Call printf which is optimized to puts since it ends with newline
 80491a6:   e8 a5 fe ff ff          call   8049050 <puts@plt>
# 8. Add 16 to the stack pointer # TODO: Why
 80491ab:   83 c4 10                add    esp,0x10
# 9. Increment i
 80491ae:   83 45 f4 01             add    DWORD PTR [ebp-0xc],0x1
# 3. Compare and jump if i is less than or equal to 9
 80491b2:   83 7d f4 09             cmp    DWORD PTR [ebp-0xc],0x9
 80491b6:   7e e4                   jle    804919c <main+0x26>
 80491b8:   b8 00 00 00 00          mov    eax,0x0
 80491bd:   8d 65 f8                lea    esp,[ebp-0x8]
 80491c0:   59                      pop    ecx
 80491c1:   5b                      pop    ebx
 80491c2:   5d                      pop    ebp
 80491c3:   8d 61 fc                lea    esp,[ecx-0x4]
 80491c6:   c3                      ret    
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    You'll have an easier time if you use GCC8 or newer to get the much simpler stack-alignment code, and `-fno-pie -no-pie` to avoid the EIP-retrieval thunk, and `-fno-stack-protector`. But see the linked duplicates for the wacky shenanigans that lea/pop is undoing by pointing the stack pointer at the saved regs, then pop, then pointing at the original return address. – Peter Cordes Nov 22 '21 at 06:01
  • Thank you. I had `-no-pie` but `-fno-pie` made quite the difference. – Duderus Smith Nov 22 '21 at 11:20
  • Right, `-fno-pie` is a code-gen option (applies even with `-c`, but not with `gcc foo.o -o foo`), while `-no-pie` is a linker option (meaningless with `-c` or `-S`). – Peter Cordes Nov 22 '21 at 11:34

0 Answers0