标準PE頭
32位和64位PE頭結構體有點差異,但是差異不是很大。
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_NT_HEADERS64 {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
擴充PE頭
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
成員 | 大小(十進制) | 說明 |
---|---|---|
Magic | 2位元組 | PE32:10B、PE32+(64):20B,可以用來确認是32位還是64位程式 |
MajorLinkerVersion | 1位元組 | 連結器版本号 |
MinorLinkerVersion | 1位元組 | 連結器版本号 |
SizeOfCode | 4位元組 | 所有代碼節的總和,檔案對齊後的大小,由編譯器填寫 |
SizeOfInitializedData | 4位元組 | 包含所有已經初始化資料的節的總大小,檔案對齊後的大小,由編譯器填寫 |
SizeOfUninitializedData | 4位元組 | 包含未初始化資料的節的總大小,檔案對齊後的大小,由編譯器填寫 |
AddressOfEntryPoint | 4位元組 | 程式入口,目前PE檔案從哪個位置開始執行,配合ImageBase(記憶體鏡像基址)來看 |
BaseOfCode | 4位元組 | 代碼開始的基址,由編譯器填寫 |
BaseOfData | 4位元組 | 資料開始的基址,由編譯器填寫 |
ImageBase | 4位元組 | 記憶體鏡像基址,目前PE檔案執行時從哪個記憶體位置展開 |
SectionAlignment | 4位元組 | 記憶體對齊 |
FileAlignment | 4位元組 | 檔案對齊 |
MajorOperatingSystemVersion | 2位元組 | 辨別作業系統版本号,主版本号 |
MinorOperatingSystemVersion | 2位元組 | 辨別作業系統版本号,次版本号 |
MajorImageVersion | 2位元組 | PE檔案自身的版本号 |
MinorImageVersion | 2位元組 | PE檔案自身的版本号 |
MajorSubsystemVersion | 2位元組 | 運作所需子系統版本号 |
MinorSubsystemVersion | 2位元組 | 運作所需子系統版本号 |
Win32VersionValue | 4位元組 | 子系統版本的值,必須為0 |
SizeOfImage | 4位元組 | 記憶體中整個PE檔案的映射尺寸,可以比實際的值大,必須是SectionAlignMent(記憶體對齊)的整數倍 |
SizeOfHeaders | 4位元組 | 所有頭+節表按照檔案對齊後的大小,否則加載會出錯 |
CheckSum | 4位元組 | 校驗和,一些系統檔案由要求用來判斷檔案是否被修改,不是所有程式都有。 整個PE檔案以2個位元組相加,加完以後如果溢出不管,得到的結果+檔案長度=校驗和 |
Subsystem | 2位元組 | 子系統,驅動程式:1、圖形界面:2、控制台或者DLL:3 |
DllCharacteristics | 2位元組 | 檔案特征,不是針對DLL檔案的 |
SizeOfStackReserve | 4位元組 | 初始化時保留的棧大小 |
SizeOfStackCommit | 4位元組 | 初始化時實際送出的棧的大小(初始化時真正使用的棧的大小) |
SizeOfHeapReserve | 4位元組 | 初始化時保留的堆大小 |
SizeOfHeapCommit | 4位元組 | 初始化時實踐送出的堆的大小(初始化時真正使用的堆的大小) |
LoaderFlags | 4位元組 | 調試相關 |
NumberOfRvaAndSizes | 4位元組 | 目錄項目數量,目前程式會用到各種表,如導入表導出表等,描述有多少個這種表 |
DataDirector | 不确定 | 結構體數組,NumberOfRvaAndSizes的長度是多少它的長度就是多少 |
注意:
AddressOfEntryPoint(程式入口)是相對的位址,也就是ImageBase(記憶體鏡像基址) + AddressOfEntryPoint(程式入口)。
IMAGE_OPTIONAL_HEADER->DllCharacteristics
資料位 | 常量符号 | 為1時的含義 |
---|---|---|
保留,必須為0 | ||
1 | 保留,必須為0 | |
2 | 保留,必須為0 | |
3 | 保留,必須為0 | |
6 | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | DLL可以在加載時被重定位 |
7 | IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY | 強制代碼實施完整性驗證 |
8 | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | 該映像相容DEP(Intel的硬體層面修複漏洞的東西) |
9 | IMAGE_DLLCHARACTERISTICS_NO_ISOLATION | 可以隔離,但并不隔離此映像 |
10 | IMAGE_DLLCHARACTERISTICS_NO_SEH | 映像不适用SEH |
11 | IMAGE_DLLCHARACTERISTICS_NO_BIND | 不綁定映像 |
12 | 保留,必須為0 | |
13 | IMAGE_DLLCHARACTERISTICS_WDM_DRIVER | 該映像為一個WDM driver |
14 | 保留,必須為0 | |
15 | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWAR | 可用于終端伺服器 |