public class App {
static public void Main(System.String[] args) {
System.Console.WriteLine("Hi");
}
}
我们简单的使用csc /out:app.exe app.cs对其编译。生成的PE文件,与.NET出现前传统的编译器生成的PE文件一致,也含有IMAGE_DOS_HEADER,我们知道这部分的作用即是早期的DOS在遇到PE文件格式时,能判定这个可执行文件不能执行于DOS下而存在的。IMAGE_DOS_HEADER与将要谈及的一些结构在winnt.h中均有详细定义。Windows OS Loader根据IMAGE_DOS_HEADER中的e_lfanew成员定位紧挨着的IMAGE_NT_HEADERS。其定义如下:
// Symbol table and startup information
IMAGE_DATA_DIRECTORY MetaData;
ULONG Flags;
ULONG EntryPointToken;
// Binding information
IMAGE_DATA_DIRECTORY Resources;
IMAGE_DATA_DIRECTORY StrongNameSignature;
// Regular fixup and binding information
IMAGE_DATA_DIRECTORY CodeManagerTable;
IMAGE_DATA_DIRECTORY VTableFixups;
IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
// Precompiled image info (internal use only - set to zero)
IMAGE_DATA_DIRECTORY ManagedNativeHeader;
} IMAGE_COR20_HEADER;
这个结构的Flags与EntryPointToken上面已经提及。从这么多的IMAGE_DATA_DIRECTORY上看,这个定义很像IMAGE_OPTIONAL_HEADER32,后者可以理解成PE文件头的精华,其用于定位.text等Section,由Windows OS Loader执行。而前者用于定位.NET CLR Data,如MetaData、Resources、StrongNameSignature等等。不同的是IMAGE_COR20_HEADER是由mscoree.dll中的_CorExeMain(对应于EXE文件)负责调用(MSIL语言需经过JIT编译成机器码才可执行)。