PE知識復習之PE新增節
一丶為什么新增節.以及新增節的步驟
例如前幾講.我們的PE文件在空白區可以添加代碼.但是這樣是由一個弊端的.因為你的空白區節屬性可能是只讀的不能執行.如果你修改了屬性.那么程序就可能出現問題.所以新增一個節可以實現我們的代碼.
等等.
1.新增節的步驟
1.在最后一個節位置添加一個節.如果沒有空白位置.自己需要給擴展頭擴大.並且自己修正節的偏移.
2.修改文件頭中節表個數.
3.添加的新節表修改節表的屬性. 節.VirtualAddress .這個成員指定了這個節在內存哪里展開.所以需要修改.
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值 + 你行增節數據大小 按照內存對齊)