一丶爲何擴大節spa
上面咱們講了,空白區添加咱們的代碼.可是有的時候.咱們的空白區不夠了怎麼辦.因此須要進行擴大節.3d
擴大節其實很簡單.修改節數據對齊後的大小便可. 而且在PE文件中添加0數據進行填充便可.調試
首先看一下咱們的節表code
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //8個字節名字.本身能夠起.編譯器也能夠給定.不重要. union { DWORD PhysicalAddress; DWORD VirtualSize; //節數據沒有對齊後的大小.也就是沒有對齊.節數據有多大. } Misc; DWORD VirtualAddress; //加載到內存中的第一個字節的地址.也就是虛擬地址.節在內存中哪裏開始.內存中的VA + ImageBase 纔是真正的節開始位置 DWORD SizeOfRawData; //修改這個屬性的值,便可擴大節.而且在PE文件中添加相應的0數據進行填充. DWORD PointerToRawData; //在文件中的偏移.是文件對齊成員倍數. DWORD PointerToRelocations; //一下都是調試相關. DWORD PointerToLinenumbers; // WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; //節的屬性 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
二丶擴大節實戰以及注意問題blog
PE擴大節的時候通常是最後一個節.緣由是本身不用修正偏移等各項屬性了.若是是最後一個節擴大就很簡單了.內存
咱們節表要修改的屬性就是將節對齊後的數據進行修改便可.編譯器
公式: 設一塊咱們添加的控件爲x的倍數io
設要修改後的值爲M編譯
那麼 M = (節.sizeofRawData 或者 節.VirtualSize 按照對齊後大小對齊) + X便可.class
看公式很複雜,其實就是節的對齊後的數據.按照內存對齊後修改.而且加上咱們新空間的大小便可.
例如原來大小: 0x600, 你要擴大0x100個字節. 那麼 修改後的值就爲 0x700. 0x700要按照內存對齊進行存放.
還要修改擴展頭中的 SizeofImage(內存PE鏡像大小)
三丶擴大節實戰
1.添加數據
隨便找一個PE文件.在最後文件偏移處添加數據. 好比咱們要擴大0x1000.那麼添加0x1000大小.
開始位置89f0 添加0x1000大小. 那麼結束位置是 0x99F0
爲了確認咱們的節數據會映射到內存.咱們0數據咱們填充爲FFFF
2.修改節表屬性
由於咱們添加了0x1000個字節大小.因此須要修改文件中節表的對齊後的大小. 也就是 節.sizeofRawToData
此時咱們沒有修改以前.
,沒有修改以前數據大小是0x0600.那麼內存中節映射也不會有咱們的FFFF數據. 觀看內存節起始位置爲0x01c000 那麼咱們去內存中
節數據位置看看.是否有咱們的FFF填充的數據
並無咱們的FF數據. 咱們修改文件節對齊數據爲 0x1600.由於加了0x1000的數據.
再次在內存中查看已經有咱們映射的內存了. 第一個是F0結尾.下方是咱們的數據.
可是注意,修改以後並不能直接查看.由於PE無法運行.咱們必須修改擴展頭中的sizeofImage屬性.這樣咱們的內存鏡像大小纔是真正的大小.
我是修改過了.節纔會映射到內存中.因此能夠查看.
3.修改SizeofImage屬性
個人SzieofImage屬性.原值就是按照內存對齊進行存放的.也就是0x01D000. 因此當我增長0x1000個字節的數據.其實並無超過SizeofImage的對其值.因此能夠映射到內存那種.若是加了數據超過了SizeofImage
那麼咱們就須要進行內存對齊了. 加上咱們擴展後的數據.而後進行內存對齊.
4.程序運行.
程序能夠正常運行.而且咱們添加的數據也映射到內存中了.