如何判断两个exe是否是相同的代码?

时间:2010-04-09 03:50:40

标签: c++ windows visual-c++ compilation exe

有没有办法检测两个EXE(从VS.Net 2008 for C ++ / MFC编译)是否在它们之间没有任何代码级别的更改,即为了知道没有语句更改。

这是出于合规目的,当我的供应商向我发送一个exe时,表面上自上次测试以来没有对代码进行任何更改。

有没有工具来检查是这样的?

干杯

7 个答案:

答案 0 :(得分:4)

您可以使用解析器将可执行文件反汇编回程序集并与普通的文本差异工具进行比较。

但即使这样也不会100%准确。编译过程不是无损的,当编译C ++代码时,很多信息都会丢失或不可逆转地转换。

特别是,不同的编译器设置可以从完全相同的源生成截然不同的机器代码。 相同编译器的不同编译器甚至不同版本或服务包/修补程序级别可以从相同的源文件生成截然不同的机器代码。

另一个问题是,为什么他们甚至会向你发送“表面上没有做出任何修改”的exe?如果是这样的话,为什么不用你原来的那个呢?

答案 1 :(得分:2)

自动化测试,以便快速重新运行测试。

尽管这是一个很小的陈述,但这是一项艰巨的任务

答案 2 :(得分:2)

对于二进制审核,您必须拥有的最佳工具之一是交互式反汇编程序,也称为IDA Pro。当您需要在不访问源代码的情况下进行审核时,它是必须的。精通使用IDA Pro的人将能够以合理的信心告诉您,如果源代码没有任何表面的更改。在这种情况下,表面的变化将包括源文件中的变量重命名或更改变量,函数或类声明和定义的顺序。他们将能够告诉您构成可执行文件的基本代码块是否具有足够大的差异以便被标记为可疑,因为差异很可能表示源级差异。< / p>

我或多或少地说,因为有两种方法可以使完全相同的源树生成的两个可执行文件仍然具有微妙的,有时彼此之间没有那么微妙的差异。可能影响可执行文件生成的因素包括:

  • 编译器优化设置
  • 可执行文件与
  • 链接的库的不同版本
  • 更改头文件,在用于构建可执行文件的源树外部,在编译步骤之前由C ++预处理器包含
  • 在运行时操作自己的代码的可执行文件,可能包括将其自身的某些部分解压缩或解密到可以跳转到的某个内存区域

此列表可能会持续一段时间。

您建议的二进制审计是否可行?是的,一个有足够知识和技能的人可以做到这一点。黑客一直这样做。如果进行分析的人足够好,他们也能够准确地告诉你他们对评估的信心。

最终它成为可行性的问题。你愿意花多少钱在这次审计上?雇用或签约可以做到这一点的人可能超出预算的审计范围,是否有足够的资金来做这件事?您正在测试的软件有多复杂?您与供应商的关系的性质是什么?

最后一个问题很重要,因为如果通过审核符合他们的最佳利益,并且他们意识到这一点,他们可能愿意在一定程度上为您提供帮助。这可能以调试符号,已使用的编译器选项列表或他们愿意披露的构建过程的其他工件的形式出现。由于任何原因,上述内容在任何分析中都非常有用,其中源代码可用用于分析目的。如果访问源代码 可用用于此目的,则事情变得更容易分析。

如果这是你想要自己追求的东西,我推荐的两本书是Chris Eagle的 The IDA Pro Book: The Unofficial Guide to the World's Most Popular Disassembler The Shellcoder's Handbook: Discovering and Exploiting Security Holes 作者:Chris Anley,John Heasman,Felix Linder和Gerardo Richarte。

最后,为分析那些对你有帮助的技术和工具仍然是非常活跃的研究领域。你的问题要么比你意识到的要深刻,要么可能被我误解了。对你的问题进行彻底的处理,即使从一个实际的角度来看,忽略了与之相关的理论,也可以并且确实填补了许多书籍。

我希望你至少找到一些有用的部分。祝你好运!

答案 3 :(得分:1)

您始终可以在可执行文件上执行MD5sum。这不会告诉你它们在逻辑上是等价还是不同,只是存在差异。

我不确定这是否能解决您的问题,因为您可能正在寻找逻辑比较工具。

答案 4 :(得分:1)

如果您控制源,则不要发送没有与其关联的正确版本信息的exes。

如果出于某种原因他们自己构建了exes,我建议他们必须使用一个构建步骤,将版本控制版本号嵌入到版本控制信息中。

如果他们不使用您的构建步骤(您可以检测到),那么您认为它们是不同的。

大多数修订控制系统(例如SVN)将允许您具有构建步骤,该步骤将说明代码是否处于修改状态。您可以将此信息嵌入到exe的嵌入式资源中的字符串中。然后,您只需提取该资源。

因此,确保所有构建都来自您的自定义构建脚本。

答案 5 :(得分:1)

从现在开始,添加一个后期构建步骤,该步骤将生成源文件的MD5并将其添加到VERSION资源(以便您可以在exe属性中看到它)。
这将花费你2或3个人日。

答案 6 :(得分:1)

在十六进制比较程序中加载exes(BeyondCompare rocks!)。

如果有任何非平凡的变化(假设编译器设置没有改变),它们应该很容易上手。如果它只是时间戳等问题,那可能非常明显。

这绝对不是万无一失的,但这将是我的第一步。