向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 的值爲    00001000html

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

在文件中爲.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/findumars/p/5788894.html
相關文章
相關標籤/搜索