PE (Portable Executable) 格式是 Windows 執行檔(EXE、DLL、SYS 等)的標準結構。本文整理作者編寫 PE 分析工具時的心得,重點補充 Delphi windows.pas 未定義的資源目錄相關結構與常數。
type
// 資源目錄表頭
TImageResourceDirectory = packed record
Characteristics: DWORD;
TimeDateStamp: DWORD;
MajorVersion, MinorVersion: WORD;
NumberOfNamedEntries, NumberOfIdEntries: WORD;
end;
// 目錄項目(項目可能是字串名稱或數值 ID,可能指向子目錄或資料實體)
TImageResourceDirectoryEntry = packed record
Name: DWORD; // 高位=1 表示字串偏移,否則為 ID
OffsetToData: DWORD; // 高位=1 表示子目錄偏移,否則為資料項目偏移
end;
// 字串名稱結構
TImageResourceDirectoryString = packed record
Length: WORD;
NameString: CHAR; // 實際為變長陣列
end;
// Unicode 字串名稱
TImageResourceDirStringU = packed record
Length: WORD;
NameString: WCHAR;
end;
// 資料實體項目
TImageResourceDataEntry = packed record
OffsetToData, Size, CodePage, Reserved: DWORD;
end;
IMAGE_FILE_EXECUTABLE_IMAGE ($0002), IMAGE_FILE_DLL ($2000), IMAGE_FILE_SYSTEM ($1000)…IMAGE_FILE_MACHINE_I386 ($014c), IMAGE_FILE_MACHINE_AMD64 ($0500), IMAGE_FILE_MACHINE_ARM64 ($0AA64)…IMAGE_SCN_CNT_CODE ($20), IMAGE_SCN_MEM_EXECUTE ($20000000), IMAGE_SCN_MEM_READ ($40000000), IMAGE_SCN_MEM_WRITE ($80000000), 對齊旗標 IMAGE_SCN_ALIGN_* 等。function BeTrue(fg, Value: Cardinal): Boolean;
begin
Result := (fg and Value) <> 0; // 原文邏輯有誤,此處修正為標準位元檢測
end;
資源目錄遍歷至少需兩層巢狀迴圈(類型 → 名稱/ID → 語言 → 資料),具體實作視分析工具需求而定。本文提供的結構定義與常數表可直接用於開發 PE 查看器、資源提取器、殼分析器等工具。