向PE文件中添加一個Section


背景

之前說過直接向類HelloWorld.exe的可執行文件添加一個MessageBox彈窗, 但有時候, 需要添加的內容太多了, 因為數據與代碼一起插入, 以至於可執行文件本身沒有足夠的空閑空間存放這些內容時, 就需要添加一個Section.
 

確認節區頭后面還有空間

用工具查看一下最后一個節區頭后面是否還有多余的空間, 一般情況都會有的. 但若沒有的話, 就要移動節區頭后面的文件內容, 這個比較復雜, 在這里不說.
一般會結合PE View 和 WinHex 這兩個工具, 如之前的HelloWorld.exe

先用PE View 查看最后一個節區頭的起始地址: 00000218   可以推算出最后一個節區頭的結束地址: 0000023F 

框選的部分就是最后一個節區頭的內容
 
可以看到紅框中的部分, 有足夠的空間去添加一個節區頭信息. 因為這個需要確保添加一個節區頭后, 后面還有一個節區頭的空間, 並且其值全為0
 

覆寫一個節區頭信息

接下來就是添加一個節區頭信息, 我的做法是復制一下可執行文件原有的最后一個節區頭的內容, 再覆寫到其后面.  在WinHex中框選內容后, 右鍵 -> Edit 

Cope Block  -> Normally  ( 框選后直接Ctrl + C 也行 )
 
 
覆寫操作: 點選要覆寫的起始地址, 在這里是 00000240  一樣先是 右鍵 -> Edit , 再就是 Clipboard Data Write ( 也可以直接ctrl + b )

 
但這里千萬不要點了Paste (Ctrl + V ) , 因為那個是向文件里插入之前復制的內容, 這樣的話, 后面的內容就會向后偏移了, 最后導致文件頭信息中的文件偏移參數不對了.
 
 
到這里, 先保存一下!
 

修改Number Of Sections的值

完成上面的工作, 用PE View查看的時候, 還是不會看到新添的這個節區頭的信息的.

所以需要去修改一下Number Of Sections 的值, 其實就是對其值加1
 
還是要用PE View查到Number Of Sections 的文件偏移 ( 000000D6 )

 
再用WinHex去到 000000D6 看一下(至於為什么不是 0003 而是0300的問題, 去看基礎知道 )

 
把其中的3直接加1 改為4就好.  保存 
 
這個時候再用PE View查看, 就會發現多了一個節區頭信息了

 
重復的.data節區頭, 我習慣改一下新節區頭的名稱


這時, 會發現節區也多了一個, 但點開節區, 會發現, .dx節區和.data節區其實是同樣的, 看文件偏移就知道
 
 
這個是因為.dx節區頭的內容是從.data節區頭復制過來的, 所以其中的文件偏移都是一樣的. 這個后面再說
 

獲取 File Alignment 和 Section Alignment的值

用PE View, 點開 PE可選頭信息: 

 
 
 
Section Alignment 的值為    00001000

      File Alignment 的值為    00001000

上面的值都是十六進制的, 先記下來, 后面會用到的
 

在文件中為.dx節區頭添加節區

這個時候是需要用到File Alignment的值了, 因為節區在文件中的空間大小必須是FileAlignment的整數倍, 為了方便, 在這里就弄一個FileAlignment的文件空間. 
因為在用WinHex添加節區的時候, 是以整數個字節添加的, 換算一下: 00001000(十六進制)  =  4096(十進制)
具體操作是把WinHex拉到最低部, 在文件最后的一個字節上 右鍵 -> Edit -> Paste Zero Bytes 
 
按提示走, 會看到下面這樣的輸入框, 輸入需要插入的字節數據量, 記得是十進制的, 
這里是一個FileAlignment的大小, 也就是4096. 點 ok .
 
藍色的字就是新添加的, 因為還沒保存, 所以WinHex標記為藍色的, 要記下藍色的開頭地址,這里是  0000A000, 因為這個值就是新節區.dx的文件偏移, 下一步是需要設置到.dx節區頭信息中Pointer to Raw Data上的.
 
記得保存.
 

設置新節區頭的Size of Raw Data和Pointer to Raw Data

還是先用PE View看一下這兩個屬性的文件偏移量:

偏移量分別為:  00000250 和 00000254. 再用WinHex找到這兩個地址:

 
把Size of Raw Data的值改為 00001000, 其實就是把其實的3改為1就可以了.
Pointer to Raw Data的值改為0000A000, 前面一步已經記下來的. 其實就是把7改為A

 
再保存. 並用PE View查看一下: 


這樣就和前面看到的不一樣了, 也證明修改成功了!
 

設置新節區的RVA

首先要查看兩個參數, 分別是前一個節區頭的 Virtual Size 和 RVA 的值:
Virtual Size : 00003E08
           RVA :  00007000
這兩個值相加一下, 得 0000AE08  , 那么新節區的RVA都是需要大於這個值的, 為了方便操作, 一般都取整, 設置為:0000B000 
再查看一下新節區頭的RVA在文件中的偏移量: 

找到文件中的0000024C, 修改上面的值為 0000B000, 再保存:


 

設置新節區的Virtual Size

Virtual Size 指定的是對應節區加載到內存后, 所占用的內存空間大小, 但它的值是Section Alignment的整數倍. 在這例程里, Section Alignment是00001000,  而且也應該不需要更多的內存空間了, 所以直接設置Virtaul Size為00001000就好:
先用PE View 找位置, 熟悉了后應該就不用了:

Virtual Size的文件偏移量是 00000248

 
找到並直接修改保存. 就好了!

 
 

修改Size of Image的值

這個參數是在IMAGE_OPTIONAL_HEADER中的, 它的作用是指定所有節區加載內存后, 一共需要多少內存空間大小. 修改起來問題不大, 就是找到指定的地址, 00000120

 
並在原有的值上加新節區頭中的Virtual Size(00001000), 也就是把B改為C, 再保存


 
到這里, 把程序運行起來, 不報錯, 基本上都證明是操作正確了!! 
 

修改新節區的屬性(權限)

上面的操作是成功添加了一個節區, 還沒上, 我們是需要向里面插入可執行代碼和數據的. 但節區頭信息里有一個參數會限定這個節區所能做的事, 下面看看這個參數: 
其中 IMAGE_SCN_CNT_INITIALIZED_DATA 說的是這個節區包含了初始化數據
剩下的  IMAGE_SCN_MEM_READ 和  IMAGE_SCN_MEM_WRITE 就是說程序可以對這個節區進行讀與寫操作.
但這樣的話, 如果是插入了代碼, 沒有執行權限是不行的哦!
 
如果不知道怎么設置, 其實我們可以參考一下.text節區頭中的  Characteristics :
 
  其實  IMAGE_SCN_CNT_CODE 說的是這個節區包含了可執行代碼, 然后  IMAGE_SCN_MEM_EXECUTE 給了這個節區執行的權限. 
只要在新節區頭中 Characteristics 的值按位與運算就行了, (其實直接加20000020就行了, 但這個說法不夠嚴謹)
 
新節區  Characteristics 的文件地址為 00000264 
再保存: 
 
 
具體怎么插入代碼, 那是另外的工作, 在這里不說. 

http://www.cnblogs.com/dilex/p/5065007.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM