| shuai 的个人资料娱乐精神照片日志 | 帮助 |
|
2007/11/9 强暴.Net程序集 之九 (TypeDef表结构)警告:本系列文章为本人原创,只作技术研究之用,您可以引用链接传播,禁止其它的转载方式,禁止用于商业或非法目的, 对于造成的一切后果本人概不负责 现在我们来看一个非常重要的元数据表TypeDef, 它定义了类型信息
在Partition II Metadata中描述了它的格式: The TypeDef table has the following columns: • Flags (a 4-byte bitmask of type TypeAttributes, §23.1.15) • TypeName (an index into the String heap) • TypeNamespace (an index into the String heap) • Extends (an index into the TypeDef, TypeRef, or TypeSpec table; more precisely, a TypeDefOrRef (§24.2.6) coded index) • FieldList (an index into the Field table; it marks the first of a contiguous run of Fields owned by this Type). The run continues to the smaller of: o the last row of the Field table o the next run of Fields, found by inspecting the FieldList of the next row in this TypeDef table • MethodList (an index into the MethodDef table; it marks the first of a continguous run of Methods owned by this Type). The run continues to the smaller of: o the last row of the MethodDef table o the next run of Methods, found by inspecting the MethodList of the next row in this TypeDef table 其中:
Flags 是一个位掩码, 描述了类型的一些属性信息, 文档中的23.1.15 Flags for types [TypeAttributes]一节中详情描述 在corhdr.h中也有一个定义, 下面是一个节选的列表: typedef enum CorTypeAttr { // Use this mask to retrieve the type visibility information. tdVisibilityMask = 0x00000007, tdNotPublic = 0x00000000, // Class is not public scope. tdPublic = 0x00000001, // Class is public scope. // Use this mask to retrieve class semantics information.
tdClassSemanticsMask = 0x00000060, tdClass = 0x00000000, // Type is a class. tdInterface = 0x00000020, // Type is an interface. // end semantics mask // Special semantics in addition to class semantics.
tdAbstract = 0x00000080, // Class is abstract tdSealed = 0x00000100, // Class is concrete and may not be extended tdSpecialName = 0x00000400, // Class name is special. Name describes how. //其它略
} CorTypeAttr; 并且corhdr.h还有一系列宏, 用于方便的查询类型的一些属性,比如
#define IsTdClass(x) (((x) & tdClassSemanticsMask) == tdClass) TypeName和TypeNamespace 都是一个String 堆的索引值, 要注意它的长度随HeapSizes的大小而变
Extends 描述了类型的继承情况, 即指向基类的信息(接口为0), 但是这个值并不是一个元数据token, 而是一个对token进行压缩后的值, TypeDefOrRefEncoded一节中描述了这个值的算法
比如token为0x01000012,那么它的TypeDefOrRefEncoded 值为 encoded = ( 0x000012 << 2 ) | 0x01 (0x01 指 TypeRef 在TypeDefOrRef中的编号) = 0x48 | 0x01 = 0x49 其中TypeDefOrRef指将TypeDef, TypeRef, TypeSpec这一组号转为一个2位的编号: TypeDefOrRef Tag TypeDef 0 TypeRef 1 TypeSpec 2 可以看出, 这个压缩后的值, 最后两位描述了基类所处于的元数据表在TypeDefOrRef中的编号, 编号之前的位是在该在表中的索引号
FieldList 和MethodList是一个指向Field和Method表中的起始索引的值, 从此开始遍历都是它的Field和Method, 结束于下一个类型的Field和Method表中的起始索引(相当不能超过RowSize), 在Partition II Metadata 的 Field 表一节中有详细的说明
比如FieldList值为0x01, 而下一个类型的FieldList为0x03, 那么0x01和0x02都是该类型的Field索引 下面我们通过代码看如何得到TypeDef 表中的这些值
row = t.Address + t.RowSize * index; //每行的地址, index为类型在TypeDef中的索引
// Flags // Name // Extends // FieldList // MethodList 引用通告此日志的引用通告 URL 是: http://iauhsgnay.spaces.live.com/blog/cns!C7C5DB6D46321CDD!429.trak 引用此项的网络日志
|
|
|