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