"剥削艺术"反汇编示例不一样(C代码)

YSY*_*YSY 8 c assembly disassembly

我正在按照"剥削艺术"一书中的示例来尝试用C语言编写程序,而本书附带了自己的Linux LiveCD,我更喜欢使用BT5(32位).

代码示例非常简单 - (我使用它相同)

#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.
}
Run Code Online (Sandbox Code Playgroud)

作者正在使用

gcc file_name.c

编译代码,我使用几乎相同的语法,但使用-o,以便将编译路径保存到我想要的地方.

然后他使用命令 -

objdump -D loop | grep -A20主要:

检查编译的二进制文件.

这是他的输出 -

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 $
Run Code Online (Sandbox Code Playgroud)

这是我同一节目的输出 -

root @bt:〜#objdump -D loop | grep -A20主要:

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:~# 
Run Code Online (Sandbox Code Playgroud)

您是否认为存在差异,因为我没有使用相同的Linux发行版?看起来他的代码printf()在我调用函数时调用puts()函数(就像他在他的例子中使用的那样).

MBy*_*ByD 6

它不一定是操作系统的差异,如果您使用不同版本的GCC来生成不同的机器代码/汇编代码就足够了.

关于puts/ printf- 编译器使用它所决定的更好(在效率,安全性等方面),当你printf没有格式调用时,没有必要,所以他使用puts哪个更快.

  • @MByD - 编译器**会解析格式字符串并警告任何差异...... (2认同)