PE知識復習之PE的節表
一丶節表信息,PE兩種狀態.以及重要兩個成員解析.
確定節表位置: DOS + NT頭下面就是節表.
確定節表數量: 節表數量在文件頭中存放着.可以准確知道節表有多少個.
節表是一個結構體數組.沒一個節表表示了數據在哪,怎么存儲.
下方是節的結構體
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //8個字節名字.自己可以起.編譯器也可以給定.不重要. union { DWORD PhysicalAddress; DWORD VirtualSize; //節數據沒有對齊后的大小.也就是沒有對齊.節數據有多大. } Misc; DWORD VirtualAddress; //加載到內存中的第一個字節的地址.也就是虛擬地址.節在內存中哪里開始.內存中的VA + ImageBase 才是真正的節開始位置 DWORD SizeOfRawData; //節在文件中對齊后的屬性.跟是可選頭中文件對齊的整數倍. sizeofRawData /文件對齊==0 DWORD PointerToRawData; //在文件中的偏移.是文件對齊成員倍數. DWORD PointerToRelocations; //一下都是調試相關. DWORD PointerToLinenumbers; // WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; //節的屬性 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
節表重要成員都標紅了.我們知道.PE文件有兩種狀態.一種是內存狀態.一種則是文件狀態.
而節就是分別保存了內存中節展開的位置偏移. 以及文件展開后.節數據在文件中的那個偏移位置.
1.內存中節開始的位置
我們分別以PE兩種狀態.來加深一下.在內存中跟文件中節數據起始位置.
VirtualAddress 是內存中節展開的起始地址.我們可以隨便打開一個文件.查看內存中起始位置值是多少.
隨便打開一個文件看一下節表.可以得出.內存中偏移位置是0x1000位置.文件中節數據的位置是0x400. 偏移+ImageBase就是內存中開始的位置.我們看一下.
可以看到機器碼為: 40 30 40 00 90 ..... 那么我們去文件中看一下,看一下節數據是否相同.
2.文件中節開始的位置
根據上方我們觀看節表.得出在文件中的偏移是0x400位置.所以跳轉到文件偏移處.發現節數據跟內存的數據是一樣的.
這也解釋了PE在內存中展開跟在文件中是不一樣的.
也加深了節表中 VirtualAddress成員 以及 PointerToRawData成員了.
值得一說節表的大小是 0x28個字節.也就是兩行半
觀看一行半可以得出節名稱.節在內存中的偏移. 以及節數據在文件中的偏移.
二丶節成員解析
根據上方節中兩個重要成員我們明白了其意思.那么我們看看其他成員.
聯合體中的成員.
聯合體中的成員我們一般看第二個.
union { DWORD PhysicalAddress; DWORD VirtualSize; //節數據沒有對齊后的大小.也就是沒有對齊.節數據有多大. } Misc;
VirtualSize 虛擬大小.指的就是節數據沒有對齊后的大小.
換句話說就是節的數據真實大小. 但是注意,如果此成員大於SizeofRawData.那么就填0.因為實際大小數據.不可能大於對齊后的大小.
SizeOfRawData 這個成員則是對齊后的大小.比如我們節數據大小是0x1FFC 那么對齊后的大小就是0x2000 就是按照對齊之后進行存放的.對齊是按照文件對齊進行對齊的.
根據文件對齊后的大小.那么我們就能確定一個節數據到底由多大.
文件中開始的位置已經有了.然后對齊后的大小也已經有了. 文件開始位置是0x400.對齊后的數據有0x2000.那么節數據大小就是從0x400開始.占0x2000大小.那么結束位置就是0x2400位置.
節的屬性.也就是最后一個成員.表明了這個節是可讀的可寫的.還是可讀可寫可執行. 具體可以查看一下宏.
三丶總結
總結來說節表中重要成員有三個.
1.內存中起始位置
2.節數據對齊后大小
3.文件中起始位置.
根據第二個成員和第三個成員可以得出節數據從哪里結束. 計算公式 節起始位置+節數據對齊后大小 = 節結束位置.
節屬性也很重要. 這個需要查詢.所以一定牢記.