MS-DOS头部:
每一个PE文件是以一个DOS程序开始的,有了它一旦程序在DOS下运行,DOS才能识别出这是有效的执行体。
PE文件的第一个字节起始于一个传统的MS-DOS头部,称为IMAGE-DOS-HEADER,这实际上就是一个结构体。
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
IMAG_NT_HEADERS的第三个字段下节分析。
每一个PE文件是以一个DOS程序开始的,有了它一旦程序在DOS下运行,DOS才能识别出这是有效的执行体。
PE文件的第一个字节起始于一个传统的MS-DOS头部,称为IMAGE-DOS-HEADER,这实际上就是一个结构体。
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;
我们并不是每个成员都是关心,我们主要关注两个成员,一个是e_magic(可执行文件标识),另一个是e_lfanew(指向PE头)。
e_magic一般是MZ(4Dh 5A),告诉系统这是一个可执行文件,一般可执行文件开头都是MZ。
e_lfanew存放的是PE头在内存中相对于基地址的偏移地址。
PE头:
PE文件头紧挨着DOS stub,PE头是PE相关结构NT映像头,里面包含着许多PE装载器用到的重要字段,实际上还是一个结构。
执行体在支持PE文件结构的操作系统中执行时,PE装载器将从MS-DOS头结构中e_lfanew字段里找到PE头的起始偏移量,加上基地址就得到PE文件头的指针。
IMAGE_NT_HEADERS STRUCT
我们并不是每个成员都是关心,我们主要关注两个成员,一个是e_magic(可执行文件标识),另一个是e_lfanew(指向PE头)。
e_magic一般是MZ(4Dh 5A),告诉系统这是一个可执行文件,一般可执行文件开头都是MZ。
e_lfanew存放的是PE头在内存中相对于基地址的偏移地址。
PE头:
PE文件头紧挨着DOS stub,PE头是PE相关结构NT映像头,里面包含着许多PE装载器用到的重要字段,实际上还是一个结构。
执行体在支持PE文件结构的操作系统中执行时,PE装载器将从MS-DOS头结构中e_lfanew字段里找到PE头的起始偏移量,加上基地址就得到PE文件头的指针。
IMAGE_NT_HEADERS STRUCT
{
+0h DWORD Signature
+4h IMAGE_FILE_HEADER FileHeader
+18h IMAGE_OPTIONAL_HEADER32 OptionalHeader
}IMAGE_NT_HEADERS ENDS;
+0h、+4h、+18h是每个字段相对于结构的偏移地址,NT头有三个字段。
第一是一个标识,标识这是一个有效的PE文件,字段被设置为00004550h,ASCII码是PE00,标识这PE头的开始。
+0h、+4h、+18h是每个字段相对于结构的偏移地址,NT头有三个字段。
第一是一个标识,标识这是一个有效的PE文件,字段被设置为00004550h,ASCII码是PE00,标识这PE头的开始。
第二个又是一个结构,这个结构是文件头,IMAGE_FILE_HEADER。
IMAGE_FILE_HEADER 结构
IMAGE_FILE_HEADER 结构
typedef struct _IMAGE_FILE_HEADER
{
+04h WORD Machine; // 运行平台
+06h WORD NumberOfSections; // 文件的区块数目
+08h DWORD TimeDateStamp; // 文件创建日期和时间
+0Ch DWORD PointerToSymbolTable; // 指向符号表(主要用于调试)
+10h DWORD NumberOfSymbols; // 符号表中符号个数(同上)
+14h WORD SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 结构大小
+16h WORD Characteristics; // 文件属性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
Machine存放可执行文件的目标CPU类型。
Machine存放可执行文件的目标CPU类型。
NumberOfSection存放的是区块的数目。
TimeDataStamp表明文件是何时被创建的。
PointerToSymbolTable指向符号表。
SizeOfOptionalHeader存放IMAGE_NT_HEADERS第三个字段的大小。
Characteristics存放文件属性,有选择的通过几个值可以运算得到。
IMAG_NT_HEADERS的第三个字段下节分析。