1. 程式人生 > >PE檔案學習(三)資料目錄表之資源

PE檔案學習(三)資料目錄表之資源

     資源是PE檔案中最複雜的結構了,資源在PE檔案中是以目錄結構的形式存在的,一般情況下分為3層,從根目錄開始分別是資源型別、目錄資源ID與資原始碼頁。

     3層目錄結構都是由一個IMAGE_RESOURCE_DIRECTORY結構為頭部,後面跟著一個IMAGE_RESOURCE_DIRECTORY_ENTRY結構陣列。

      結構體IMAGE_RESOURCE_DIRECTORY_ENTRY如下所示:

typedef  struct  _IMAGE_RESOURCE_DIRECTORY{
DWORD  Characteristics;    //資源屬性標識
DWORD  TimeDateStamp;  //資源建立的時間
WORD    MajorVersion;      //資源主版本
WORD    MinorVersion;       //資源子版本
WORD    NumberOfNamedEntries;  //資源名稱條目個數
WORD    NumberOfIdEntries;   //資源ID條目個數
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;

  結構體IMAGE_RESOURCE_DIRECTORY_ENTRY:
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
{
	union 
	{
		struct 
		{
        DWORD NameOffset:31;    //資源名偏移
		DWORD NameIsString:1;   //資源名為字串
		};	
        DWORD Name;        //資源/語言型別
	WORD Id;           //資源數字ID
	};
	union{
		DWORD OffsetToData;     //資料偏移地址
		struct 
		{
			DWORD OffsetToDirectory:31;   //子目錄偏移地址
			DWORD DataIsDirectory:1;      //資料為目錄
		};
	};
}IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
   其中的Name成員當此結構體位於第一層目錄中時,此欄位儲存有資源型別的值。當此結構體位於第三層目錄中時,此欄位儲存有資源語言區域的型別值

    

  OffsetToDirectory和DataIsDirectory:當DataIsDirectory為1時,OffsetToDirectory的值指向下一層子目錄的偏移。

   這個IMAGE_RESOURCE_DIRECTORY_ENTRY是由兩個大小為4位元組的聯合體組成的,在不同情況下,兩個聯合體中的有效欄位也不同。

        第一個聯合體內的欄位是根據當前結構體所處的目錄層次來決定的,位於第一層目錄時欄位Name有效,儲存的資訊是資源型別;位於第二層目錄時欄位Id或結構體有效,這取決於此資源的索引方式,如果採用的是編號索引就是欄位Id有效,否則結構體有效;位於第三層目錄時欄位Name有效,儲存的資訊是資源語言區域型別。
第二個聯合體內的欄位理論上是根據具體情況而定的,如果下一級是一個子目錄的話,那麼就是結構體生效,如果下一級是資源資料則是欄位OffsetToData生效。

   在經過三層目錄的索引後,最後會到達一個IMAGE_RESOURCE_DATA_ENTRY結構中,這個結構將指引我們找到資源資料。下面這個結構體描述的就是此結構。

typedef struct _IMAGE_RESOURCE_DATA_ENTRY
{
	DWORD OffsetToData;   //資源資料的RAV
	DWORD Size  ;         //資源資料的長度
	DWORD CodePage;       //內碼表
	DWORD Reserved;       //保留欄位
}IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;