0x01 前言
上一篇講到了數據目錄表的結構和怎找到到數據目錄表(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偏移后面會介紹。