如何理解objdump的输出,关于间接jmp?

时间:2015-03-05 07:29:17

标签: linux kernel reverse-engineering x86-64 disassembly

当objdump -S my_program时,通常我可以看到以下间接jmp指令,它通常用于切换/案例跳转表:

ffffffff802e04d3: ff 24 d5 38 2e 10 81 jmpq *-0x7eefd1c8(,%rdx,8)

如何理解地址-0x7eefd1c8?这意味着表的基地址是0xffffffff802e04d3 - 0x7eefd1c8

另外,如何从-0x7eefd1c8获取ff 24 d5 38 2e 10 81

1 个答案:

答案 0 :(得分:3)

  

解码问题

比你必须看Intel Development Manuals

  • ff是JMP操作码(跳近,绝对间接)[1]
  • 24 ModR / M 字节[2],这意味着 SIB 字节在它之后(JMP操作码只有一个操作数,因此寄存器字段被忽略了)
  • d5是一个 SIB 字节[2],这意味着 disp32 在此之后,Scale = 8Index = %rdx(在32位模式,索引应为%edx),没有基础。
  • 38 2e 10 81是一个4字节的 disp32 操作数。如果您将其编码为双字,则会0x81102e38注意最高位设置为1。这是一个符号位,意味着值在 Two的补码编码 [3]中编码。

从两个补码转换得到我们预期的数字:

>>> print hex(0x81102e38 - (1 << 32))
-0x7eefd1c8 

当处理器在64位模式下执行该指令时,它从0xffffffff81102e38 + (%rdx * 8)读取8个字节(原始数字是符号扩展的)并将该四字字放入%rip [4]。

参考手册:

  1. Vol.2A, 3.2指令(A-M),页 3-440
  2. 第2卷, 2.1.5 ModR / M和SIB字节的寻址模式编码,页 2-6..2-7
  3. 第1卷, 4.2.1.2签名整数,第页4-4
  4. 第2卷, 2.2.1.3位移,页 2-11