Linux 将对象文件转换为另一个体系结构

Linux 将对象文件转换为另一个体系结构,linux,x86,arm,cpu-architecture,Linux,X86,Arm,Cpu Architecture,我正在尝试使用带有覆盆子Pi的Wifi加密狗。加密狗的供应商提供了一个Linux驱动程序,我可以在ARM体系结构上成功编译该驱动程序,但是,该驱动程序附带的一个对象文件是为x86体系结构预编译的,这会导致链接器失败 我知道重新编译那个(相当大的)文件会容易得多,但我没有访问源代码的权限 是否可以将该对象文件从x86体系结构转换为ARM体系结构 谢谢大家! 您可以通过安装x86 GNU binutils并反汇编来手动翻译x86程序集 对象文件包含objdump。可能有些地址会有所不同,但应该是直截

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

我知道重新编译那个(相当大的)文件会容易得多,但我没有访问源代码的权限

是否可以将该对象文件从x86体系结构转换为ARM体系结构


谢谢大家!

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

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

这样做没有合理的方法。联系制造商,询问他们是否可以在ARM代码中提供相关代码,因为x86对您毫无用处。如果他们不能做到这一点,你必须找到不同的硬件供应商[所有组件都有ARM版本或完全开源],或者软件供应商[假设有其他来源]

是的,您完全可以进行静态二进制翻译。尽管x86反汇编很痛苦,但如果它是从高级别编译的,那么它就不会像可能的那么糟糕

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


到目前为止,您在反汇编方面取得了多大进展?

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


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

理论上,是的。在真正的内核驱动程序上执行此操作而不访问源代码将非常困难

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

即使您运气好,并且能够正确地对目标文件中的所有地址进行分类,也会遇到一些问题:

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

  • ARM上的硬件接口与X86上的不同。为了翻译代码,您必须了解驱动程序是如何工作的。这需要大量的X86硬件可比性层,或者对驱动程序的工作方式进行反向工程。如果你能对驱动程序进行反向工程,那么你就不需要翻译它。你可以写一个arm版本

  • ARM和X86之间的内部内核API不同。你必须理解这些差异以及如何在它们之间进行翻译。这可能不是小事

  • Linux内核使用一种“替代”机制,当代码首次加载到内核时,该机制将动态重写机器代码。例如,在单处理器机器上,锁通常被替换为无操作以提高性能。像“popcnt”这样的指令被不支持它的机器上的函数调用所取代,等等。它在内核中的使用非常普遍。根据上面给出的定义,这意味着对象is文件中的代码很有可能不是“行为良好的”。您必须验证对象文件没有使用该机制,或者找到一种方法来转换它的使用

  • X86使用的内存模型与ARM不同。为了“安全地”将X86代码转换为ARM(而不引入竞争条件),您必须在每次内存访问之后引入内存围栏。这将导致ARM芯片的性能非常差。弄清楚什么时候需要引入内存围栏(而不是在任何地方都这样做)是一个极其困难的问题。这种分析中最成功的尝试需要自定义类型系统,而这在对象文件中是没有的


  • 您最好的选择(成功的最快途径)是尝试对有问题的对象文件进行反向工程,然后替换它。

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

    我认为这需要一个完整的x86代码解释器。您有指向该文件的链接吗?我想试一试。我在Linux方面没有那么丰富的经验,如何获得x86 binutils?在反汇编之后,我需要做什么才能将文件组装回一个对象文件呢?我想你可以直接在linux/arm中使用objdump,它应该理解linux/x86:
    objdump-d file.o
    ,将arm指令写入file.s,然后使用
    as(1)
    gcc(1)
    进行组装。事实上,这是一个不可行的解决方案,任何超过几百个