需要解释 64 位汇编指令与 32 位相反

Posted

技术标签:

【中文标题】需要解释 64 位汇编指令与 32 位相反【英文标题】:Need Interpretation of 64bit Assembly Instruction As Opposed to 32bit 【发布时间】:2021-04-13 18:42:06 【问题描述】:

我正在阅读这本书 Hacking : The Art of Exploitation,它使用 32 位汇编,而我的机器是 64 位的。现在我明白这不是一件好事,但这就是问题所在。

当我调试这个程序时,

  Reading symbols from ./a.out...
(gdb) break main
Breakpoint 1 at 0x113d: file first.c, line 6.
(gdb) run
Starting program: /home/kingvon/Desktop/asm/a.out 

Breakpoint 1, main () at first.c:6
6               for(i=0; i < 10; i++)
(gdb) x/3i $rip
=> 0x55555555513d <main+8>:     movl   $0x0,-0x4(%rbp)
   0x555555555144 <main+15>:    jmp    0x555555555156 <main+33>
   0x555555555146 <main+17>:    lea    0xeb7(%rip),%rdi        # 0x555555556004

这是我在我的机器上看到的(64 位),

0x55555555513d <main+8>:     movl   $0x0,-0x4(%rbp)

但在示例中(32 位)给出的说明是:

0x55555555513d <main+8>:     mov   DWORD PTR [ebp-4],0x0

通过阅读 32 位程序集,很明显这应该意味着机器会将 0 的值移动到存储在 EBP 寄存器中的内存位置减 4。我知道两条指令做同样的事情,但我觉得64 指令看起来并不像它的真正含义。 64条指令如何解释/措辞?我知道 64 位上的寄存器名称不同

【问题讨论】:

您展示的两条指令的主要区别不是因为一条是 32 位,一条是 64 位,而是一条是 AT&T 语法,一条是 Intel 语法。操作数颠倒过来,百分号、美元符号和单词“dword ptr”是显着特征。 @prl Book 还声明设置为我已经完成的 intel,但 gdb 停留在&t...我试过 echo "set disassembly-flavor intel" &gt; ~/.gdbinit 并检查了文件,它说它设置为 intel,但是 gdb继续在 at&t 中打印.....编辑 - .gdbinit 中的错字,gdb 现在在 intel 中打印 【参考方案1】:

使用gcc -m32 构建 32 位可执行文件可能是最简单的,这样您就可以更密切地关注本书。不要在学习时尝试将教程移植到另一个操作系统或 ISA,这很少能顺利进行。 (例如,不同的调用约定,而不仅仅是不同的大小。)

在 GDB 中,使用 set disassembly-flavor intel 来获得 GAS .intel_syntax noprefix 反汇编,就像你的书显示的那样,而不是默认的 AT&T 语法。对于 objdump,请使用 objdump -drwC -Mintel。有关查看 GCC 输出的更多信息,另请参阅 How to remove "noise" from GCC/clang assembly output?。

(参见 https://***.com/tags/att/info 与 https://***.com/tags/intel_syntax/info)。

两条指令都是立即数 0 的双字存储,相对于帧指针指向的位置偏移 -4。(这就是它实现 i=0 的方式,因为您通过优化编译已禁用。)

【讨论】:

我试过 -m32,但 gcc 吐出/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory 27 | #include &lt;bits/libc-header-start.h&gt; @raincouver: 所以安装你的发行版的gcc-multilib 包或者它叫什么,比如Arch 的lib32-gcc-libs。 (没有它,您可以构建和链接纯 asm 静态可执行文件,您可以在其中编写自己的 _start 并且不链接任何库,但其他所有内容都需要 /usr/lib32/libc.so 等等,是的,32 位标头甚至编译。) 我已将 gdb 设置为 intel,并将 .gdbinit 编辑为 intel,但 gdb 不会更改为 intel。编辑 - 我在 .gdbinit 中打错字,问题现已修复

以上是关于需要解释 64 位汇编指令与 32 位相反的主要内容,如果未能解决你的问题,请参考以下文章

BFD_RELOC_64:使用 C++ 在 32 位 linux 上编译汇编器指令

优化系列汇编优化技术:X86架构汇编优化及demo

汇编,寄存器,内存,mov指令

汇编指令和寄存器

8086汇编语言 汇编语言伪指令

汇编语言各种指令的解释与用法