Search code examples
cassemblydisassembly

"Art of Exploitation" disassembly example isn't the same (C code)


I'm following the example in the Art of Exploitation book to try and disassemble a program in C, while the book comes with its own Linux LiveCD, I prefer using BT5 (32 bit).

The code example is very simple - (I've used it the same)

#include <stdio.h>

int main()
{
  int i;
  for(i=0; i < 10; i++)       // Loop 10 times.
  {
    puts("Hello, world!\n");  // put the string to the output.
  }
  return 0;                   // Tell OS the program exited without errors.
}

The author is using

gcc file_name.c

to compile the code, and I use the almost the same syntax but with -o in order to save the compiled path to where I want.

Then he uses the command -

objdump -D loop | grep -A20 main.:

to examine the compiled binary.

This is his output -

reader@hacking:~/booksrc $ objdump -D a.out | grep -A20 main.:
08048374 <main>:
 8048374:       55                      push   %ebp
 8048375:       89 e5                   mov    %esp,%ebp
 8048377:       83 ec 08                sub    $0x8,%esp
 804837a:       83 e4 f0                and    $0xfffffff0,%esp
 804837d:       b8 00 00 00 00          mov    $0x0,%eax
 8048382:       29 c4                   sub    %eax,%esp
 8048384:       c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffc(%ebp)
 804838b:       83 7d fc 09             cmpl   $0x9,0xfffffffc(%ebp)
 804838f:       7e 02                   jle    8048393 <main+0x1f>
 8048391:       eb 13                   jmp    80483a6 <main+0x32>
 8048393:       c7 04 24 84 84 04 08    movl   $0x8048484,(%esp)
 804839a:       e8 01 ff ff ff          call   80482a0 <printf@plt>
 804839f:       8d 45 fc                lea    0xfffffffc(%ebp),%eax
 80483a2:       ff 00                   incl   (%eax)
 80483a4:       eb e5                   jmp    804838b <main+0x17>
 80483a6:       c9                      leave
 80483a7:       c3                      ret
 80483a8:       90                      nop
 80483a9:       90                      nop
 80483aa:       90                      nop
reader@hacking:~/booksrc $

and this is my output for the same program -

root@bt:~# objdump -D loop | grep -A20 main.:

080483e4 <main>:
 80483e4:   55                      push   %ebp
 80483e5:   89 e5                   mov    %esp,%ebp
 80483e7:   83 e4 f0                and    $0xfffffff0,%esp
 80483ea:   83 ec 20                sub    $0x20,%esp
 80483ed:   c7 44 24 1c 00 00 00    movl   $0x0,0x1c(%esp)
 80483f4:   00 
 80483f5:   eb 11                   jmp    8048408 <main+0x24>
 80483f7:   c7 04 24 e0 84 04 08    movl   $0x80484e0,(%esp)
 80483fe:   e8 15 ff ff ff          call   8048318 <puts@plt>
 8048403:   83 44 24 1c 01          addl   $0x1,0x1c(%esp)
 8048408:   83 7c 24 1c 09          cmpl   $0x9,0x1c(%esp)
 804840d:   7e e8                   jle    80483f7 <main+0x13>
 804840f:   b8 00 00 00 00          mov    $0x0,%eax
 8048414:   c9                      leave  
 8048415:   c3                      ret    
 8048416:   90                      nop
 8048417:   90                      nop
 8048418:   90                      nop
 8048419:   90                      nop
 804841a:   90                      nop
root@bt:~# 

Do you think there's a difference because I'm not using the same Linux Distribution? It also looks like his code is calling the printf() function while mine is calling the puts() function (like he used in his example).


Solution

  • It doesn't have to be the OS difference, it's enough if you use different version of GCC to produce different machine code / assembly code.

    Regarding puts / printf - the compiler uses whatever it decides better (in terms of efficiency, security etc.) when you call printf with no format, there is no need for it, so he uses puts which is faster.