深入理解.NET程序集的PE文件格式

在本文中,将探讨.NET程序集是如何被打包进PE文件格式的。将使用一些工具来帮助分析和理解文件结构,而不是深入到每个字节的详细包装方式。

1. 使用的工具

为了分析PE文件,使用了以下工具:

1.1 Hex编辑器ImHex:这是一个免费的软件,它允许给文件的不同部分上色,以便更好地理解文件结构。

1.2 PE查看器PE-bear:这是一个非常有用的工具,用于可视化地分析PE文件。虽然它不覆盖所有PE文件的变体和风格,但对于简单的PE文件来说,它是一个出色的查看器/解析器/分析器。

1.3 汇编查看器:项目中提供了一个出色的.NET汇编查看器,它是免费的。

1.4 CFF Explorer:另一个PE文件资源管理器,可以在指定的链接中找到。

2. .NET头信息(也称为“COR20头”或“CLI头”)

在之前的中,通过PE-bear工具看到了NT头信息的“可选头 - 数据字典”部分。在文件偏移0x168处,可以看到.NET头信息位于0x2008(RVA)地址。通过计算,可以找到原始文件中的位置和大小。

在Hex编辑器中,可以看到这个信息的十六进制表示。PE-bear和汇编查看器也提供了对这个信息的解释。

3. 资源(也称为“托管资源”)

资源目录位于0x2AFC(RVA),大小为0xD8。通过计算,可以找到原始文件中的位置和结束位置。在Hex编辑器中,可以看到资源目录的十六进制表示,并且可以看到如何将C#代码资源中的字符串“HW”映射到“Hello World!”。

4. 元数据

4.1 简短的理论背景:.NET程序集中的元数据被组织在5个流中,每个流的名称都以#开头。这些流包括:

#~流:这是“元数据流”,包含程序集中的类型、方法、字段、属性和事件的信息。

#Strings流:包含命名空间、类型和成员的名称。

#US流:这是“用户字符串堆”,包含代码中使用的所有字符串。

#GUID流:存储程序集中使用的GUID。

#Blob流:包含纯二进制数据。

4.2 文件内容:在文件偏移0x210处,可以看到元数据头的位置。通过计算,可以找到元数据头在原始文件中的位置。在Hex编辑器中,可以看到元数据头的十六进制表示,而汇编查看器提供了对这个信息的解释。

通过计算,可以找到每个流在原始文件中的起始和结束位置。例如,#Strings流从0x6EC开始,到0xAFC结束。

#~流是特殊的,所以它被以不同的方式呈现。

5. 方法体

元数据之后,方法体(即IL)在哪里?为了找到它们,需要解释元数据。将使用工具来帮助进行解释,而不是手动进行。

通过CFF Explorer,可以看到元数据流#~包含一个包含方法的文件夹。对于方法Main,可以看到起始点的偏移量是0x2069(RVA)。通过计算,可以找到原始文件中的位置。

因此,方法体存储在.NET头信息和元数据头之间。在文件中,这个区域是0x250到0x31B。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485