如何检查二进制文件是否是从特定来源构建的

Dar*_*zak 7 java reverse-engineering

我正在处理的遗留项目包括一些二进制jar文件形式的外部库.我们决定对于分析和潜在的修补,我们希望接收这个库的源代码,使用它们来构建新的二进制文件,并在经过详细和足够长的回归测试后切换到这些二进制文件.

假设我们已经检索并构建了源(我实际上处于计划阶段).在进行实际测试之前,我想执行一些"兼容性检查",以排除源代表与"旧"二进制文件中的内容截然不同的可能性.

使用该javap工具,我能够提取用于编译的JDK版本(至少我相信它是JDK的版本).它说,二进制文件是使用主要版本46和次要版本0构建的.根据这篇文章,它映射到JDK 1.2.

假设相同的JDK将用于源编译.

问题是:有没有验证的可靠的和可能有效的方法,如果这两个二进制文件是由相同的源代码构建的?我想知道所有方法签名和类定义是否相同,以及大多数或可能所有方法实现是否相同/相似.

该库非常大,所以我认为对反编译二进制文件的详细分析可能不是一种选择.

Pat*_*han 1

我建议采用多阶段过程:

应用之前建议的 Jardiff 或类似工具来查看是否存在任何 API 差异。如果可能,选择一个具有报告私有方法等选项的工具。实际上,Java 中的任何重大实现更改都可能会更改某些方法和类,即使公共 API 未更改。

如果你有API匹配,用指定的编译器编译一些随机选择的文件,反编译结果和原始类文件,并比较结果。如果它们匹配,则对越来越大的代码体应用相同的过程,直到发现不匹配或检查完所有内容。

与实际的类文件相比,反编译代码的差异更有可能为您提供有关差异性质的线索,并且更容易过滤非显着差异。

如果发现不匹配,请进行分析。这可能是由于您不关心的事情造成的。如果是这样,请尝试构建一个脚本来删除该形式的差异并恢复编译和比较过程。如果出现广泛的不匹配情况,请尝试使用优化等编译器参数。如果对编译器参数的调整消除了差异,则继续进行批量比较。此阶段的目标是找到编译器参数和反编译代码过滤器的组合,以在示例文件上产生匹配,并将它们应用于库的批量比较。

如果您无法在反编译的代码中获得相当接近的匹配,则您可能没有正确的源代码。即便如此,如果您有 API 匹配,那么构建您的系统并使用编译结果运行测试可能是值得的。如果您的测试至少与您从源代码构建的版本运行得一样好,请继续使用它。