我正在尝试将 Wifi-Dongle 与 Raspberry Pi 一起使用。加密狗的供应商提供了一个 Linux 驱动程序,我可以在 ARM 架构上成功编译,但是,驱动程序附带的一个目标文件是为 x86 架构预编译的,这导致链接器失败。
我知道再次编译那个(相当大的)文件会容易得多,但我无权访问源代码。
是否可以将该目标文件从 x86 架构转换为 ARM 架构?
谢谢!
我正在尝试将 Wifi-Dongle 与 Raspberry Pi 一起使用。加密狗的供应商提供了一个 Linux 驱动程序,我可以在 ARM 架构上成功编译,但是,驱动程序附带的一个目标文件是为 x86 架构预编译的,这导致链接器失败。
我知道再次编译那个(相当大的)文件会容易得多,但我无权访问源代码。
是否可以将该目标文件从 x86 架构转换为 ARM 架构?
谢谢!
嗯,不,这在我看来是浪费时间。Wi-Fi 驱动程序很复杂,你说这个麻烦的目标文件是“大”的。翻译有很多痛苦,成功调试的机会微乎其微。此外,在这个目标文件和系统其余部分之间传递的任何参数都不会直接在 x86 和 ARM 之间转换。
理论上,是的。在不访问源代码的情况下在真正的内核驱动程序上执行此操作将很困难。
如果您对目标文件进行了高质量的反汇编,并且目标文件中的代码“表现良好”(使用标准调用约定,没有自修改代码),那么您可以自动将 X86 指令转换为 arm 指令。但是,您可能没有高质量的拆卸。特别是,目标文件的某些部分可能无法正确分类为执行正常递归下降反汇编的代码或数据。如果您将数据误解为代码,它将被转换为 ARM 代码,而不是按原样复制,因此会有错误的值。这可能会导致代码无法正常工作。
即使你很幸运,并且可以正确分类目标文件中的所有地址,也有几个问题会让你大吃一惊:
X86 上的调用约定与 ARM 上的调用约定不同。这意味着您必须识别与 X86 调用约定相关的模式并将它们更改为使用 ARM 调用约定。这是一个不平凡的重写。
ARM 上的硬件接口与 X86 上的不同。您必须了解驱动程序的工作原理才能翻译代码。这将需要一个实质性的 X86 硬件可比性层,或者对驱动程序的工作方式进行逆向工程。如果您可以对驱动程序进行逆向工程,那么您不需要翻译它。你可以只写一个arm版本。
ARM 和 X86 的内部内核 APIS 不同。您将必须了解这些差异以及如何在它们之间进行翻译。这可能不是微不足道的。
Linux 内核使用“替代”机制,当代码首次加载到内核中时,它将动态重写机器代码。例如,在单处理器机器上,锁通常被替换为无操作以提高性能。在不支持它的机器上,诸如“popcnt”之类的指令被替换为函数调用等。它在内核中的使用非常普遍。这意味着根据上面给出的定义,文件中的代码很有可能不是“行为良好”。您必须要么验证目标文件不使用该机制,要么找到一种方法来转换它的使用。
X86 使用与 ARM 不同的内存模型。为了“安全地”将 X86 代码转换为 ARM(不引入竞争条件),您必须在每次内存访问后引入内存栅栏。这将导致 ARM 芯片的性能非常糟糕。弄清楚何时需要引入内存围栏(而不是到处都这样做)是一个非常困难的问题。在这种分析中最成功的尝试需要自定义类型系统,而您在目标文件中没有这些系统。
您最好的选择(通往成功的最快途径)是尝试对相关目标文件的功能进行逆向工程,然后替换它。
没有合理的方法可以做到这一点。联系厂商,询问他们是否可以提供ARM代码中的相关代码,因为x86对你没有用。如果他们无法做到这一点,您将不得不寻找不同的硬件供应商[具有 ARM 版本或所有组件的完全开源],或软件供应商 [假设有另一个的来源]。
是的,您绝对可以进行静态二进制翻译。x86 反汇编虽然是痛苦的,但如果这是从高级别编译的,那么它就没有那么糟糕了。
真的值得努力吗?可以尝试使用指令集模拟器。您是否对使用的指令数量进行了分析?需要系统调用等?
到目前为止,您在拆卸方面已经走了多远?
您可以通过安装 x86 GNU binutils 手动翻译 x86 程序集,并使用 objdump 反汇编目标文件。可能有些地址会有所不同,但应该是直截了当的。
也许该文件仅包含 wifi 固件的二进制转储?如果是这样,您不需要指令翻译,并且可以使用 objcopy 完成转换。
您可以使用 objdump -x file.o 并查看 obj 文件中是否有任何真正的可执行代码,或者它是否只是数据。
如果您可以使用 Hex-Rays 反编译器访问 IDA,您可以(通过一些工作)将目标文件反编译为 C 代码,然后尝试为 ARM 重新编译它。