代码之家  ›  专栏  ›  技术社区  ›  peter.murray.rust

在没有文档的情况下,如何解释旧的二进制数据文件?

  •  2
  • peter.murray.rust  · 技术社区  · 15 年前

    数据 通常存储在程序特定的二进制文件中,对于这些文件几乎没有文档或没有文档。在我们的领域中,一个典型的例子是来自仪器的数据,但我怀疑问题是一般性的。试图理解和解释数据有哪些方法?

    设定一些界限。文件没有加密,也没有DRM。文件的类型和格式特定于程序的编写者(即它不是一个“标准文件”,如*.tar,其标识已丢失)。有(可能)没有故意混淆,但可能有一些业余的努力,以节省空间。我们可以假设我们对数据是什么有了一般的了解,并且我们可以识别一些字段和数组,但可能不是全部字段和数组。

    假设大多数数据是数字的,带有标量和数组(可能是一维和二维的,有时是不规则的或三角形的)。还有一些字符串,可能是人名、网站、日期,也可能是一些关键字。程序中有读取二进制文件的代码,但我们没有访问源代码或汇编程序的权限。例如,它可能是由一个vax-fortran程序或一些早期的Unix或Windows作为OLE对象编写的。数字可以是大的或小的尾数(开始时不知道),但可能是一致的。我们 在不同的机器上可能有不同的版本(例如cray)。

    我们可以假设我们有相当大的文件库——比如说,大约几百个。

    我们可以假设两种情况:

    1. 我们可以用不同的输入重新运行程序,这样我们就可以做实验了。
    2. 我们无法重新运行程序-我们有一组固定的文档。这与用一种未知语言(如线性b)解码历史文件略有相似。

    一个部分的解决方案可能是可以接受的——也就是说,可能有一些领域现在没有一个活着的人能理解,但大多数其他领域是可以解释的。

    我只对开源方法感兴趣。

    更新 有一个相关的问题( How to reverse engineer binary file formats for compatibility purposes )但重点有些不同。 更新 @brianege给地址的巧妙建议(1)。使用 truss (或可能) strace 在Linux上)转储程序中的所有write()和类似调用。这至少应允许收集写入磁盘的记录。

    5 回复  |  直到 12 年前
        1
  •  0
  •   blueshift rafaelvalle    13 年前

    这是一个有趣的问题,我认为答案是逆向工程二进制格式是一项获得的技能,但有一些工具可以帮助。

    一个工具是 WinOLS 用于解释和编辑车辆发动机管理计算机二进制图像(主要是查找表中的数字数据)。它支持各种各样的endian格式(我认为不是pdp),以不同的宽度和偏移量查看数据,定义数组区域(map),并使用各种缩放和偏移选项在二维或三维中可视化它们。它还有一个启发式/统计式自动地图查找工具,可能对您有用。

    这是一个商业工具,但是免费的演示会让你做任何事情,除了保存对二进制文件的更改,并使用你不需要的引擎管理功能。您说过您只对开源解决方案感兴趣,但这是stackoverflow,其他人可能不会那么挑剔。

        2
  •  2
  •   Quamis    15 年前

    所有文件都有一个标题。从那里开始,看看两个文件之间有什么相似之处,消除常见的“签名”,并处理不同之处。它们应该标记记录的数量、出口日期和类似的东西。

    两个标题之间的公共部分可能只是一般签名,我想您可以忽略它们。

        3
  •  2
  •   alanc    12 年前

    如果您所在的系统提供 truss ,只需注意系统调用的写入,您可能会有一个好主意。程序也可能会直接从内存中mmap文件并进行复制,但这并不常见。

    $ truss -t write echo foo
    foowrite(1, " f o o", 3)                                = 3
    write(1, "\n", 1)                               = 1
    

    查看二进制文件也可能有意义。在UNIX系统上,您可以使用 反汇编 查看二进制文件的布局。这将指向代码和数据部分。然后您可以打开二进制文件的十六进制编辑器并转到特定的偏移量。你可能对我的 tips for Solaris binary files .

        4
  •  1
  •   Jason Williams    13 年前
    • 差异2或更多文件以查找相似性。这通常有助于识别头块和文件的不同部分。

    • 通常可以很容易地计算出字节结尾-更重要的字节往往比不重要的字节更容易为零,因此如果您看到类似“0078”或“7800”的模式,可以很好地猜测哪个字节是最高位字节。但是,只有当您(粗略地)了解了前面的数据是什么时,这才有帮助,这样您就知道了数据是如何对齐的。

    • 寻找容易识别的数据-字符串是第一个开始的地方,因为您可以很容易地发现它们。这些通常为您提供线索,因为它们通常嵌入在相关数据附近,用作标题等中的节项。如果字符串是Unicode,则通常会看到文本中由零字节分隔的字母,这将帮助您识别数据中该点的端序和数据对齐。

    • 一种常见的格式方法(如iff)是存储数据块,每个数据块都有一个小的头(例如,一个2或4字节的ID,然后是块的2或4字节大小,然后是块的数据)。一般来说,人们使用有意义的(对他们来说)块ID,因此他们很容易被发现-如果你找到一个标签的样子,检查下面的数据看它是否像一个长度(查看数据中的许多字节,看它是否像另一个头)。如果你能识别出这样的格式,你就可以把“一个大文件”问题分解成“许多小文件”问题,这使得它更容易识别。(然而,许多设备数据往往会被“优化”以使其紧凑,在这种情况下,程序员通常会丢弃方便的可扩展格式并将所有内容塞进一起,打包位,通常会使事情对您来说更加困难)

    • 查找已知值。如果您的设备显示“温度:40”,那么您可能会发现该值直接存储在文件中。(使用比例因子或定点值也很常见,因此40可以表示为(例如)40*10=400或40*256=10240)

    • 如果你能足够地控制设备:创建一些简单的文件。您试图获得的是可以从设备中获取的最小文件,以最小化您必须检查的数据。然后对设备进行更改,使文件发生更改-尽量减少更改的次数-然后再次获取文件。如果文件格式是“打开”(未压缩或加密),那么您应该能够识别已更改的字节。

    • 如果您可以将文件“加载”回设备,那么您也可以创建自己的文件,只需更改一个值,看看您是否可以注意到设备上的任何行为变化。如果您设法达到简单的值,这可以很好地工作,但通常您会发现您只是打破文件格式,设备将无法读取其他数据。

        5
  •  0
  •   peter.murray.rust    15 年前

    我希望有一个神奇的实用程序,可以解决模式,尝试不同的结尾等,但似乎没有!