【问题标题】:Dumped i386 assembly code and recompile as PPC?转储 i386 汇编代码并重新编译为 PPC?
【发布时间】:2015-04-22 00:22:36
【问题描述】:

我使用 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 

...

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

非常感谢您的帮助。

问候

【问题讨论】:

  • 您无法在 ppc 上本地运行 i386 代码。你需要一个模拟器。
  • "提示提示 -- 此代码执行处理器仿真"。我想知道这些汇编命令...“pushl”“movl”等是否可以在PPC上用正确的汇编程序形成一个可运行的文件。谢谢。
  • 此外,它现在是 .s 文件的源代码。一切顺利。
  • 不,每个架构的程序集都不同。仅仅因为它现在是一个文本文件,并不意味着它以任何方式与 ppc 兼容。 ppc 甚至没有 pushlmovl 或 i386 的任何寄存器。
  • 您在这里谈论的是仿真。模拟不是一件容易的事:)

标签: assembly disassembly i386 powerpc otool


【解决方案1】:

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

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

如果您的可执行文件足够老,它可能是"fat binary"。在苹果同时支持 PPC 和 x86 的 Mac 期间,他们会将编译后的 PPC 和 x86 代码打包在一个文件中。根据this answer 判断,您可以使用file 命令检测胖二进制文件。

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

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

【讨论】:

  • 好的,所以我必须手动筛选代码并重新组装它。在实践中经常这样做吗?或者是否有可以简化过渡的自动化工具(自动进行架构重写......?)我从上面的答案中得到(我已经赞成:))在某些情况下,1 条指令可以等于 3。
  • 我不知道任何汇编到汇编的翻译器。使用 C 作为中间体的反编译器可能是最接近的,但我没有看到对它们的任何乐观评论。无论如何,您最终都不会运行“相同的程序”。您将构建一个新程序,使其与第一个程序一样。或者您进行仿真 - 为原始程序提供其运行环境的副本。
  • 典型的路径是采用更高级的语言(例如 C)并将其编译成程序集。从一个程序集转换到另一个程序集是非常罕见且非常痛苦的。
  • @Everyone upvoting above:应该让新手清楚,只有当file 命令输出二进制文件具有 ppc 架构,除了 i386 和/或 x86_64,它是所需的 fat binary 用于此处的讨论线。上面的链接没有显示。对于新手:请参阅下面的答案以获取摘要。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2014-05-28
    • 2016-05-05
    • 2011-06-14
    • 2013-01-22
    • 2023-01-31
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多