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).
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.
Even if you use the same compiler (gcc) there is no expectation that compiling on different machines on the same day or the same machine on different days will give the same result.
Different versions of gcc, 32 bit vs 64 bit, etc. if you didnt install gcc yourself to exactly match a gcc installed by the author then you likely have a different version and the expectation is the code will be different.
Once you add optimizations and other command line options (related to code generation, -o is not one of those) the differences on the same machine the same day vary dramatically.
I would hope that is not the point of the book, I would expect it teaches you these differences but how to take advantage of some things when you do happen to see them produced. Basically go with what the book came up with as it is probably related to what the book is trying to teach.
bottom line expect the same code to never build the same, some compilers go so far as to put a time stamp in the file insuring that no two builds will never exactly match. gcc in particular is constantly evolving and no two people build it the same way so even with the same source version you can see differences in the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With