[你必须知道的.NET]第二十五回:认识元数据和IL(中)2011-03-23 博客园 Anytao书接上回[第二十四回:认识元数据和IL(上)],我们对PE文件、程序集、托管模块,这些概念与元数据、IL的关系进行了必要的铺垫,同时顺便熟悉了以ILDASM工具进行反编译的基本方法认知,下面是时候来了解什么是元数据,什么是IL这个话题了,我们继续。很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有《第一回:恩怨情仇:is和as》那么迅速,但是Metadata和IL却是绝对重量级的内容,值得我们在任何时间关注,本文就是开始。3 元数据是什么?元数据,就是描述数据的数据。这一概念并非CLR之独创,Metadata存在于任何对数据和数据关系中,例如程序集清单信息也被称为程序集元数据。而不同系统的元数据也相应具有本身的特点,.NET元数据也是如此。那么,CLR元数据描述的是哪些内容呢?正如前文的描述一样,编译之后,类型信息将以元数据的形式保存在PE格式文件中。.NET是基于面向对象的,所以元数据描述的主要目标就是面向对象的基本元素:类、类型、属性、方法、字段、参数、特性等,主要包括:定义表,描述了源代码中定义的类型和成员信息,主要包括:TypeDef、MehodDef、FieldDef、ModuleDef、PropertyDef等。引用表,描述了源代码中引用的类型和成员信息,引用元素可以是同一程序集的其他模块,也可以是不同程序集的模块,主要包括:AssemblyRef、TypeRef、ModuleRef、MethodsRef等。指针表,使用指针表引用未知代码,主要包括:MethodPtr、FieldPtr、ParamPtr等。堆,以stream的形式保存的信息堆,主要包括:#String、#Blob、#US、#GUIDe等。如前文所述,我们以ILDasm.exe可以通过反编译的方式,通过执行Ctrl+M快捷键来获取该程序集所使用的MetaData信息列表,在.NET中每个模块包含了44个CLR元数据表,如下:
表记录 | 元数据表 | 说明 |
0(0) | ModuleDef | 描述当前模块 |
1(0x1) | TypeRef | 描述引用Type,为每个引用到类型保存一条记录 |
2(0x2) | TypeDef | 描述Type定义,每个Type将在TypeDef表中保存一条记录 |
3(0x3) | FieldPtr | 描述字段指针,定义类的字段时的中间查找表 |
4(0x4) | FieldDef | 描述字段定义 |
5(0x5) | MethodPtr | 描述方法指针,定义类的方法时的中间查找表 |
6(0x6) | MethodDef | 描述方法定义 |
7(0x7) | ParamPtr | 描述参数指针,定义类的参数时的中间查找表 |
8(0x8) | ParamDef | 描述方法的参数定义 |
9(0x9) | InterfaceImpl | 描述有哪些类型实现了哪些接口 |
10(0xa) | MemberRef | 描述引用成员的情况,引用成员可以是方法、字段还有属性。 |
11(0xb) | Constant | 描述了参数、字段和属性的常数值 |
12(0xc) | CustomAttribute | 描述了特性的定义 |
13(0xd) | FieldMarshal | 描述了与非托管代码交互时,参数和字段的传递方式。 |
14(0xe) | DeclSecurity | 描述了对于类、方法和程序集的安全性 |
15(0xf) | ClassLayout | 描述类加载时的布局信息 |
16(0x10) | FieldLayout | 描述单个字段的偏移或序号 |
17(0x11) | StandAloneSig | 描述未被任何其他表引用的签名 |
18(0x12) | EventMap | 描述类的事件列表 |
19(0x13) | EventPtr | 描述了事件指针,定义事件时的中间查找表 |
20(0x14) | Event | 描述事件 |
21(0x15) | PropertyMap | 描述类的属性列表 |
22(0x16) | PropertyPtr | 描述了属性指针,定义类的属性时的中间查找表 |
23(0x17) | Property | 描述属性 |
24(0x18) | MethodSemantics | 描述事件、属性与方法的关联 |
25(0x19) | MethodImpl | 描述方法的实现 |
26(0x1a) | ModuleRef | 描述外部模块的引用 |
27(0x1b) | TypeSpec | 描述了对TypeDef或者TypeRef的说明 |
28(0x1c) | ImplMap | 描述了程序集使用的所有非托管代码的方法 |
29(0x1d) | FieldRVA | 字段表的扩展,RVA给出了一个字段的原始值位置 |
30(0x1e) | ENCLog | 描述在Edit-And-Continue模式中哪些元数据被修改过 |
31(0x1f) | ENCMap | 描述在Edit-And-Continue模式中的映射 |
32(0x20) | Assembly | 描述程序集定义 |
33(0x21) | AssemblyProcessor | 未使用 |
34(0x22) | AssemblyOS | 未使用 |
35(0x23) | AssemblyRef | 描述引用的程序集 |
36(0x24) | AssemblyRefProcessor | 未使用 |
37(0x25) | AssemblyRefOS | 未使用 |
38(0x26) | File | 描述外部文件 |
39(0x27) | ExportedType | 描述在同一程序集但不同模块,有哪些类型 |
40(0x28) | ManifestResource | 描述资源信息 |
41(0x29) | NestedClass | 描述嵌套类型定义 |
42(0x2a) | GenericParam | 描述了泛型类型定义或者泛型方法定义所使用的泛型参数 |
43(0x2b) | MethodSpec | 描述泛型方法的实例化 |
44(0x2c) | GenericParamConstraint | 描述了每个泛型参数的约束 |