最近看了《逆向工程核心原理》,其中第25.4節講了更改pe檔案讓目標檔案載入我們的動態庫。現在做一下完整介紹。
pe檔案的匯入dll資訊儲存在idt中,於是我們只需將dll加到目標pe檔案的idt中,這時我們得先看一下idt的空間大小。
1.檢視idt:
首先用peview檢視目標程式,看import directory table內容
可見位址範圍從76cc---772f,用hxd觀察該範圍記憶體空間
我們可以看到idt由乙個個結構體構成,每個結構體大小為0x14(20)位元組
2.移動idt
移動idt我們有三種方法:
1.查詢檔案中的空閒區域
2.增加最後乙個節區的大小
3.增加乙個新節區
首先我們嘗試第一種方法。
我們可以看到在節區的.rdata最後部分存在大量空白區域,pe檔案稱這種空白區域稱為null-padding
這時我們還要確認這個部分是否可用,我們觀察.rdata大小為2e00,但是實際使用大小為2c56於是,我們可以用剩下的1aa位元組位址
我們在raw:7e80(rva:8c80)處建立idt
資料的檔案偏移
=(資料
rva -
節rva) +
節的檔案偏移
rvatoraw
raw -porintertorawdata = rva- virtualaddress
raw = rva -virtualaddress+pointertorawdata(address of entry point)
所以rva=7e80(當前raw)-5200(.rdata節起始raw)+6000(.rdata節rva)
現在新加入乙個匯入函式,導致idt增大0x14位元組,所以在更改檔案160處的idt的rva為8c80,size為78
3.刪除繫結匯入表
若要正常匯入dll,需要向繫結匯入表新增資訊。但是繫結匯入表是個可選項,所以為了方便可刪除。如果繫結匯入表資訊錯誤,則執行失敗,但是沒有繫結匯入表反而沒有問題。本例的繫結匯入表資訊為0,所以不用刪除,但是其他檔案需注意。
4.建立新的idt
完全複製原idt內容(76cc---772f ),然後覆蓋到新的idt位址處
5。設定name,int,iat
6.修改.rdata的屬性
向iat節區頭新增image_sec_mem_write(80000000)屬性
至此,我們任務完成。
我們發現原檔案的iat也位於.rdata節區,且原.rdata節區並沒有可寫屬性,為什麼也可以正常執行呢?這是因為在pe頭中的image_optional_header結構的datadirectory陣列中存在iat,若iat存在於該區域,即使相應的節區沒有可寫屬性也沒事。
載入PE檔案 PE載入器模擬法
1 找到檔案載入到記憶體的基址 通常為0x0040 0000 2 取得記憶體對齊粒度 3 載入pe頭,按照記憶體對齊粒度讀取到指定起始位址的記憶體處 4 載入各個節。得到節數目,定位節表,按照記憶體對齊粒度讀取到記憶體,不足的用0填充。5 基址不對,需要重定位修復。include stdafx.h ...
載入PE檔案 記憶體對映檔案
將程式安裝記憶體對齊的方式讀取到記憶體有兩種方法 1 記憶體對映檔案 2 pe載入器模擬法 1 記憶體對映檔案 lpheader所指記憶體是唯讀的,儘管是page readwrite include stdafx.h include include int main int argc,char ar...
PE檔案載入過程揭秘(2)
2011年10月09日 星期日 16 23 自 cvvd 最終編輯 cvvd 圖1pe 載入器在完成檔案實體資料到記憶體虛擬資料的對映之後,便開始從位於 image option header 末端的image data directory 陣列的第 2項 如圖 2 取出輸入表的 rva和大小,準備...