机器代码中的哪些提示可以指向用于生成它的编译器?

逆向工程 部件 编译器 目标代码 全映射
2021-06-25 01:08:52

当我查看应用程序的机器代码时,是否有我可以从生成的机器代码中辨别出的提示和模式,这些提示和模式表明使用哪个编译器(可能还有版本)来生成它?

了解用于生成应用程序的编译器是否有助于我更有效地从生成的对象逆向工程回源代码可能是什么,如果它确实有帮助,那么如何?

4个回答

这方面有一些学术研究,你想要的关键词是“工具链出处”。Nate Rosenblum有一篇关于这个主题的非常好的论文,我已经有一段时间没有阅读这篇论文了,但是您可以使用许多技术来建立这些信息。我认为有些人使用机器学习,而其他人则可以使用一大堆关于编译器行为的启发式或公理。

建立这一点在 IMO 的效用有限。在您尝试获取有关恶意软件组或威胁参与者的情报的对抗性情况下,它可能很有用,但请记住,此类信息可能会被混淆或破坏。此信息的一个潜在用途是确定某些二进制软件是使用某些公司的 SDK 编译的,其中包含具有该公司独有的签名信息的编译器。建立工具链来源可以帮助您证明购买您的 SDK 的人违反了许可或合同,例如生产恶意软件。

行为差异的一个例子是参数写入。有两种方法可以将值放入堆栈,一种使用“push”,另一种使用mov基于地址的地址esp作为目标操作数。所以一个编译器可以做到这一点:

推eax
推 ebx

另一个可以这样做:

mov [esp+foo], eax
mov [esp+foo+4], ebx

他们这样做。一般来说,MSVC 做第一个例子,GCC 做第二个例子,至少在一些非常有限的测试/观察中......

在查看机器代码时,通常会有一个可以跟踪的“轨迹”,除非生成的二进制文件经过某种程度的清理。例如,我在 Linux 机器上使用 GCC 生成了一个小的“hello world”应用程序,gcc -Wall hello.c现在如果你使用一个工具,就像hexedit你在机器代码中看到的那样,有一个包含构建信息的部分:

在此处输入图片说明

很明显,你可以在那里看到,是的,我用 GCC 4.6.3 版构建了它。其他编译器将具有其他类型的签名Microsoft 的“丰富”签名

在 Recon 上有一个题为“Packer Genetics:The Selfish Code”的演讲,描述了一种方法。他们使用一些统计数据从编译的程序中提取最常见的代码序列,并用它来检测解包的结束,但这种方法可以很容易地用于识别特定的编译器。

请参阅此处的幻灯片 15:http : //blog.zynamics.com/2010/07/16/recon-slides-packer-genetics-the-selfish-code-bochspython/

幻灯片似乎有些被截断了,我相信实际的演示文稿有更多信息。

了解用于生成应用程序的编译器是否有助于我更有效地从生成的对象逆向工程回源代码可能是什么,如果它确实有帮助,那么如何?

由于以下原因,我认为了解使用的编译器是非常重要的一步:

  1. 它可以帮助您选择合适的工具来分析目标。
  2. 了解运行时对于分析很重要,例如在 Delphi 中TFileStream是用于读取/写入文件的常用对象。了解该对象的 vtable 有助于我了解偏移量是否为读/写/查找等。

举例说明 1:IDR 之类的工具可能比 IDA Pro 更适合 Delphi 目标。或者至少我们可以用它生成一个 MAP 文件/IDC 脚本,以改进 IDA 中的符号。但是对于用 Visual Basic 编写的目标,可以使用VB Decompiler等。