0

我使用 Apple 内置的“otool”命令和“-Vvtd”开关来转储 Mach-O i386 二进制文件,重定向到 .s 文件。我曾尝试使用 nasm 和 GAS 汇编器在 PPC 机器上重新编译代码(gcc/darwin 的 i386 目录中的“as”-binary 和 ppc 目录中的“as”-binary),但未成功。输出内容如下:

some_topmost_label:
(__TEXT,__text) section
_default_pager:
00112000    pushl   %ebp
00112001    movl    %esp,%ebp
00112003    pushl   %edi
00112004    pushl   %esi
00112005    pushl   %ebx
00112006    subl    $0x3c,%esp
00112009    movl    _default_pager_internal_count,%ebx
0011200f    addl    _default_pager_external_count,%ebx
00112015    leal    0x00000004(,%ebx,4),%ebx

还有一个数据部分,如下所示:

...

(__DATA,__data) section
00421000    02 00 00 00 04 00 00 00 00 40 00 00 28 64 65 66

...

00449bc0    50 00 3d 00 00 00 00 00 00 00 00 00 00 00 00 00 
00449bd0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

...

我打算在 PPC 上的 Mac 中运行二进制文件,因此需要重新编译;我尝试删除最左侧列中的地址以使语法更像“AT&T”风格,留下它们等等。我不想对现有代码结构进行任何编辑(这不完全是逆向工程,本身,只是一些定制)。但是,如果我必须进行任何编辑,我非常希望它能够严格地使 i386 的现有、纯正代码在 PPC 上运行。

我将非常感谢您的帮助。

问候

4

2 回答 2

4

在汇编语言中,每个“语句”都是处理器可以执行的指令。指令以人类可读的文本格式表示(如果你是正确的人类),但仍然存在于汇编中的每个指令名称(例如movl)和寄存器(例如%esp)和内存引用(例如)直接对应于0x00000004(,%ebx,4)处理器的实现细节。

所以每个处理器真的都有自己的汇编语言。倾倒和重新组装不会让你到任何地方。甚至在一组相关的处理器中也不行——如果您使用一些启用了 SSE3 优化的编译 32 位 x86 代码并将其转储,您将获得带有 SSE3 指令的汇编代码。重新组装它不会得到一个可以在稍旧的 x86-32 处理器上运行的程序。

如果您的可执行文件足够老,则可能有机会成为“胖二进制文件”。在苹果同时支持 PPC 和 x86 的 Mac 期间,它们会将编译后的 PPC 和 x86 代码打包在一个文件中。从这个答案file来看,您可以使用该命令检测胖二进制文件。

但是您可能需要做的工作比您预期的要多得多。

PPC 没有movl指令(或任何其他类型的指令mov- 它分别处理加载和存储)。它没有像 一样的专用堆栈寄存器%esp,尽管r1这是一个安全的选择。它没有任何类似寻址模式的东西0x00000004(,%ebx,4)- 这是一个寄存器乘以 4,然后加上常数 4 - 在 PPC 中,您必须使用一条指令将常数加载到不同的寄存器中,然后移位(*4= <<2)在另一条指令中注册,然后在第三条指令中将这些中间结果相加。这与指令是以“源形式”还是“二进制形式”编写无关。这是原始代码中的指令在PPC 上根本不存在的问题。

于 2015-04-22T01:02:41.890 回答
1

反编译器可以生成 C 文件(正如我所尝试的),这些文件可用于从不同架构上的源代码编译(我也尝试过)。这种体验充其量是冒险的。我仍在努力,可能还会持续一段时间。

作为替代方案,可以实现仿真以在 ppc 上运行 i386 的二进制/可执行文件。这是一条快速但可能不太有效的路线。

此外,我觉得它证实了汇编到汇编将是最痛苦的路线,而不是使用 C 编程语言作为中间语言(通过将 i386 二进制文件反编译为 C 并在目标架构上重新编译 C)。

在反编译的情况下:如果它产生 25 万行代码怎么办?你可能需要一个团队:)

于 2015-04-22T01:52:21.403 回答