3

我正在使用 GDB 调试 Mac OS X 64 位应用程序。我看到跳过一大段代码解决了我所有的问题。

但:

如何修补可执行文件以实现跳转?我希望应用程序在没有调试器的情况下自动跳转到代码中的定义点。

这就是我想要做的:

在 address 0x1000027a9(由调试器给出)跳转到 address 0x100003b6e。我正在努力通过 HexEdit 做到这一点,但没有成功。我在任何地方读到了关于 jmp 到绝对地址操作码的信息(FF似乎是正确的操作码,但它是一个调用,而不是一个跳转......)但没有任何效果。访问不正确,段错误。

我怎样才能做到这一点?

4

1 回答 1

5

你要的不是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
于 2013-02-17T14:59:25.160 回答