PE檔案詳解三
上一篇講到了資料目錄表的結構和怎找到到資料目錄表(DataDirectory[16]),這篇我們我來講講資料目錄表後面的另一個結構——區塊表。
0x01 區塊
區塊就是PE載入器將PE檔案載入後,將PE檔案分割成若干塊,每塊包含不同的資訊,由讀寫資料塊.data,程式碼塊.code,只讀資料塊.rdata等等,一般至少得有讀寫資料塊和程式碼塊。區塊的的劃分資訊儲存在一張名為區塊表(IMAGE_SECTION_HEADER)的結構中。區塊表緊鄰著PE檔案頭IMAGE_NT_HEAER。它的結構如下:
typedef struct _IMAGE_SECTION_HEADER
{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 節表名稱,如“.text”
//IMAGE_SIZEOF_SHORT_NAME=8
union
{
DWORD PhysicalAddress; // 實體地址
DWORD VirtualSize; // 真實長度,這兩個值是一個聯合結構,可以使用其中的任何一個,一
// 般是取後一個
} Misc;
DWORD VirtualAddress; // 節區的 RVA 地址
DWORD SizeOfRawData; // 在檔案中對齊後的尺寸
DWORD PointerToRawData; // 在檔案中的偏移量
DWORD PointerToRelocations; // 在OBJ檔案中使用,重定位的偏移
DWORD PointerToLinenumbers; // 行號表的偏移(供除錯使用地)
WORD NumberOfRelocations; // 在OBJ檔案中使用,重定位項數目
WORD NumberOfLinenumbers; // 行號表中行號的數目
DWORD Characteristics; // 節屬性如可讀,可寫,可執行等} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
大小位40位元組。由於它緊鄰PE檔案頭,而PE檔案頭的中的Data[16]中的最後一個保留雙字開頭為100h+F0h=1F0h故區塊表的開始位為1F0h+8h=1f8h,共佔四十個位元組,如下圖:
由上圖我們可讀出很多重要資訊,前八個位元組可以知道這是個.code塊,後面四個位元組為00001000h這個是VirtualSize欄位即Vsize,再後面四個位元組是00001000h這個是VirtualAddress,即RAV欄位,這個欄位很有用,後面將會講到。再後面是00000200h,標識的是SizeOfRawData欄位,這個欄位也很有用。再後面的幾個欄位就不再介紹了,其實用的也不多,用到了可以再進行分析。上圖可知Code區段後面就是DATA區段了,分析方法和CODE欄位一樣,這裡就不再做介紹了。
對於上述的分析其實我們也可以通過工具來完成,我們今天來使用另一個強大的工具PEID,這個工具對於脫殼來說很有用。我們開啟PEID.exe。直接把檔案拖到PEID視窗即可,點選EP段:邊上的按鈕即可檢視剛剛分析的內容。如下圖:
顯然我們的分析是正確的。注意這裡寫的V偏移即為RAV,V大小即為Vsize,R大小即為SizeOfRawData,至於R偏移後面會介紹。