你要的不是a call
,而是a jmp
,而且你要的是直接的jmp
。直接跳转通常使用相对于下一条指令地址的寻址(请参阅我对 SO 问题的回答:How encode a relative short jmp in x86)。相对于跳转指令的结束是另一种看待它的方式。
所以,你在0x1000027a9
并且想要跳到0x100003b6e
.
0x100003b6e
- 0x1000027a9
= 0x000013C5
= 5061d
,因此绝对不适合短跳转(rel8
在英特尔文档中),但您需要jmp rel32
. 它也适合rel16
,但 x86-64(在 64 位模式下)不支持。
所以,你想要一个jmp rel32
. 这是相对于 之后的下一条指令进行jmp
编码的,并且由于指令的长度是 5 个字节(E9 xx xx xx xx
),rel32
因此将是0x000013C0
。由于 x86 是 little-endian 架构,因此它被编码为E9 C0 13 00 00
.
为了确认这一点,我用 NASM 组装了一个小型测试可执行文件,并用 ndisasm 反汇编它(注意我留下了第一个0x10000000
字节,但由于跳转是相对的,它不会改变编码中的任何内容):
000027A8 90 nop
000027A9 E9C0130000 jmp dword 0x3b6e ; this is the instruction you need.
000027AE 90 nop