将目标文件转换为另一种架构

时间:2012-12-30 14:35:58

标签: linux x86 arm cpu-architecture

我正在尝试使用带有Raspberry Pi的Wifi-Dongle。加密狗的供应商提供了一个Linux驱动程序,我可以在ARM体系结构上成功编译,但是,驱动程序附带的一个目标文件是针对x86体系结构进行预编译的,这会导致链接器失败。

我知道再次编译那个(非常大的)文件要容易得多,但我无法访问源代码。

是否可以将该对象文件从x86架构转换为ARM架构?

谢谢!

7 个答案:

答案 0 :(得分:7)

嗯,不,它看起来像浪费时间。 Wi-Fi驱动程序很复杂,你说这个麻烦的目标文件是“大”的。翻译的痛苦很多,成功调试的机会很少。此外,在此一个目标文件和系统其余部分之间传递的任何参数都不会直接在x86和ARM之间进行转换。

答案 1 :(得分:4)

理论上,是的。在没有访问源代码的情况下在真正的内核驱动程序上执行它将很困难。

如果您对目标文件进行了高质量的反汇编,并且目标文件中的代码“表现良好”(使用标准调用约定,没有自修改代码),那么您可以自动将X86指令转换为arm指令。但是,您可能没有高质量的拆卸。特别是,对象文件的某些部分可能无法正确分类为执行正常递归下降分解的代码或数据。如果您将数据误解为代码,它将被转换为ARM代码,而不是按原样复制,因此将具有错误的值。这可能会导致代码无法正常工作。

即使您很幸运,并且可以正确地对目标文件中的所有地址进行分类,但仍有几个问题会让您失望:

  1. X86上的调用约定与ARM上的调用约定不同。这意味着您必须识别与X86调用约定相关的模式,并将其更改为使用ARM调用约定。这是一个非常重要的改写。

  2. ARM上的硬件接口与X86上的硬件接口不同。您必须了解驱动程序如何工作才能翻译代码。这需要大量的X86硬件可比性层,或者需要对驱动程序的工作方式进行逆向工程。如果您可以对驱动程序进行反向工程,则无需翻译它。你可以写一个手臂版本。

  3. ARM和X86之间的内核APIS不同。您将必须了解这些差异以及如何在它们之间进行转换。这可能是非常重要的。

  4. Linux内核使用“替代”机制,当代码首次加载到内核时,它会动态地重写机器代码。例如,在单处理器机器上,锁通常被替换为无操作以改善性能。像“popcnt”这样的指令被替换为不支持它的机器上的函数调用等。它在内核中的使用是非常常见的。根据上面给出的定义,这意味着对象中的代码很可能不是“表现良好”。您必须验证目标文件不使用该机制,或者找到一种方法来翻译它的使用。

  5. X86使用与ARM不同的内存模型。要“安全地”将X86代码转换为ARM(不引入竞争条件),您必须在每次访问内存后引入内存屏障。这将导致ARM芯片真正的糟糕性能。弄清楚何时需要引入内存栅栏(无需在任何地方进行)是一个非常难的问题。这种分析最成功的尝试需要自定义类型系统,而目标文件中没有这些系统。

  6. 您最好的选择(成功的最快途径)是尝试对相关目标文件进行反向工程,然后替换它。

答案 2 :(得分:1)

没有合理的方法可以做到这一点。联系制造商并询问他们是否可以在ARM代码中提供相关代码,因为x86对您没用。如果他们无法做到这一点,你将不得不找到硬件[具有ARM版本或所有组件的完全开源]或软件供应商的不同供应商[假设还有另一个供应商]那个来源]。

答案 3 :(得分:0)

您可以通过安装x86 GNU binutils和反汇编来手动翻译x86程序集  objdump的目标文件。可能一些地址会有所不同,但应该是直截了当的。

答案 4 :(得分:0)

是的,您绝对可以进行静态二进制翻译。 x86反汇编是痛苦的,如果这是从高级编译然后它不是它可能是坏的。

真的值得努力吗?可能会尝试使用指令集模拟器。您是否对所使用的指令数进行了分析?需要系统调用等?

你到目前为止在拆卸方面有多远?

答案 5 :(得分:0)

也许该文件只包含wifi固件的二进制转储?如果是这样,您不需要指令翻译,并且可以使用objcopy进行转换。

您可以使用objdump -x file.o并查看obj文件中是否有任何真正的可执行代码,或者它是否只是数据。

答案 6 :(得分:0)

如果您可以使用Hex-Rays反编译器访问IDA,您可以(通过一些工作)将目标文件反编译为C代码,然后尝试为ARM重新编译它。