原文出自:www.fishc.com
最近一直在安排第一屆魚c 學習班的事情,忙活了好一陣子,真是對不住大家,還大家久等了,這裡要跟大家說聲不好意思 ^_^
今天我們來談談資源部分,資源部分可以說是 pe 檔案所有結構中,最複雜的一部分,也最讓人揪心。很多朋友都想通過自己動手修改一些遊戲的資源、工具的介面、或者一些軟體的圖示等,都知道要改資源部分。但純粹一進去就像走進了迷宮……出不來……
雖然說是迷霧重重,但是本節的學習確意義非凡,例如我們可以對遊戲進行漢化!怎麼樣?刺激吧?給力吧?我們可以自己漢化我們喜歡的**遊戲哦!
小甲魚pe詳解之資源(pe詳解11)
資源結構
資源是pe 檔案中非常重要的部分,幾乎所有的pe 檔案中都包含著資源,與匯入表和匯出表相比,資源的組織方式要複雜很多,其實我們只要看下圖就知道俺所言不虛。
我們知道我們的資源有很多種型別,每種型別的資源中可能存在多個資源項,這些資源項用不同的id 或者名稱來區分。但是要將這麼多種型別的不同id 的資源有序地組織起來是一件非常痛苦的事情,因此,我們採取類似於磁碟目錄結構的方式儲存。
從圖中我們可以看到,pe 檔案中的資源是按照 資源型別 -> 資源id -> 資源**頁 的3層樹型目錄結構來組織資源的,通過層層索引才能夠進入相應的子目錄找到正確的資源。
資源目錄結構
資料目錄表中的 image_directory_entry_resource 條目(第三項)包含資源的 rva 和大小。資源目錄結構中的每乙個節點都是由 image
_resource
_directory 結構和緊跟其後的數個
image
_resource
_directory_entry 結構組成的。(是不是有點像我們之前提到的檔案目錄?資料夾每個都長得一樣,乙個巢狀另乙個,這樣子可以實現將非常複雜的資料細化切分,小澤瑪利亞、蒼井空、吉澤明步、松島楓……)
我們再來看這張圖:
認識了這層關係後,我們來看下
image
_resource
_directory 這個結構,該結構長度為 16 位元組,共有 6 個字段,定義如下:
image_resource_directory struct
characteristics dword ? ;理論上為資源的屬性,不過事實上總是0image_resource_directory endstimedatestamp dword ? ;資源的產生時刻
majorversion word ? ;理論上為資源的版本,不過事實上總是0
minorversion word ?
numberofnamedentries word ? ;以名稱(字串)命名的入口數量
numberofidentries word ? ;以id(整型數字)命名的入口數量
其實在這裡邊我們唯一要注意的就是 nameberofnamedentries 和 numberofidentries,它們說明了本目錄中目錄項的數量。兩者加起來就是本目錄中的目錄項總和。也就是後邊跟著的
image
_resource
_directory_entry 數目。
資源目錄入口的結構(
image
_resource
_directory_entry
)image
_resource
_directory_entry 緊跟在資源目錄結構後,此結構長度為 8 個位元組,包含 2 個字段。該結構定義如下:
image_resource_directory_entry struct
name dword ? ;目錄項的名稱字串指標或idimage_resource_directory_entry endsoffsettodata dword ? ;目錄項指標
name 字段完全是個百變精靈,改欄位定義的是目錄項的名稱或id。當結構用於第一層目錄時,定義的是資源型別;當結構定義於第二層目錄時,定義的是資源的名稱;當結構用於第三層目錄時,定義的是**頁編號。
注意:當最高位為 0 的時候,表示欄位的值作為 id 使用;而最高位為 1 的時候,欄位的低位作為指標使用(資源名稱字串是使用 unicode編碼),但是這個指標不是直接指向字串哦,而是指向乙個 image_resource_dir_string_u 結構的。
該結構定義如下:
image_resource_dir_string_u struct
length dword ? ; 字串的長度image_resource_dir_string_u endsnamestring dword ? ; unicode字串,由於字串是不定長的。由length 制定長度
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
offsettodata dword ? ; 資源資料的rvaimage_resource_data_entry endssize dword ? ; 資源資料的長度
codepage dword ? ; **頁, 一般為0
reserved dword ? ; 保留字段
千山萬水,此處的
image_resource_data_entry 結構就是真正的資源資料了。結構中的offsetofdata 指向資源資料的指標,其為 rva 值。
工具:peinfo.exe, ultraedit
00054 小甲魚PE詳解之資源(PE詳解11)
資源結構 資源是pe 檔案中非常重要的部分,幾乎所有的pe 檔案中都包含著資源,與匯入表和匯出表相比,資源的組織方式要複雜很多,其實我們只要看下圖就知道俺所言不虛。我們知道我們的資源有很多種型別,每種型別的資源中可能存在多個資源項,這些資源項用不同的id 或者名稱來區分。但是要將這麼多種型別的不同i...
小甲魚PE詳解之資源(PE詳解11)
小甲魚pe詳解之資源 pe詳解11 資源結構 資源是pe 檔案中非常重要的部分,幾乎所有的pe 檔案中都包含著資源,與匯入表和匯出表相比,資源的組織方式要複雜很多,其實我們只要看下圖就知道俺所言不虛。我們知道我們的資源有很多種型別,每種型別的資源中可能存在多個資源項,這些資源項用不同的id 或者名稱...
小甲魚PE詳解之資源(PE詳解11)
小甲魚pe詳解之資源 pe詳解11 資源結構 資源是pe 檔案中非常重要的部分,幾乎所有的pe 檔案中都包含著資源,與匯入表和匯出表相比,資源的組織方式要複雜很多,其實我們只要看下圖就知道俺所言不虛。我們知道我們的資源有很多種型別,每種型別的資源中可能存在多個資源項,這些資源項用不同的id 或者名稱...