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

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

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

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

我们可以假设两种情况:

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

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

我只对开源方法感兴趣。

更新 有一个相关的SO问题(如何对二进制文件格式进行逆向工程以实现兼容性)但侧重点有所不同。更新 @brianegge 对地址 (1) 的聪明建议。使用 truss (或者可能 strace 在 Linux 上)转储程序中的所有 write() 和类似调用。这至少应该允许将记录集合写入磁盘。

有帮助吗?

解决方案

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

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

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

其他提示

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

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

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

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

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

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

  • 字节顺序通常很容易计算出来 - 较高有效字节比较低有效字节更容易为零,因此,如果您看到类似“00 78”或“78 00”的模式,您可以很好地猜测哪个字节是最高有效位。然而,只有当您(大致)弄清楚前面的数据是什么时,这才有任何帮助,以便您知道数据是如何对齐的。

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

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top