我有一个包含错误的可执行文件(C++,i386,在 MacOS/X Tiger 下编译,如果有的话)。该错误的修复很简单——代码中有一个地方调用了 fork(),但它不应该调用。因为修复很简单,并且因为此时从头开始重新编译可执行文件会很困难(不要问),所以我想直接修补可执行文件/二进制文件。

作为实现这一目标的第一步,我在可执行文件上运行了“otool -tV MyExecutableName”,瞧,我在反汇编输出中发现了这一点:

./MyExecutableName:
(__TEXT,__text) section
[... many lines omitted ...]
0002ce0d        subl    $0x10,%esp
0002ce10        calll   0x0051adac
0002ce15        movzbl  0x14(%ebp),%esi
0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34
[... many more lines omitted ...]

所以我想做的是替换第 0002ce19 行的操作码,这样它就不会调用 _fork,而是无条件地跳转到失败情况(即它应该表现得好像 fork() 返回了 -1)

不幸的是,我在反汇编/二进制修补方面完全是新手,所以我不知道如何去做这件事。我的问题特别是:

1) 我应该将哪些字节写入位置 0002ce19 到 0002xe1d 才能得到我想要的内容?我假设它是“jmp 0x0002cf02”的汇编等价物,但我如何找出这些字节是什么?

2) “otool -tV”打印的偏移量似乎是可执行文件的 __TEXT 段中的偏移量。如何计算出打印偏移量和文件顶部之间的字节增量,以便我可以编辑/修补文件中的正确字节?

感谢您提供的任何建议!

有帮助吗?

解决方案

我不熟悉的MacOS / X,但我可以给你一些提示。

要解决这个问题的正确方法,是使用反汇编修补您的文件。

0002ce19        calll   0x00850ac9

可以替换

0002ce19        movl   eax, -1 ; mov eax, 0xFFFFFFFF

您看到的偏移量是相对的,所以你不能在文件中找到他们。结果 例如,jll 0x0002cf02实际上jll 0x000000DF

如果我正确的,下面的代码块

0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34

将具有该组装形式(20个字节):

0x  E8   AB3C8200
    83F8 00
    0F8C DF000000
    0F84 0B000000

如果该序列是在文件中独特的,那么你可以尝试改变E8AB3C8200B8FFFFFFFF,如果你不能使用反汇编。

其他提示

也许最简单的将是把mov $-1, %eax到位通话。你可以发现,通过把它在一个.s文件,编译它,并与空指令倾销的结果,填充,如果它比补丁位置短对应于什么字节。我得到 “B8 FF FF FF FF”,这正好适合。

您可以通过运行__TEXT和寻找偏移找到otool -l的开始。

奥克斯六角恶魔 将成为你的朋友。otx 会给你一个带有文件相对偏移量的反汇编,而 Hex Fiend 会让你修补跳转。请记住,0x90 是 NOP 的 (x86) 操作码,因此 9090909090 是 fork() 调用的适当替代。(请记住,它不会生成返回值,因此 eax 中可能会出现一些奇怪的内容。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top