一直都想写篇文章来说说那些尘封在PE/Coff文件格式下的那些事,还有Metadata和EEClass是如何表现了一个静态的PE格式文件在内存中的映射结构。
在这篇文章里,我不去介绍windows下PE文件的具体格式,也不去介绍一个托管或者是非托管PE文件的加载运行方式,更加不去介绍一个PE文件里面的各个头部以及整体结构的各个部分的含义。
而是侧重于介绍,基于托管环境下,DotNet对基本的PE/CoFF文件格式做了那些扩充,CLR头部介绍,以及元数据和IL代码详析解析。主要侧重从静态文件的角度,来剖析DotNet下最基本的模块的结构,以及这样的结构如何适应一个托管的环境。
拟把PE文件格式里里外外从上到下一点一点的完全解剖一遍,当然,不可能做到很全面,不然,如果想知道PE文件的各个方面的具体的细节,可以参阅文章底部推荐的那个白皮书文档,这份文档相当详尽介绍了PE文件格式的点点滴滴。
首先,还是从一段C#代码开始:
class Program
{
public const int conField=122*1119;
public readonly int roField;
private int _property;
public int Property
{
get {return _property; }
set{_property = value; }
}
static void Main (string[] args)
{
(new Program()).Method();
}
public void Method()
{
System.Console.ReadLine();
}
}
之所以定义这么多类型和字段,主要是为了在解说托管PE文件格式的时候,元数据表中相关的表都会出现相关记录。
编译之后,得到一个叫做TestConsoleApp.exe的托管PE文件。在继续下面的叙述之间,首先先概括的说一下Metadata。不说IL语言是因为,在我以前的博文中,已经有相关的介绍。
一个托管PE文件,粗略的讲,由4个部分组成。PE32(+)的头部,CLR头部,Metadata以及IL。
首先,我们来说说CLR的头部。这个东西,是托管的PE文件所特有的东西。
我们打开DotNet Framework里面的include文件夹里面一个叫做CorHdr.h的文件,找到一个叫做IMAGE_COR20_HEADER这个数据结构的定义。这个数据结构,定义的就是CLR的header里面内容。下面对其的定义:
// COM+ 2.0 header structure.</