參考:http://blog.csdn.net/huanjieshuijing/article/details/5874365
http://lwglucky.blog.51cto.com/1228348/283812
涉及到的資料結構
我們可以在Winnt.h這個檔案中找到關於PE檔案頭的定義:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
//PE檔案頭標誌 :“PE/0/0”。在開始DOS header的位移3CH處所指向的地址開始(待研究和考證)
IMAGE_FILE_HEADER FileHeader; //PE檔案物理分布的資訊
IMAGE_OPTIONAL_HEADER32 OptionalHeader;//PE檔案邏輯分布的資訊
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;//該檔案運行所需要的CPU,對於Intel平台是14Ch
WORD NumberOfSections;//檔案的節數目
DWORD TimeDateStamp;//檔案建立日期和時間
DWORD PointerToSymbolTable;//用於調試
DWORD NumberOfSymbols;//符號表中符號個數
WORD SizeOfOptionalHeader;//OptionalHeader 結構大小
WORD Characteristics; //檔案資訊標記,區分檔案是exe還是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;//標誌字(總是010bh)
BYTE MajorLinkerVersion;//連接器版本號碼
BYTE MinorLinkerVersion;
DWORD SizeOfCode;//程式碼片段大小
DWORD SizeOfInitializedData;//已初始化資料區塊大小
DWORD SizeOfUninitializedData;//未初始化資料區塊大小
DWORD AddressOfEntryPoint;
PE裝載器準備啟動並執行PE檔案的第一個指令的RVA,若要改變整個執行的流程,可以將該值指定到新的RVA,這樣新RVA處的指令首先被執行(以往許多文章都有介紹RVA,請大家先瞭解)。
DWORD BaseOfCode;//程式碼片段起始RVA
DWORD BaseOfData;//資料區段起始RVA
//
// NT additional fields.
//
DWORD ImageBase;//PE檔案的裝載地址
DWORD SectionAlignment;//塊對齊
DWORD FileAlignment;//檔案塊對齊
WORD MajorOperatingSystemVersion;//所需作業系統版本號碼
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;//使用者自訂版本號碼
WORD MinorImageVersion;
WORD MajorSubsystemVersion;//win32子系統版本。若PE檔案是專門為Win32設計的
WORD MinorSubsystemVersion;//該子系統版本必定是4.0否則對話方塊不會有3維立體感
DWORD Win32VersionValue;
DWORD SizeOfImage;//記憶體中整個PE映像體的尺寸
DWORD SizeOfHeaders;//所有頭+節表的大小
DWORD CheckSum;//校正和
WORD Subsystem; //NT用來識別PE檔案屬於哪個子系統
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];//IMAGE_DATA_DIRECTORY 結構數組。每個結構給出一個重要資料結構的RVA,比如引入地址表等 IMAGE_NUMBEROF_DIRECTORY_ENTRIES=16
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;//表的RVA地址
DWORD Size;//大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
PE檔案頭後是節表,在winnt.h下如下定義
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//節表名稱,如“.text” IMAGE_SIZEOF_SHORT_NAME = 8
union {
DWORD PhysicalAddress;//物理地址
DWORD VirtualSize;//真實長度
} Misc;
DWORD VirtualAddress;//RVA
DWORD SizeOfRawData;//物理長度
DWORD PointerToRawData;//節基於檔案的位移量
DWORD PointerToRelocations;//重定位的位移
DWORD PointerToLinenumbers;//行號表的位移
WORD NumberOfRelocations;//重定位項數目
WORD NumberOfLinenumbers;//行號表的數目
DWORD Characteristics;//節屬性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;