PE文件詳解九:資源結構體


Windows 將程序的各種界面定義為資源,包括加速鍵(Accelerator)、位圖(Bitmap)、光標(Cursor)、對話框(Dialog Box)、圖標(Icon)、菜單(Menu)、串表(String Table)、工具欄(Toolbar)和版本信息(Version Information)等。
資源有很多種類型,每種類型的資源中可能存在多個資源項,這些資源項用不同的ID 或者名稱來區分。但是要將這么多種類型的不同ID 的資源有序地組織起來是一件非常痛苦的事情,因此,我們采取類似於磁盤目錄結構的方式保存。
PE 文件中的資源是按照 資源類型 -> 資源ID -> 資源代碼頁 的3層樹型目錄結構來組織資源的,通過層層索引才能夠進入相應的子目錄找到正確的資源。

資源目錄結構:
數 據目錄表中的 IMAGE_DIRECTORY_ENTRY_RESOURCE 條目(第三項)包含資源的 RVA 和大小。資源目錄結構中的每一個節點都是由 IMAGE_RESOURCE_DIRECTORY 結構和緊跟其后的數個IMAGE_RESOURCE_DIRECTORY_ENTRY 結構組成的。
我們再來看這張圖:



IMAGE_RESOURCE_DIRECTORY STRUCT 【資源表位於數據目錄表的第三項,共動態分配字節,其中結構體中的成員指出的RVA偏移量都是對於此結構體的地址作為基地址】
{
+00 h DWORD Characteristics ; 理論上為資源的屬性,不過事實上總是0
+04 h DWORD TimeDateStamp ; 資源的產生時刻
+08 h WORD MajorVersion ; 理論上為資源的版本,不過事實上總是0
+0A h WORD MinorVersion
+0C h WORD NumberOfNamedEntries ; 以名稱(字符串)命名的入口數量
+0E h WORD NumberOfIdEntries ; 以ID(整型數字)命名的入口數量
};IMAGE_RESOURCE_DIRECTORY ENDS

后面緊接着一個結構體,個數由上個結構指出:

IMAGE_RESOURCE_DIRECTORY_ENTRY STRUCT
{
+10 h DWORD Name ; 目錄項的名稱字符串指針或ID,高位為1時指向子結構體一
+14 h DWORD OffsetToData ; 目錄項指針,高位為1時指向子結構體二
};IMAGE_RESOURCE_DIRECTORY_ENTRY ENDS

Name 字段完全是個百變精靈,改字段定義的是目錄項的名稱或ID。

當結構用於第一層目錄時,定義的是資源類型;

當結構定義於第二層目錄時,定義的是資源的名稱;

當結構用於第三層目錄時,定義的是代碼頁編號。
注意:

當最高位為 0 的時候,表示字段的值作為 ID 使用;

而最高位為 1 的時候,字段的低位作為指針使用(資源名稱字符串是使用 UNICODE編碼),但是這個指針不是直接指向字符串,而是指向一個IMAGE_RESOURCE_DIR_STRING_U 結構的。
子結構體一:

IMAGE_RESOURCE_DIR_STRING_U STRUCT
{
+00 h DWORD Length ; 字符串的長度
+04 h DWORD NameString ; UNICODE字符串,由於字符串是不定長的。由Length 制定長度
};IMAGE_RESOURCE_DIR_STRING_U ENDS

OffsetOfData 字段是一個指針,

當最高位為 1 時,低位數據指向下一層目錄塊的其實地址;

當最高位為 0 時,指針指向 IMAGE_RESOURCE_DATA_ENTRY 結構。


注意:將 Name 和 OffsetToData 用做指針時需要注意,該指針是從資源區塊開始的地方算起的偏移量(即根目錄的起始位置的偏移量),不是我們習慣的 RVA 哦。


最后,在上圖中我們看到,在第一層的時候,IMAGE_RESOURCE_DIRECTORY_ENTRY 的Name 字段作為資源類型使用。
具體類型匹配見下表:



經 過三層 IAMGE_RESOURCE_DIRECTORY_ENTRY (一般是3層,偶爾少一些。第一層資源類型,第二層資源名,第三層是資源的 Language),第三層目錄結構中的 OffsetOfData 指向 IMAGE_RESOURCE_DATA_ENTRY 結構。該結構描述了資源數據的位置和大小,定義如下:
子結構體二:

IMAGE_RESOURCE_DATA_ENTRY STRUCT
{
+00 h DWORD OffsetToData ; 資源數據的RVA
+04 h DWORD Size ; 資源數據的長度
+08 h DWORD CodePage ; 代碼頁, 一般為0
+0C h DWORD Reserved ; 保留字段
};IMAGE_RESOURCE_DATA_ENTRY ENDS


此處的 IMAGE_RESOURCE_DATA_ENTRY 結構就是真正的資源數據了。結構中的OffsetOfData 指向資源數據的指針,其為 RVA 值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM