.NET 函数有函数序言吗?

逆向工程 部件 十六进制 。网
2021-06-13 09:34:59

如果我在十六进制编辑器中查看用 VC++ 编译的二进制文件,并且我想确定函数的开头——我可以查找十六进制“55 8B”——这是一个常见的函数序言。

是否有与 .net CIL 等效的东西?即是否有我可以寻找的十六进制模式来识别原始函数的开始?

这里的应用程序是寻找恶意软件样本之间的共享代码。

2个回答

IL 代码中没有真正的 prolog,因为它不需要管理堆栈、保存损坏的寄存器或在本机代码中执行任何其他必要的标准簿记。

但是,字节码本身前面是方法 header,并且这些方法的可能性有限。来自.NET IL Assembler一书

方法头属性

方法记录的 RVA 值(如果非零)指向方法体。CorHdr.h 中定义了两种类型的方法头——fat 和 tiny。头的前两位表示它的类型:第 10 位代表小格式,第 11 位代表胖格式。

[...]

一个微小的方法头只有 1 个字节的大小,前两个(最低有效)位保存类型 - 10 - 剩下的六个位保存方法 IL 代码大小(以字节为单位)。如果一个方法既没有局部变量也没有托管异常处理,如果它在 8 个槽的默认评估堆栈深度下工作正常,并且它的代码大小小于 64 字节,则为该方法提供一个很小的标头。胖头的大小为 12 个字节,其结构如表 10-1 所示。胖头必须从 4 字节边界开始。图 10-4 显示了 tiny 和 fat 方法头的结构。

因此,如果您使用一些 .NET 二进制文件,在元数据中查找方法 RVA 并转到二进制文件中的 RVA,您可以收集一些标头模式并使用它们在二进制文件中查找字节码。(虽然我建议首先只使用元数据——它列出了二进制文件中所有合法方法的位置)。

我不认为 .NET 是那么简单......你可以在 IDA Pro 中清楚地看到它 - 至少有几个不同的单字节函数序言。

为什么不使用 dnSpy/de4dot 的反编译器库 - dnlib进行反编译,然后使用代码克隆检测,例如Simian或实现一些模糊匹配(散列?)算法。

.NET 在未打包或混淆时通常可以很好地反编译。然而,如果它被混淆或打包,您将不会在匹配功能方面取得很大成功。