用于x64 JMP指令的汇编解码

时间:2016-08-08 17:26:44

标签: assembly x86 x86-64 disassembly machine-code

我是一个非常偶然的装配用户。所以我需要更专家的帮助来解码我必须处理的一小段代码。

0000:  48 ff 25 61 57 07 00    rex.W jmp QWORD PTR [rip+0x75761]        # 0x75768
0007:  cc                      int3

这是内存间接跳转到rip+0x75761保存的8字节/ 64位地址,因此跳转目标的绝对地址是0007 + 0x75761 = 0x75768 ,对吗?

1 个答案:

答案 0 :(得分:2)

这是x86-64上的标准尾调用序列,由Microsoft编译器生成。

是的,正如你所说,它是间接跳转到64位内存地址0x75768。在执行此代码时,rip等于7,因此rip + 0x75761 == 0x7 + 0x75761 == 0x75768。代码将无条件地将控制转移到地址0x75768处的指令。

后续int 3只是填充,但它也可以作为砖墙。由于前一条指令中的无条件分支,执行应该永远不会达到这一点。如果是这样,CPU会陷阱,因为这是“中断”中断。

对于REX.W前缀,harold在技术上是正确的,因为它是不必要的,但不是你可能想到的原因。有点令人惊讶的是,当在x86-64上使用间接跳过寄存器时,Windows需要REX.W前缀以确保堆栈展开成功。堆栈展开代码在内部使用它作为信号。 Ross Ridge撰写了an excellent answer关于Windows x64中以REX为前缀的JMP指令的用途。

在这种情况下并不是绝对必要的,因为这是一个带有IP相对操作数的间接跳转,但编译器显然仍在发送它。它处理这个问题的逻辑可能并不复杂,也许它总是生成这个代码以保持一致性。或者官方文档可能并不全面了解堆栈展开代码是如何实现的。比抱歉更安全,因为额外的REX.W前缀没有真正的缺点。