【发布时间】:2016-08-30 23:29:39
【问题描述】:
如何在 arm 上运行 x86 二进制文件(例如 .exe 文件)?正如我在 Wikipedia 上看到的,我需要将模拟平台的二进制数据转换为适合在目标平台上执行的二进制数据。但问题是:我该怎么做?我需要在十六进制编辑器中打开文件并更改?还是别的什么?
【问题讨论】:
标签: architecture binary x86 arm
如何在 arm 上运行 x86 二进制文件(例如 .exe 文件)?正如我在 Wikipedia 上看到的,我需要将模拟平台的二进制数据转换为适合在目标平台上执行的二进制数据。但问题是:我该怎么做?我需要在十六进制编辑器中打开文件并更改?还是别的什么?
【问题讨论】:
标签: architecture binary x86 arm
要成功做到这一点,您必须做两件事.. 一件相对容易,一件非常困难。您不想在十六进制编辑器中手动执行这两个操作。
将机器代码从 x86 转换为 ARM。这很简单,因为您应该能够将每个 x86 操作码映射到一个或多个 ARM 操作码。有不同的方法可以做到这一点,有些方法比其他方法更有效,但可以通过非常简单的映射来完成。
重新映射函数调用(和其他跳转)。这很难,因为使用操作码会改变跳转和返回点的所有偏移量。如果您有动态链接库 (.so),并且我们假设所有库在两个地方都以完全相同的版本提供(充其量是粗略的假设),则您必须重新映射负载。
它本质上是一个机器->机器编译器和链接器。
那么,你能做到吗?当然。
容易吗?没有。
那里可能有商业工具,但我不知道。
【讨论】:
你不能用 binary 做到这一点;note1 这里 binary 表示一个没有符号信息的对象,如 elf 文件。即使使用 elf 文件,这也很难甚至是不可能的。问题在于从 data 中确定 code。如果你解决了这个问题,那么你可以制作反编译器和其他工具。
即使您有一个 elf 文件,编译器也会在 text 段中插入代码中使用的常量。您必须查看许多 操作码 并反向执行 basic block 以找出函数的开始和结束位置。
更好的机制是在 ARM 上模拟 x86。在这里,你可以使用JIT技术来做遇到的翻译,但是你大约加倍的代码空间。此外,代码将执行得很糟糕。 ARM 有 16 个寄存器,而 x86 寄存器匮乏(通常它有隐藏寄存器)。编译器的一项重要工作是分配这些寄存器。 QEMU 是一种可以做到这一点的技术。我不确定它是否在 x86 到 ARM 方向;如前所述,这将是一项艰巨的工作。
注意1: x86 具有不对称的操作码大小。为了识别function prologue 和结语,您必须多次扫描图像。要做到这一点,我认为问题将是类似 O(n!) 其中n 是图像的字节,然后您可能会遇到用汇编程序编码的内联汇编程序和库例程的问题.这也许是可能的,但它非常很难。
【讨论】:
将 x86 二进制文件读取为 utf-8,然后从 ELF 复制到最后一个字符。然后转到 arm 二进制文件并在使用 x86 复制时删除。然后将剪贴板中的 x86 复制到 head。我试过了,它正在工作.
【讨论】: