编译器版本在生成签名中的重要性

逆向工程 艾达 小精灵 调情签名
2021-06-24 22:29:00

我将我为 AArch64 交叉编译的参考精灵加载到 IDA Pro 中,idb2pat 以生成一个 .pat,然后我通过 sigmake 进行处理。

然后我使用签名文件(在适当的 IDA Pro 目录中)来处理商业图像,但是它只能识别一两个函数(数百个),即使我知道我正在检查的二进制文件是根据参考源构建的我用来构建参考精灵,我生成了一个 .pat(然后是一个签名)。

商业小精灵已经剥离了所有调试/编译器信息......非常无情,所以我必须猜测它是用什么gcc编译的,然后使用这个猜测的gcc版本交叉编译参考源。

我的问题是在构建精灵以生成签名时,编译器版本有多重要?如果我得到的版本不正确,我的所有签名是否都无法与我正在使用的目标二进制文件匹配?

谢谢你的帮助!

1个回答

是的,获得正确的编译器版本以及编译选项非常重要。

FLIRT依赖于固定的字节模式,并且不能容忍生成代码中的哪怕是微小的差异。不同版本的编译器可能具有截然不同的寄存器分配器或优化算法,这可能会导致相同源的二进制文件非常不同。此外,idb2pat可能未针对 AArch64 进行调整,并且可能无法正确标记可重定位字节,从而导致模式过于严格。更好的选择是从目标文件 ( .o) 或静态库 ( .a)生成模式pelf因为它可以使用重定位信息来标记通配符字节。

如果您只有一个二进制文件,我建议您手动将其与源代码进行匹配,使用直接的旧人类直觉和函数/字符串文字之间的引用。这可能比找到正确的编译器版本和选项更快。

另一种选择是使用更灵活的差异实用程序,例如Diphora ,它除了固定字节模式匹配之外还有更多算法。

如果您需要大规模使用,则需要收集许多编译器版本并尝试影响代码生成的各种选项(至少是优化级别,即-O0, -O1, -O2, -O3)。您还应该尝试其他编译器,例如 llvm/clang(公共版本和ARM 的定制版本)。

为了快速测试,您可以在一些简短的代码片段上使用Compiler Explorer,看看您是否可以找到一个编译器和一组选项来匹配您在二进制文件中看到的代码。