元数据和 PE 文件结构
更新:2007 年 11 月
元数据存储在 .NET Framework 可移植可执行文件 (PE) 文件的一个部分中,而 Microsoft 中间语言 (MSIL) 则存储在 PE 文件的另一部分中。文件的元数据部分包含一系列的表和堆数据结构。MSIL 部分包含 MSIL 和引用 PE 文件元数据部分的元数据标记。当使用工具(例如,使用 MSIL 反汇编程序 (Ildasm.exe) 来查看代码的 MSIL 或使用运行库调试器 (Cordbg.exe) 来执行内存转储)时,您可能会遇到元数据标记。
元数据表和堆
每个元数据表都保留有关程序元素的信息。例如,一个元数据表说明代码中的类,另一个元数据表说明字段等。如果您的代码中有 10 个类,类表将有 10 行,每行一类。元数据表引用其他的表和堆。例如,类的元数据表引用方法表。
元数据还以四种堆结构存储信息:字符串、Blob、用户字符串和 GUID。所有用于对类型和成员进行命名的字符串都存储在字符串堆中。例如,方法表不直接存储特定方法的名称,而是指向存储在字符串堆中的方法的名称。
元数据标记
元数据标记在 PE 文件的 MSIL 部分中唯一确定每个元数据表的每一行。元数据标记在概念上和指针相似,永久驻留在 MSIL 中,引用特定的元数据表。
元数据标记是一个四个字节的数字。最高位字节表示特定标记(方法、类型等)引用的元数据表。剩下的三个字节指定与所说明的编程元素对应的元数据表中的行。如果您用 C# 定义一个方法并将其编译到 PE 文件,下面的元数据标记可能存在于 PE 文件的 MSIL 部分:
0x06000004
最高位字节 (0x06) 表示这是一个 MethodDef 标记。低位的三个字节 (000004) 指示公共语言运行库在 MethodDef 表的第四行查找对该方法定义进行描述的信息。
PE 文件中的元数据
当为公共语言运行库编译程序时,该程序转换为由三部分组成的 PE 文件。下表说明了每部分的内容。
PE 部分 |
PE 部分的内容 |
---|---|
PE 标头 |
PE 文件主要部分的索引和入口点的地址。 运行库使用该信息确定该文件为 PE 文件并确定当将程序加载到内存时执行从何处开始。 |
MSIL 指令 |
组成代码的 Microsoft 中间语言指令 (MSIL)。许多 MSIL 指令带有元数据标记。 |
元数据 |
元数据表和堆。运行库使用该部分记录您的代码中每个类型和成员的信息。本部分还包括自定义属性和安全性信息。 |