如何确定可执行文件中反汇编代码的位置?

发布于 2024-08-09 05:05:44 字数 1013 浏览 12 评论 0原文

我有一个包含错误的可执行文件(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 段中的偏移量。如何计算出打印偏移量和文件顶部之间的字节增量,以便我可以编辑/修补文件中的正确字节?

感谢您提供的任何建议!

I've got an executable file (C++, i386, compiled under MacOS/X Tiger, if it matters) that contains a bug. The fix for the bug is straightforward -- there's a place in the code where it calls fork() and it shouldn't. Because the fix is simple, and because recompiling the executable from scratch would be difficult at this point (don't ask), I'd like to just patch the executable/binary file directly.

As a first step towards that, I ran "otool -tV MyExecutableName" on my executable, and voila, I found this in the disassembly output:

./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 ...]

So what I'd like to do is replace the opcode at line 0002ce19, so that instead of calll'ing _fork, it simply jumps unconditionally to the failure case (i.e. it should act as if fork() had returned -1)

Unfortunately, I'm a complete newbie at disassembly/binary patching, so I'm not sure how to go about doing this. In particular, my questions are:

1) What bytes should I write into locations 0002ce19 through 0002xe1d to get what I want? I assume it would be the assembled equivalent of "jmp 0x0002cf02", but how do I figure out what those bytes are?

2) The offsets printed by "otool -tV" appear to be offsets into the __TEXT segment of the executable. How can I figure out the byte-delta between the printed offsets and the top of the file, so that I can edit/patch the correct bytes within the file?

Thanks for any advice you can give!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回眸一笑 2024-08-16 05:05:44

我对 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

如果该序列在如果您无法使用反汇编程序,则可以尝试将 E8AB3C8200 更改为 B8FFFFFFFF

I'm not familiar with the MacOS/X but I can give you some hints.

The proper way to fix it, is to use a disassembler to patch your file.

0002ce19        calll   0x00850ac9

can be replaced with

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

The offsets you see are relative, so you can not find them in the file.
For example, jll 0x0002cf02 is actually jll 0x000000DF

If I'm correct, the below code block

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

will have this assembled form (20 bytes):

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

If that sequence is unique in the file then you can try to change the E8AB3C8200 to B8FFFFFFFF, if you can't use a disassembler.

夜吻♂芭芘 2024-08-16 05:05:44

也许最简单的方法是用 mov $-1, %eax 代替调用。您可以通过将其放入 .s 文件中、编译并转储结果来找出对应的字节,如果它比补丁位置短,则用 nops 填充。我得到“b8 ff ff ff ff”,正好合适。

您可以通过运行otool -l 并查找偏移量来找到__TEXT 的开头。

Probably the easiest would be to put mov $-1, %eax in place of the call. You can find out what bytes that corresponds to by putting it in a .s file, compiling it, and dumping the result, padding with nops if it is shorter than the patch location. I get "b8 ff ff ff ff", which just fits.

You can find the start of __TEXT by running otool -l and looking for the offset.

甲如呢乙后呢 2024-08-16 05:05:44

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

otx and Hex Fiend will be your friends. otx will give you a disassembly with file-relative offsets, and Hex Fiend will let you patch out the jump. Remember that 0x90 is the (x86) opcode for NOP, so 9090909090 is an appropriate replacement for the fork() call. (Just keep in mind that it won't generate a return value, so something weird may end up in eax.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文