还记得第一次见到PE这个名词的时候,还是在铜陵市图书馆里,在一本《计算机学报》里看到的,也不知道是哪一期了,当时也没看明白说的什么,看的云里雾去。第二次又见PE是半年前,因为工作需要,花了几天通了解了一遍,现在又忘的差不多,其中也有一部分当时看的就似懂非懂。所以现在在拾起来再看一遍,谁叫它是Windows的基础呢。费话就不多说了,下面开始。
PE结构鸟瞰
一、PE文件的存储形式
磁盘中的PE文件 ==>> 0:+-------------------+ +-------------------+ ImageBase <<=== 内存中的PE文件
| DOS Header | ----> | DOS Header |
|--------------------| |-------------------|
| PE Header | ----> | PE Header |
|--------------------| |-------------------|
| Section Talbe | ----> | Section Talbe |
|--------------------| |-------------------|
| Section 1 | -+ | |
|--------------------| +--> | Section 1 |
| Section 2 | -+ | |
|--------------------| | |------------------|
| ... | +--> | |
|--------------------| | Section 2 |
| Section n | -+ | |
+--------------------+ | |------------------|
| | ... |
| |------------------|
| | |
+--> | Section 2 |
| |
+-------------------+
一般文件节(FileAlignment)的大小为512B(0x200),内存节(SectionAlignment)的大小为4K(0x1000)。也有文件节等于内存节的,这样载入速度是很快的,但相对来说,文件所占的磁盘空间也较大。
二、PE文件结构定义
可参考头文件WINNT.H
1 DOS Header: _IMAGE_DOS_HEADER结构
记住结构中的最后一个LONG型的成员e_lfanew,一般在基址的3C偏移处,它的值指向PE Header的偏移。
2 PE Header: _IMAGE_NT_HEADERS结构
其结构定义为:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
_IMAGE_NT_HEADERS结构又包含了两个结构:IMAGE_FILE_HEADER文件头结构和IMAGE_OPTIONAL_HEADER可选头结构。
1) IMAGE_FILE_HEADER文件头结构比较简单,其结构为:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;//目标CPU
WORD NumberOfSections;//节的数目
DWORD TimeDateStamp;//时间戳
DWORD PointerToSymbolTable;//
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;//可选头大小
WORD Characteristics;//文件属性标志位:可执行文件,驱动程序,DLL文件,系统文件等等。
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
2) IMAGE_OPTIONAL_HEADER最为复杂,
在这只要记住它包含了一个IMAGE_DATA_DIRECTORY数据目录的结构就行了。
3 Section Talbe节表:
节表数目有文件头结构的NumberOfSections成员指定。节表结构定义如下:
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//节名,可为任意,对OS不影响。
union {
DWORD PhysicalAddress;
DWORD VirtualSize;//一般指定为该项,该节在内存中的大小
} Misc;
DWORD VirtualAddress;//该节在内存中的起始偏移量
DWORD SizeOfRawData;//该节在磁盘文件中数据的大小
DWORD PointerToRawData;//该节在磁盘文件中的起始偏移量
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;//节在内存中的特征:可读,可写,可执行等等。
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
PE结构鸟瞰
一、PE文件的存储形式
磁盘中的PE文件 ==>> 0:+-------------------+ +-------------------+ ImageBase <<=== 内存中的PE文件
| DOS Header | ----> | DOS Header |
|--------------------| |-------------------|
| PE Header | ----> | PE Header |
|--------------------| |-------------------|
| Section Talbe | ----> | Section Talbe |
|--------------------| |-------------------|
| Section 1 | -+ | |
|--------------------| +--> | Section 1 |
| Section 2 | -+ | |
|--------------------| | |------------------|
| ... | +--> | |
|--------------------| | Section 2 |
| Section n | -+ | |
+--------------------+ | |------------------|
| | ... |
| |------------------|
| | |
+--> | Section 2 |
| |
+-------------------+
一般文件节(FileAlignment)的大小为512B(0x200),内存节(SectionAlignment)的大小为4K(0x1000)。也有文件节等于内存节的,这样载入速度是很快的,但相对来说,文件所占的磁盘空间也较大。
二、PE文件结构定义
可参考头文件WINNT.H
1 DOS Header: _IMAGE_DOS_HEADER结构
记住结构中的最后一个LONG型的成员e_lfanew,一般在基址的3C偏移处,它的值指向PE Header的偏移。
2 PE Header: _IMAGE_NT_HEADERS结构
其结构定义为:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
_IMAGE_NT_HEADERS结构又包含了两个结构:IMAGE_FILE_HEADER文件头结构和IMAGE_OPTIONAL_HEADER可选头结构。
1) IMAGE_FILE_HEADER文件头结构比较简单,其结构为:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;//目标CPU
WORD NumberOfSections;//节的数目
DWORD TimeDateStamp;//时间戳
DWORD PointerToSymbolTable;//
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;//可选头大小
WORD Characteristics;//文件属性标志位:可执行文件,驱动程序,DLL文件,系统文件等等。
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
2) IMAGE_OPTIONAL_HEADER最为复杂,
在这只要记住它包含了一个IMAGE_DATA_DIRECTORY数据目录的结构就行了。
3 Section Talbe节表:
节表数目有文件头结构的NumberOfSections成员指定。节表结构定义如下:
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//节名,可为任意,对OS不影响。
union {
DWORD PhysicalAddress;
DWORD VirtualSize;//一般指定为该项,该节在内存中的大小
} Misc;
DWORD VirtualAddress;//该节在内存中的起始偏移量
DWORD SizeOfRawData;//该节在磁盘文件中数据的大小
DWORD PointerToRawData;//该节在磁盘文件中的起始偏移量
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;//节在内存中的特征:可读,可写,可执行等等。
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;