如何确定可执行文件中反汇编代码的位置?
我有一个包含错误的可执行文件(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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我对 MacOS/X 不熟悉,但我可以给你一些提示。
修复它的正确方法是使用反汇编程序来修补文件。
可以替换为
你看到的偏移量是相对的,所以你在文件中找不到它们。
例如,
jll 0x0002cf02
实际上是jll 0x000000DF
如果我是正确的,下面的代码块
将具有这种汇编形式(20字节):
如果该序列在如果您无法使用反汇编程序,则可以尝试将
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.
can be replaced with
The offsets you see are relative, so you can not find them in the file.
For example,
jll 0x0002cf02
is actuallyjll 0x000000DF
If I'm correct, the below code block
will have this assembled form (20 bytes):
If that sequence is unique in the file then you can try to change the
E8AB3C8200
toB8FFFFFFFF
, if you can't use a disassembler.也许最简单的方法是用 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 runningotool -l
and looking for the offset.otx 和 Hex 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.)