一丶爲何新增節.以及新增節的步驟blog
例如前幾講.咱們的PE文件在空白區能夠添加代碼.可是這樣是由一個弊端的.由於你的空白區節屬性多是隻讀的不能執行.若是你修改了屬性.那麼程序就可能出現問題.因此新增一個節能夠實現咱們的代碼.內存
等等.io
1.新增節的步驟擴展
1.在最後一個節位置添加一個節.若是沒有空白位置.本身須要給擴展頭擴大.而且本身修正節的偏移.程序
2.修改文件頭中節表個數.im
3.添加的新節表修改節表的屬性. 節.VirtualAddress .這個成員指定了這個節在內存哪裏展開.因此須要修改.d3
4.修改節表文件偏移 節.PointerToRawData 咱們指定了內存中從哪裏展開節.那麼也須要指定這個節在文件中在哪裏展開總結
5.修改節表中的 節數據對齊後的大小. 節.SizeofRawData. 咱們新增的節.本身須要在PE文件添加一段節數據.數據的大小按照文件對齊添加. 而且填寫到這個成員中.命名
6.修改擴展頭的PE鏡像大小. sizeofImage. 這個成員纔是關鍵.若是不按照內存對齊修改鏡像大小.那麼咱們的節就不會映射到內存中.或者PE文件根本沒法執行.數據
二丶根據新增節步驟.實戰手工添加一個節.
1.添加一個節表
添加節表的時候.須要在最後一個節後面添加.隨便哪個PE文件舉例
由於擴展頭中的SizeofHeaders 標明瞭 DOS頭+NT頭 +節表的大小.按照文件對齊存放.因此在400開始纔是節數據.那麼咱們上圖所示.最後一個節表爲.rsrc. 咱們下面有足夠的空間添加一個新的節表.因此咱們複製這個節表.在他後面粘貼.粘貼了一個新的.rsrc節表.
咱們爲這個節重命名爲 AAAA
2.修改節表個數.在文件頭屬性中.
文件頭中有一個屬性記錄了咱們節表的個數.咱們新增了一個節.那麼就須要在原有的個數上加1.找到文件頭記錄節表個數位置.並加一便可.
原爲7,如今改成8便可.
3.修正節表中的偏移.
咱們新增了一個節表.那麼咱們就要爲這個節表指明內存中開始展開的位置. 文件中展開的位置. 以及節數據的大小.
對應的三個成員分別是:
節.VirtualAddress
節.SizeOfRawData
節.PointerToRawData
3.1 節.VirtuallAddress修改
首先第一個成員. 節.virtuallAddress .咱們按照文件對齊.與上一個節表對齊存放便可.
例如上一個節表對齊後的展開位置爲 0x1c000 那麼咱們就修改成 0x1d000
3.2 節.sizeofRawData修改
這個成員就是節數據按照文件對齊後的大小.取決於咱們給這個節添加多少數據.咱們能夠在PE文件後面添加 0x1000個字節.
新增的節開始位置改爲FFFFF方便咱們查看.
咱們添加了0x1000的節數據.那麼這個成員就修改成0x1000
3.3 節.PointerRawToData 文件偏移修改
最後修改的就是節在文件中哪裏展開的. 這個咱們須要看上一個節的文件偏移.以及節數據大小. 算出來的.
例如上一個節 偏移位置爲10. 那麼節數據爲100. 那麼節數據就是從10 ~ 100都是上一個節. 咱們的節展開就要從100位置展開.
例以下圖:
上一個節開始位置是8400 節數據對齊後的大小是0x600 他倆相加則是 0x8A00. 因此咱們的偏移位置在0x8A00開始.
4.修改擴展頭中PE的鏡像大小 SizeofImage
咱們新增了0x1000節數據大小.那麼咱們的鏡像大小也要加0x1000大小進行映射.注意.要按照內存對齊.
咱們的原鏡像大小以及按照內存對齊的方式存放了. 就是0x1D000. 那麼咱們加了0x1000的數據就是 0x1E000大小.咱們修改成0x1E000
保存文件
5.保存文件內存中查看是否映射.
首先運行一下:
能夠成功運行.
去內存中查看.節表是否映射. 咱們節在內存中展開的偏移是 0x1D000 加上咱們的ImageBase 就是 0x41D000位置.
跳轉過去以後發現就是咱們剛纔填寫FFFF的數據.已經成功映射了.至此咱們就爲這個PE文件新增了一個節.
三丶總結
根據上面實戰添加節.進行一個總結.
1.一個節表0x28個字節.在最後一個節表位置添加.若是SizeofHeaders 有足夠空間的狀況下.
2.修改文件頭中節表個數. 文件.SectionNumber = 原有節個數 + 你新增節的個數. 例如: 原爲7.你增長了一個節.就爲8
3.修改節屬性:
節.VirtuallAddress 內存中展開的位置.按照內存對齊. 能夠參照上一個節.virtuallAddress位置.咱們進行修改.
節.SizeofRawData 節數據按照文件對齊後的大小. 節.SizeofRawData = 你添加的節數據大小. 按照文件對齊存放. 例如添加了0x1000.那麼大小就是0x1000
節.PointerToRawData 文件中的偏移. 節.PointerToRawData = ()上一個節.PointerToRawData + 上一個節.SizeofRawData. )
4.修改擴展頭SizeofImage PE鏡像大小. 擴展頭.SizeofImage = 內存對齊(原SizeofImage值 + 你行增節數據大小 按照內存對齊)