首页 文章

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

提问于
浏览
2

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

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

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

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

我们可以假设两种情况:

  • 我们可以用不同的输入重新运行程序,这样我们就可以进行实验了 .

  • 我们无法重新运行程序 - 我们有一套固定的文件 . 这与以未知语言(例如,线性B)解码历史文档具有温和的相似性 .

部分解决方案可能是可接受的 - 即可能存在一些现在没有活着的人理解的领域,但是其他大多数领域都是可解释的 .

我只对开源方法感兴趣 .

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

5 回答

  • 2

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

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

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

  • 0

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

  • 0

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

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

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

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

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

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

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

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

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

  • 1

    如果你在一个提供 truss 的系统上,只需要看你的系统调用来编写,你也可能会编写一个文件并直接从内存中复制,但这种情况并不常见 .

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

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

相关问题