.Net版本PE文件结构,其实是在原始PE文件结构中套入了一层CLI文件结构
外层PE文件结构:
比较关注的点是在NT头-可选头部,有一个DataDirector数据结构数组,每一项包含一个虚拟地址以及大小,第十五项(下标从1开始啊)对应就是CLI头部的起始地址和大小,在010 Editor中可以解析到此处:
跳转到CLI头部,头部比较关心的点是MetaData,它也是DataDirector类型,包含了metadata的虚拟地址以及数据大小。
Metadata对应包含了多个流数据,这些流数据对应有类型表、方发表、字符串表等等,是解析的关键所在。
之后对应通过流的信息可以跳转到不同表中进行解析,这里比较关心的是#~流,里面包含了方法类型等很多重要的表,是每一个.Net版本PE文件都必须要包含的。
这里将方法表的解析结构列出,其他结构的可以参照Mono源码去分析。
一些坑点说明:
1、此处得到的cli头部虚拟地址并不是在文件中的虚拟地址,需要减去section中text段的虚拟地址,加上section段在文件中的起始地址:
File_rva = rva – text.virtualaddress + section_offset
2、有效表中表项的长度不一定是固定的,会随着表对应的类型而有所变化,比如类型对应#Strings偏移的值,可能会出现2字节或者4字节的情况,视#Strings表大小决定,同样的还有#Blob也存在这样的情况。
参考:
http://www.cnblogs.com/seely/p/4186864.html
Mono源码:https://github.com/mono/mono