用Python解析二进制文件
作为一个副项目,我想尝试解析二进制文件(特别是Mach-O文件)。我知道已经有工具可以做到这一点(比如otool),所以我把这当作一个学习练习。
我遇到的问题是,我不太明白如何将找到的二进制元素转换成Python可以理解的格式。例如,Mach-O文件格式的开头有一个头部,它是由C语言的结构体定义的。第一个项目是一个uint_32的“魔法数字”字段。当我执行
magic = f.read(4)
时,我得到
b'\xcf\xfa\xed\xfe'
这开始让我明白了。这实际上是一个4字节的字节数组。但是我想把它当作一个4字节的整数,表示原始的魔法数字。另一个例子是numberOfSections字段。我只想要这个4字节字段表示的数字,而不是一堆字面上的字节数组。
也许我想得不对。有没有人做过类似的事情?我需要写函数来查看这些4字节的字节数组,然后移动和组合它们的值,以产生我想要的数字吗?字节序会不会让我困扰?任何建议都会很有帮助。
3 个回答
我建议你看看这个叫做 Construct
的模块。它提供了一个非常简单易用的界面。
有一个叫做Kaitai Struct的项目,正好解决了这个问题。首先,你需要用一个叫做 .ksy 的文件格式描述文件格式,然后把它编译成一个Python库(其实也可以编译成其他主要编程语言的库),接着你只需import
这个库,哇,解析文件就变得简单了:
from mach_o import MachO
my_file = MachO.from_file("/path/to/your/file")
my_file.magic # => 0xfeedface
my_file.num_of_sections # => some other integer
my_file.sections # => list of objects that represent sections
他们有一个不断增长的文件格式规范库。虽然目前还没有Mach-O文件格式的规范,但像Java的.class
文件或者微软的PE可执行文件的复杂格式都有描述,所以我想为Mach-O格式写规范应该也不是什么大问题。
其实这个工具比Construct或者Hachoir要好,因为它是编译型的(而不是解释型的),所以运行速度更快,而且还包含很多其他有用的工具,比如可视化工具或者格式图表生成器。例如,下面是为PE可执行文件格式生成的解释图:
看看这个 struct
模块:
In [1]: import struct
In [2]: magic = b'\xcf\xfa\xed\xfe'
In [3]: decoded = struct.unpack('<I', magic)[0]
In [4]: hex(decoded)
Out[4]: '0xfeedfacf'