我正在处理的遗留项目包括一些二进制 jar 文件形式的外部库。我们决定,为了进行分析和潜在的修补,我们希望接收该库的源代码,使用它们来构建新的二进制文件,并在经过详细且足够长的回归测试后切换到这些二进制文件。
假设我们已经检索并构建了源(我实际上处于计划阶段)。在真正的测试之前,我想执行一些“兼容性检查”,以排除源代表的内容与“旧”二进制文件中的内容显着不同的可能性。
使用javap
工具我能够提取用于编译的JDK版本(至少我相信它是JDK的版本)。它说,二进制文件是使用主要版本 46 和次要版本 0 构建的。根据本文它映射到 JDK 1.2。
假设相同的 JDK 将用于源编译。
The question是:
如果这两个二进制文件都是从相同的来源构建的,是否有可靠且可能有效的验证方法?我想知道是否所有方法签名和类定义都相同,以及大多数或可能所有方法实现是否相同/相似。
该库相当大,因此我认为对反编译的二进制文件进行详细分析可能不是一个选择。
我建议采用多阶段过程:
应用之前建议的 Jardiff 或类似工具来查看是否存在任何 API 差异。如果可能,选择一个具有报告私有方法等选项的工具。实际上,Java 中的任何重大实现更改都可能会更改某些方法和类,即使公共 API 未更改。
如果你有API匹配,用指定的编译器编译一些随机选择的文件,反编译结果和原始类文件,并比较结果。如果它们匹配,则对越来越大的代码体应用相同的过程,直到发现不匹配或检查完所有内容。
与实际的类文件相比,反编译代码的差异更有可能为您提供有关差异性质的线索,并且更容易过滤非显着差异。
如果发现不匹配,请进行分析。这可能是由于您不关心的事情造成的。如果是这样,请尝试构建一个脚本来删除该形式的差异并恢复编译和比较过程。如果出现广泛的不匹配情况,请尝试使用优化等编译器参数。如果对编译器参数的调整消除了差异,则继续进行批量比较。此阶段的目标是找到编译器参数和反编译代码过滤器的组合,以在示例文件上产生匹配,并将它们应用于库的批量比较。
如果您无法在反编译的代码中获得相当接近的匹配,则您可能没有正确的源代码。即便如此,如果您有 API 匹配,那么构建您的系统并使用编译结果运行测试可能是值得的。如果您的测试至少与您从源代码构建的版本运行得一样好,请继续使用它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)