PE文件格式应用于所有32位Windows系统:Windows 9X, Windows NT,Windows 2000及Windows XP(Vista已经对PE格式进行了升级,也出现了PE64),而在MSDN 98中有PE的大量详细资料(按目录:MSDN Library Visual Studio 6.0 | Specification | Platforms | Microsoft Portable Executable and Common Object File Format Specification)。
PE文件内容被分割为不同的区段(Section),每一区段中可能包含代码或数据。各区段按页边界对齐,区段没有大小限制,是一个连续结构。每一个区段在内存中都有它自己的一套属性,比如:这个区段是否包含代码、是否只读或可读/写等。每一个区段都有不同的名字,这个名字用来表示区段的功能。例如:
.text 是在编译或汇编结束时产生的一种块,它的内容全是指令代码;
.rdata 是运行期只读数据;
.data 是初始化的数据块;
.idata 包含其它外来DLL的函数及数据信息,即导入表;
.rsrc 包含模块的全部资源,如图标、菜单、位图、对话框等。
Note:使用区段名只是方便人们使用,而对操作系统来说是无关紧要的,因此可将上面区段名任意更改而不会影响PE文件执行。
PE文件非常好的一个特性是其在磁盘上的数据结构与在内存中的结构是一致的。在X86系统中,每个内存页大小为4KB(即0x1000字节)。所以,在X86系统中,PE文件区段(Section)的内存对齐值一般是0x1000,在内存中的每个区段的起始地址为0x1000的倍数。而磁盘PE文件对齐值一般为0x200(即512字节,扇区块大小),所以PE文件中每个区段的起始地址为0x200的倍数。在磁盘PE文件中,区段间的间隙用0x00来填充。由于PE文件在磁盘和在内存中的对齐值不同,所以往往所占用的空间也不相同(在内存中往往占用更多空间)。磁盘上的PE文件和加载进内存中的PE文件比较图如下:
VC编译器默认编译时,exe文件基地址(ImageBase)是0x00400000,DLL文件基地址是0x10000000,可以在链接时使用/BASE参数来改变基址。
我们可以利用一些现成的工具来直观地查看PE文件内容和结构,加深对PE文件格式的理解。这样的工具有:LordPE、PEditor、Stud_PE等。