如何分析使用 JIT 编译代码的程序?

逆向工程 调试器
2021-06-25 05:46:52

我今天遇到的很多代码在运行时生成了相当多的代码,这使得分析非常费力和费时。

有什么方法可以为 JIT 编译器引入的各种函数创建符号名称,这些函数会不断出现,或者为通过 GDB 或 WinDBG 中的 JIT 编译器引入到可执行文件中的各种工件(例如类型信息)创建符号名称?

2个回答

对于 .net,有SOS.dll和 WinDbg。您可以在 .NET Framework 的子文件夹中找到已安装 .NET 框架的每个版本的版本%SYSTEMROOT%\Microsoft.NET\Framework\您可以通过键入.loadSOS dll 的完整路径将其加载到 WinDbg 中

使用!name2ee以获得类的方法表,!dumpmt转储方法表,!dumpmd转储你想看看该方法的方法描述符,CodeAddr是JIT编译的代码的地址,最后!U拆卸代码地址。

这是描述该过程博客的链接

我实际上不确定你会从攻击 JIT 编译的代码中获得什么,因为几乎总是这样,源 VM 更简单并且类型注释很重。攻击中间语言几乎总是更容易。我能想到的唯一原因是如果您想使用 JIT 的优化来消除混淆。即便如此,将优化传递应用到中间语言可能更容易。我想还有一种情况是,您想修改 JIT 代码,以便它可以在某种漏洞利用中重用。

我误解了这个问题吗?

是的,答案取决于您究竟要实现什么目标。

在分析.NET 应用程序本身方面,您可以通过使用例如JetBrains 编写的DotPeek 来获得完整的源代码。您甚至可以将其导出到功能齐全的 Visual Studio 项目中,进行构建和调试。但是,某些应用程序可能会被混淆。

另一种情况是 .NET 应用程序是用另一种语言(例如 C++)编写的另一个应用程序的一部分。在这种情况下,最有可能的 .NET 代码被编译成 DLL,也可以使用 DotPeek 等应用程序反汇编。

可能存在更复杂的场景,例如嵌入恶意软件的自定义 JIT 编译器。在这种情况下,最合理的方法可能是编写自定义插件(例如,使用 IDAPython for IDA Pro)。该插件应该了解数据结构或行为,并且可以在逆向工程过程的每个步骤中为您提供帮助。但是编写自定义插件可能需要大量的底层语言知识,并且本身可能是一个挑战。