我是一个非常偶然的装配用户。所以我需要更专家的帮助来解码我必须处理的一小段代码。
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
,对吗?
答案 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前缀没有真正的缺点。