最终的目标是比较2的二进制文件建立完全相同的来源,在完全相同的环境和能告诉他们事实上是功能上等同的。

一个应用程序,为此将重点QA时间的事情,实际上是更改的版本之间,以及改变监测。

MSVC与PE格式自然使得这很难做到的。

到目前为止,我发现和消灭这些东西:

  • PE时间戳和校验
  • 数字签名directory entry
  • Debugger部分时间戳
  • PDB签名、年龄和文件路径
  • 资源的时间戳
  • 所有文件/产品版本在VS_VERSION_INFO资源
  • 数字签名的部分

我分析PE,找到偏移量和大小的所有这些事情而忽略字节的范围进行比较时的二进制文件。就像魅力(良好,几个测试我碰它)。我可以告诉大家,签署的可执行的版本1.0.2.0建立在赢得服务器2008年等于未签名的一个版本10.6.6.6,建立在我赢XP dev框,因为只编译版本以及所有来源和标题都是相同的。这似乎是工作进VC--7.1 9.0.(对于释放建立)

一个警告。

绝对的道路为生 必须是相同的 必须有同样的长度。

cl.exe 将相对路径绝对的,并提出他们的权利成对象随着编译器标志等等。这unproportional影响整个二进制的。一个字符的改变的道路将导致一个字节的变化在这里和那里好几次的整体。文字部分(但是许多对象是相互关联我怀疑).改变长的道路明显更差异。在obj文件和链接的二进制的。

感觉就像文件路径与编制标志是用来作为某种类型的散列,这使得它成链接的二进制或甚至影响到安置顺序不相关的编码。

因此,这里是3-部分的问题(概述为"现在怎么办?"):

  • 我应该放弃整个项目的回家吧因为我想要做到打破法律的物理和企业政策的MS?

  • 假设我处理绝对路径问题(在政策一级或者通过找到一个神奇的编译器标志),有没有任何其他事情我应该看出来的?(喜欢的东西__时间__ 意味着改变码的,所以我不介意那些没有被忽略)

  • 有没有办法或者强制编译器使用的相对路径、或欺骗入思考的道路是不是什么吗?

因为最后一个是美丽的恼人的窗户文件系统。你只是不知道什么时候删除了若干违规记录的价值的来源和目的和svn元数据将会失败,因为流氓文件锁。至少创造新的根总是成功的同时,还有剩余空间。运行多个建立在一旦一个问题。运行一堆虚拟机,同时解决方案,是一个相当沉重的一个。

我不知道如果有一个方法来设置一个虚拟的文件系统进程及其儿童,使若干过程的树木将会看到 不同的 "C:\build"dirs、私人他们只有在同一时间...轻虚拟化的种种...

更新: 我们最近开源的工具上 .看看 比较 部分文件。

有帮助吗?

解决方案

我解决了这个程度。

目前我们已经建立的系统,确保所有新建立的路径不断的长度(建立/001,建立/002,等等),因此可以避免的变化在PE布局。之后建立一个工具,比较老的和新的二进制文件忽视了有关PE领域和其他地点已知的肤浅的改动。它还运行一些简单的启发式检测动态可忽略的改变。这里是全部的东西的列表以忽略:

  • PE时间戳和校验
  • 数字签名directory entry
  • 出口表的时间戳
  • Debugger部分时间戳
  • PDB签名、年龄和文件路径
  • 资源的时间戳
  • 所有文件/产品版本在VS_VERSION_INFO资源
  • 数字签名的部分
  • MIDL虚荣根嵌入式类型图书馆(包含有时间戳string)
  • __文件__,__日__和时间__宏时它们被用来作为文字串(可以是广泛或狭窄char)

一旦在一个连接,同时会使一些PE部分更大的不扔任何东西出的取向。看起来像它移动的部分边界内填充--这是零所有周围无论如何,但因为它,我会得到的二进制文件有1字节的差异。

更新: 我们最近开源的工具上 .看看 比较 部分文件。

其他提示

标准化建立的路径

一个简单的解决办法是规范对生成路径,所以他们总是的形式,例如:

c:\buildXXXX

然后,当你比较,比方说, build0434build0398, ,只需进行预处理的二进制的改变所有出现 build0434build0398.选择一个模式,你知道的是不太可能出现在你的实际来源数据,除了在这些字符串编译/连接嵌入到PE。

然后你可以做你的正常差的分析。通过使用相同长度的路径,你不会转移任何数据的周围以及造成误判。

Dumpbin用

另一个技巧是使用 dumpbin.exe (船舶与MSVC).使用 dumpbin/所有 要转储的所有详细信息的二进制文本/hex垃圾场。这可以使它更为明显看到什么/在那里正在发生变化。

例如:

dumpbin /all program1.exe > program1.txt
dumpbin /all program2.exe > program2.txt
windiff program1.txt program2.txt

或者用你最喜欢的文本比较的工具,而不是Windiff.

Bindiff用

你可以找Microsoft的 bindiff.exe 有用的工具,它可以获得在这里:

Windows XP Service Pack2的支持工具

它已a/v选择,指导它忽略某些二进制领域,例如时间戳,校验,等等:

"BinDiff使用一个特殊的比较程序 for Win32可执行的文件的面具 出各种建立时间标记领域 这两个文件时进行 比较。这两个允许可执行 文件被标记为"几乎相同" 当文件的忠实地完全相同, 除了时间,他们建造的。"

然而,这听起来像 你可能已经这样做 超集的什么bindiff.exe 不。

有没有办法要么是力量 编译器使用的相对路径,或 傻到想的道路是不是 这是什么?

你有两种方式来这样做:

  1. 使用subst.exe 命令和地图驱动的信建立文件夹(这可能不可靠).
  2. 如果subst.exe 不工作,然后创建的股份的每一个生成文件夹和使用"净额的使用"的命令。这一个几乎可以肯定应工作。

在任何一种情况下,你要地图,并重复使用相同的驱动的信用的一个文件夹在你开始之前的一个特定的建立,使路径似乎完全相同的编译器。

你有没有尝试过拆解的可执行和比较拆卸?应该删除的许多分散注意力的细节,你说,让除其他容易得多。

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