一丶節表信息,PE兩種狀態.以及重要兩個成員解析.數組
肯定節表位置: DOS + NT頭下面就是節表.spa
肯定節表數量: 節表數量在文件頭中存放着.能夠準確知道節表有多少個.調試
節表是一個結構體數組.沒一個節表表示了數據在哪,怎麼存儲.code
下方是節的結構體blog
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.內存中節開始的位置io
咱們分別以PE兩種狀態.來加深一下.在內存中跟文件中節數據起始位置.編譯
VirtualAddress 是內存中節展開的起始地址.咱們能夠隨便打開一個文件.查看內存中起始位置值是多少.class
隨便打開一個文件看一下節表.能夠得出.內存中偏移位置是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.文件中起始位置.
根據第二個成員和第三個成員能夠得出節數據從哪裏結束. 計算公式 節起始位置+節數據對齊後大小 = 節結束位置.
節屬性也很重要. 這個須要查詢.因此必定牢記.