2

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

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

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

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

我们可以假设两种情况:

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

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

我只对开源方法感兴趣。

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

4

5 回答 5

2

all files have a header. Start from there, see what similarities you have between 2 files, eliminate common "signatures" and work with the differences. They should mark the number of records, export date and similar things.

Common parts between the two headers may just be considered general signatures and i guess you can ignore them

于 2009-11-26T09:21:18.643 回答
2

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

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

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

于 2009-11-26T07:18:00.827 回答
1
  • 比较 2 个或更多文件以寻找相似之处。这通常可以帮助您识别标题块和文件的不同部分。

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

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

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

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

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

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

于 2011-12-07T07:49:18.440 回答
0

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

于 2009-12-18T19:18:34.927 回答
0

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

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

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

于 2011-12-07T07:22:36.467 回答