可攜式可執行檔(Portable Executable,PE)是 Windows 以及 UEFI PE/COFF 映像使用的可執行檔映像格式。與 ELF 不同,PE 沒有程式標頭表。載入器會根據 COFF 標頭、選擇性標頭、區段表與資料目錄來映射映像。
檔案配置 #
PE 映像以 DOS 標頭(MZ)開頭。其中的 e_lfanew 成員指向 NT 標頭,而 NT 標頭以 PE\0\0 簽章開頭。DOS stub 位於 DOS 標頭之後;有些工具鏈也會在 NT 標頭之前產生非標準的 Rich 標頭。
NT 標頭包含 COFF 檔案標頭,以及對可執行檔映像與 DLL 而言的選擇性標頭。COFF 標頭記錄目標機器、區段數量、時間戳記、符號表位置(最終映像通常未使用)、選擇性標頭大小,以及可執行檔映像或 DLL 等特性。可重新定位的 COFF 物件檔沒有選擇性標頭。
選擇性標頭與定址 #
PE32 選擇性標頭為 224 位元組,PE32+ 標頭為 240 位元組。PE32+ 使用 64 位元定址欄位,並省略 BaseOfData。Magic 會識別 PE32(0x10b)、PE32+(0x20b)或 ROM 映像(0x107)。
RVA(相對虛擬位址)是相對於映像基底的偏移量。執行時,虛擬位址為 ImageBase + RVA;偏好的 ImageBase 只是一項要求,而基底重新定位記錄可讓載入器將啟用 ASLR 的映像映射到其他位置。AddressOfEntryPoint 與 BaseOfCode 都是 RVA。BaseOfCode 識別映像中的第一個程式碼位元組;它不保證所有可執行程式碼都是連續的。
FileAlignment 控制區段在磁碟上的對齊,而 SectionAlignment 控制記憶體中的對齊,且通常至少同樣大。SizeOfHeaders 涵蓋所有標頭,以及區段資料之前的填補;SizeOfImage 是記憶體中對齊後的範圍。Subsystem 選取所需環境,例如 Windows GUI、主控台或 EFI 開機服務驅動程式。資料目錄會指向匯入、匯出、資源、例外、憑證、基底重新定位、偵錯資訊、TLS 與其他載入器功能的表格。
區段 #
每個區段標頭會將一段檔案資料映射到一段虛擬記憶體,並以可讀、可寫、可執行、已初始化資料或未初始化資料等特性標記。常見名稱包括 .text、.rdata、.data、.pdata 與 .reloc,但名稱是慣例,而非載入器要求。VirtualSize 可能大於 SizeOfRawData;載入器會將剩餘部分填零,未初始化資料就是以這種方式表示。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)