反汇编程序是否可以检测到C / C ++标准函数的使用并在输出代码中指定它们,然后将#include行添加到适当的头文件(例如stdio.h甚至windows.h)中?整个大型库被公认是开发人员自己的业务逻辑代码,并且编写完整吗?标准库不是已知的二进制序列(或者可以通过某种已知的方式进行处理,因为二进制代码可能由于寻址而有所不同)?并正确地将它们包含在输出中?

评论

#include听起来像您期望C输出。大多数反汇编程序输出汇编代码。另外:“标准”库,还有很多标准。 IDA Pro(如下面的答案所述)可以识别许多标准库-但很可能不是“全部”。

#1 楼

IDA Pro将借助其FLIRT功能来执行此类操作。
您可以在此处查看更多信息:什么是FLIRT签名?

评论


还请注意,您可以使用Hex-Rays下载页面上可用的FLAIR工具创建自己的FLIRT签名(需要购买许可证时收到的电子邮件中提供的登录名/密码)。因此,如果您对“标准库”的定义与IDA的定义不同,则可以选择。

–滚轴
13年11月16日在23:13

#2 楼

重要的一件事是,标准运行时通常被视为任何其他代码或库。如何链接和加载已编译的代码在很大程度上取决于平台。 .net与c ++完全不同。

基本功能至少具有三种在二进制文件中显示的主要方式:

动态链接

当函数保留在动态加载的库中时,这种情况就是您通过windows.h获得的许多函数的情况。识别它们通常很容易,因为它们在功能上是分开的,并通过其字符串名称(修饰或未修饰)或顺序来命名。大多数反汇编程序应处理没有问题的动态链接的标准函数。这是各种编译器,运行时和平台选项的最常见默认值。这取决于编译器能否将函数移至单独的编译单元,而C ++中的许多模板通常不是这种情况。

静态链接而不是内联

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

静态链接和内联

这是当函数包含在二进制文件中并且在功能上与其他函数没有区别时。这通常在以下情况发生:函数足够小,以至于执行函数调用的开销非常昂贵,无法保证在调用函数中重复相同的函数,或者仅在二进制文件中的很少位置(通常一次)调用该函数。这意味着反汇编程序几乎没有什么信息可以知道这最初是一个单独的函数,而调试信息对恢复这些函数没有多大帮助。不会有功能序言或结语。操作码可能会大量重新排列/我知道的唯一可以实现这种功能的恢复非常有限的工具是Hex-Rays反编译器,而非diassembler。我已经看到了链接时间优化的二进制文件,其中一个函数最终是数百个嵌套的内联函数的大规模结果,从而导致一个具有数千个分支的函数。将它们分离回原来的功能将是非常有用的操作。 Hex-Rays IDA及其反编译器和BinDiff可能提供了我所知道的最完整的解决方案。在.net,java或python等反射性强的平台上,这并不是什么大问题。

评论


您是说要结合IDA反编译器和BinDiff吗?还是您是指IDA +反编译器还是BinDiff?您将如何使用BinDiff检测库?

– gogo_gorilla
16年5月31日在12:05

首先,您要检测到他们使用了lib。您可以使用尽可能接近的编译器设置自己构建库。然后,将二进制文件与刚刚构建的库绑定。以我的经验,这会有所帮助。当然,这是用于没有符号的静态链接。

–彼得·安德森(Peter Andersson)
16年5月31日在12:07