如何最好地比较两个编译的二进制文件? [关闭]

Posted

技术标签:

【中文标题】如何最好地比较两个编译的二进制文件? [关闭]【英文标题】:How best to compare two compiled binaries? [closed] 【发布时间】:2018-11-08 19:55:57 【问题描述】:

我最近发现了一个出色的 Visual Studio 扩展,它可以在项目中发现不必要的 #include 语句并将其删除。我处理一些粗糙的遗留代码,它被剥离了很多。唯一的问题是我不能确定它没有以某种微妙的方式改变构建。我突然想到一个项目可能仍在构建,但某个地方的 #define 可能已被更改。

无论如何,我突然想到,通过检查二进制文件,我可以确定没有进行任何重要的更改。我想知道是否有人对如何最好地做到这一点有任何建议?明显的问题是二进制文件中的少量元数据会因为编译器元数据的构建时间等而改变。

目前的想法:

    反汇编所有二进制文件并将反汇编结果与差异进行比较。 (虽然这不会涵盖我猜的数据部分)。 使用某种能够识别 PE 标头的二进制差异程序。

有什么想法吗?有人知道我描述的理解 PE 标头的工具吗?

【问题讨论】:

“有人知道像我描述的那样好的二进制差异程序吗?” 在将近 20k 的代表中,你应该明白你正在危险地接近离题这里。 :) 是的,我想这是真的。但这是只有程序员同行才可能知道答案的问题。 通过检查二进制文件没有做出重要的改变鉴于您已经修改了粗糙的遗留代码并且它被大量剥离,您做出了重大改变。你做什么样的测试?因为你现在必须重做全部 一些编译器往往是不确定的。即使是相同的输入代码也不能保证生成相同的输出。检查二进制文件的语义相等性是一个“难题”。您需要依靠您的测试用例来确保没有任何问题。 您不需要反汇编二进制文件,您可以使用 gcc 和 clang 中的-S 选项生成程序集。我记得 cl 有 /FA 标志。不过要小心行号和其他调试信息。您可以将其从输出中剥离以仅保留说明。 【参考方案1】:

PE 头总是在同一个地方,并且范围最多只有 512 字节(确切地说)。 所以只需截断前 512 个字节,然后比较结果。

我通过 xxd 管道将文件转换为十六进制,然后对生成的文本文件进行比较(任何文本比较程序都可以,但您需要 git 命令行来获取 xxd)。

xxd -p -c 4 < Truncatedfile1.exe > output.diff1

tail -n -512 < File1.exe | xxd -p -c 4 > output1.hex
tail -n -512 < File2.exe | xxd -p -c 4 > output2.hex
git diff --no-index --color output1.hex output2.hex 

请注意,我将行仅设置为 4 个字节长,以便当在其间插入奇数字节时,对齐(尤其是发生在数据部分中)有可能使我重新调整行的形状。如果您非常幸运,您的代码也是双字对齐的,那么它也可以与您的代码一起使用。

【讨论】:

谢谢!所以听起来这是一种对你有用的方法? cmets 中的一些人说,编译器的不确定性太强,无法实现这个想法。 嗯,我确实用二进制规模的自动化东西编辑二进制文件,作为一名软件测试人员,我在检查差异方面有一些经验。我只是考虑了如何区分数据部分并记住它通常是双字对齐的,所以我认为每行 4 个字节的 xxd 对于重新编译的程序也是一个好主意。

以上是关于如何最好地比较两个编译的二进制文件? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

递归地比较目录,忽略所有二进制文件

Python:如何比较两个二进制文件?

我需要一个用于 Win/Linux 的二进制比较工具 [关闭]

如何在编译时检测 XNU 内核二进制文件?

如何比较两个二进制文件或文件集并在 Python 中显示它们之间的差异?

grepping 二进制文件和 UTF16