一个有效的PE文件,总是以一个DOS头结构开始的。
这个DOS头结构就是IMAGE_DOS_HEADER,具体定义见winnt.h文件,这里给复制了过来,如下:
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
对于有效的PE程序而言,其有效也是必须设置的2个成员就是(首尾):
1、WORD e_magic;
DOS可执行文件的标记,其值是固定的0x5A4D,即字符“MZ”,
2、 LONG e_lfanew;
这个成员指定了IMAGE_NT_HEADERS结构的位置,其重要性也就不言而喻了!
注:[color=#FF0000]Microsoft文档中曾说过,如果MS-DOS首部的偏移地址0x18处的值为0x40或者更大,则表明该程序为Win32程序,且领衔地址0x3C处的值为Windows首部的偏移量,即下面即将说到的IMAGE_NT_HEADERS结构的偏移![/color]
我写一个简单的16位程序-Hello.exe(见附件),大家可以比较一下:
但实际上,这一点完全可以忽略过去,并非必要。
同样的,IMAGE_NT_HEADERS结构也是定义在winnt.h文件中的,其他实际的格式有两种:
IMAGES_NT_HEADERS32和IMAGE_NT_HEADERS64
typedef struct _IMAGE_NT_HEADERS64 {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
当然,这些不用我们操心,我们在调用时,只需要用IMAGES_NT_HEADERS就OK了,通过条件编译会自行指定:
#ifdef _WIN64
typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
#else
typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
#endif
待续……