PE header对应C中的IMAGE_NT_HEADER32结构,如下:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; // PE Signature PE.. (50h 45h 00h 00h)
IMAGE_FILE_HEADER FileHeader; // PE的文件头信息
IMAGE_OPTIONAL_HEADER OptionalHeader; // 可选头
} IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
再是真实PE文件的截图:
PICTURE MISSING
(一)中我们已经得到PE header的起始地址D8h,直到DBh,共4个字节,就是结构中的Signature成员,数据为50h 45h 00h 00h,对应值为00 00 45 50h(注,以后凡说到值,均指按高位在高地址的原则倒过来后的实际值,不再说明),对应winnt.h中的常数IMAGE_NT_SIGNATURE,如果Signature等于454Ch表示是IMAGE_VXD_SIGNATURE,即Win3.X中的Virtual Device Driver;等于454Eh表示IMAGE_OS2_SIGNATURE,即OS2的程序等等,请自行查阅winnt.h。
IMAGE_NT_HEADERS32结构只有三个成员,比较简单,但是展开后两个成员的结构体IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER,就会让人绝倒了。。。我们首先看一下IMAGE_FILE_HEADER结构:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; // 支持机器的类型
WORD NumberOfSections; // 区段的个数
DWORD TimeDateStamp; // 连接器创建EXE时的日期时间
DWORD PointerToSymbolTable; // 旧文件中,COFF符号表地址,没有是0
DWORD NumberOfSymbols; // COFF符号表中符号的个数
WORD SizeOfOptionalHeader; // Optional header的长度 (32位EXE中是224字节)
WORD Characteristics; // 见下面的说明
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
结合图,分析如下:
Machine值为014Ch,对应IMAGE_FILE_32BIT_MACHINE常数,即32位机器,其他值请查阅winnt.h。
接着两个字节表示NumberOfSections区段的个数,值为0007h,也就是我们的testPE.exe有7个区段。
SizeOfOptionalHeader位于ECh,EDh,值为00E0h,即后面的Optional Header结构总长为224字节。
再看一个Characteristics,表示这个PE文件的类型,图中位于EEh和EFh,值为0102h,是使用二进制位来标记的,二进制为100000010 = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_EXECUTABLE_IMAGE,表示该文件是32位的EXE文件,如果它的值是2XXXh,则表示是一个DLL,具体还请查阅winnt.h。(唉。。。这句话打的好累啊,以后就说自行查阅了)