標籤:point 複習 cti bubuko png 就是 struct 中文 pointer
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.檔案中起始位置.
根據第二個成員和第三個成員可以得出節資料從哪裡結束. 計算公式 節起始位置+節資料對齊後大小 = 節結束位置.
節屬性也很重要. 這個需要查詢.所以一定牢記.
PE知識複習之PE的節表