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

时间:2009-11-26 06:58:55

标签: reverse-engineering binaryfiles

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

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

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

我们可以假设我们有一个相当大的文件集 - 比如说数百个。

我们可以假设两种情况:

  1. 我们可以使用不同的输入重新运行程序,以便我们可以进行实验。
  2. 我们无法重新运行程序 - 我们有一套固定的文件。这与以未知语言(例如,线性B)解码历史文档具有温和的相似性。
  3. 部分解决方案可能是可以接受的 - 即可能有一些领域现在没有活着的人理解,但其他大多数领域都是可解释的。

    我只对开源方法感兴趣。

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

5 个答案:

答案 0 :(得分:2)

如果您使用的是提供 truss 的系统,只需观看您的系统调用即可,您可能会有一个好主意。程序也可以将mmap文件直接复制并从内存中复制,但这种情况不太常见。

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

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

答案 1 :(得分:2)

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

两个标题之间的公共部分可能只被视为一般签名,我想你可以忽略它们

答案 2 :(得分:1)

  • Diff 2个或更多文件以查找相似之处。这通常可以帮助您识别标题块和文件的不同部分。

  • Endianness通常很容易解决 - 更重要的字节往往比不太重要的字节往往更零,所以如果你看到像“00 78”或“78 00”这样的模式你可以很好地猜测哪个字节是msb。但是,当您(粗略地)计算出前面的数据时,这只有任何帮助,以便您知道数据是如何对齐的。

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

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

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

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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