反汇编程序是否检测标准函数?

逆向工程 艾达 拆卸 反汇编者
2021-07-05 00:40:57

反汇编程序是否检测到 C/C++ 标准函数的使用并在输出代码中指定它们,将#include添加到适当的头文件(例如stdio.h甚至windows.h)?

如果不是,整个大库是否被认为是开发人员自己的业务逻辑代码,并完全编写?标准库不是已知的二进制序列(或者可以通过某种方式进行处理,因为二进制代码可能因寻址而不同)?

您知道可以检测标准函数并在输出中正确#include 的反汇编程序吗?

2个回答

需要意识到的一件事是标准运行时通常被视为任何其他代码或库。编译后的代码如何链接和加载在很大程度上取决于平台。.net 与 C++ 非常不同。

基本上函数至少有三种主要的方式显示在你的二进制文件中:

动态链接

当一个函数保存在动态加载的库中时,这就是您所说的通过windows.h获得的许多函数的情况识别这些通常很容易,因为它们在功能上是分开的,并且通过它们的字符串名称、装饰或未装饰或通过序数命名。大多数反汇编程序应该可以毫无问题地处理动态链接的标准函数。这是各种编译器、运行时和平台选项的最常见默认值。这取决于编译器能否将函数移动到单独的编译单元,而 C++ 中的许多模板通常不是这种情况。调用约定受到尊重,并且存在序言和结语。

静态链接而不是内联

这是当一个函数包含在您的二进制文件中但在功能上与其他函数分开时。这可以使用某种形式的一组签名来识别。IDA 使用FLIRT 签名bindiff这样的东西使用更多样化和更复杂的方法来比较函数,例如使用流程图分析。通常参数是根据调用约定传递的,除非二进制文件是用链接时间优化构建的,在这种情况下,编译器可以按任何顺序自由地传递参数。如果幸运的话,二进制文件包含调试信息,可以允许大量恢复函数名称和参数。

静态链接和内联

这是当一个函数包含在你的二进制文件中并且在功能上与其他函数没有分开时。这通常发生在一个函数足够小以致于执行函数调用的开销足够昂贵以保证在调用函数中重复相同的函数时,或者如果该函数仅在很少的位置被调用,通常是一次,在二进制文件中。这意味着反汇编器几乎没有信息知道这最初是一个单独的函数,调试信息对恢复这些函数没有多大帮助。不会有函数序言或结语。操作码可以大量重新排列/我所知道的对此类功能的恢复非常有限的唯一工具是 Hex-Rays 反编译器,而不是反汇编器。一世' 已经看到具有链接时间优化的二进制文件,其中一个函数最终是数百个嵌套内联函数的大量结果,导致函数具有数千个分支。将它们分离回原来的功能将是一个非常有用的操作。

最后

没有解决方案可以解决上述所有情况。Hex-Rays IDA 结合他们的反编译器和 BinDiff 可能提供了我所知道的最完整的解决方案。.net、java 或 python 等反射性很强的平台上,这不是什么大问题。

由于其 FLIRT 功能,IDA Pro 可以做到这些。您可以查看此处以获取更多信息:什么是 FLIRT 签名?