【问题标题】:How can I interpret a legacy binary data file without documentation?如何在没有文档的情况下解释遗留的二进制数据文件?
【发布时间】:2012-08-18 15:11:10
【问题描述】:

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

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

假设大部分数据是数字、标量和数组(可能是一维和二维,有时是不规则或三角形)。还有一些字符串,可能是人名、站点、日期,可能还有一些关键字。程序中会有读取二进制文件的代码,但我们无权访问源代码或汇编程序。例如,它可能是由 VAX Fortran 程序或一些早期的 Unix 或 Windows 作为 OLE 对象编写的。这些数字可能是大端或小端(一开始并不知道),但它可能是一致的。我们 在不同的机器上可能有不同的版本(例如 Cray)。

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

我们可以假设两种情况:

  1. 我们可以使用不同的输入重新运行程序,以便进行实验。
  2. 我们无法重新运行程序 - 我们有一组固定的文档。这与用未知语言(例如线性 B)解码历史文档有轻微的相似性。

部分解决方案可能是可以接受的 - 即,可能有些领域现在没有人能理解,但其他大多数领域是可以解释的。

我只对开源方法感兴趣。

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

【问题讨论】:

    标签: reverse-engineering binaryfiles


    【解决方案1】:

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

    两个标头之间的共同部分可能只是一般的签名,我想你可以忽略它们

    【讨论】:

    • 是否有任何免费实用程序可以简化此操作?
    【解决方案2】:

    如果您在一个提供 truss 的系统上,只需观察您的系统调用 write,您可能会有一个好主意。程序也可能会映射文件并直接从内存中复制,但这不太常见。

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

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

    【讨论】:

    • 谢谢。只是为了澄清它是输出数据,而不是我感兴趣的代码。但是,当然,strings untility 和类似的可能有一些用处。
    【解决方案3】:
    • 比较 2 个或更多文件以查找相似之处。这通常可以帮助您识别标题块和文件的不同部分。

    • 字节顺序通常很容易解决 - 更重要的字节往往比不重要的字节更频繁地为零,所以如果你看到像“00 78”或“78 00”这样的模式,你可以很好地猜测哪个字节是 msb。但是,这仅在您(大致)计算出前面的数据是什么时才有帮助,以便您知道数据是如何对齐的。

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

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

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

    • 如果你能足够控制设备:创建一些简单的文件。您想要实现的是您可以从设备中获取的最小文件,以最大限度地减少您必须检查的数据。然后在导致文件更改的设备上进行更改 - 尽量减少更改次数 - 并再次抓取文件。如果文件格式是“开放的”(未压缩或加密),那么您应该能够识别已更改的字节。

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

        我希望有一个神奇的实用程序可以计算出模式,尝试不同的字节序等。但似乎没有!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-18
          • 2010-09-14
          • 2011-01-22
          • 2018-06-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多