一個印象最深得Bug-修復(fù)IAT以及ASLR解決
去年我記得修復(fù)了一個Bug是我印象最深刻的,我們都知道脫殼,首先修改被加殼程序的入口點到程序原來的OEP,然后修改PE程序?qū)氡砟夸浀刂窞樵瓉韺?dǎo)入表地址,或者新建一個節(jié),將這個新節(jié)作為導(dǎo)入表節(jié),并將原導(dǎo)入表內(nèi)容寫入新節(jié)導(dǎo)入表。
這個過程很簡單,OD跟蹤,讓殼運行到原程序OEP(不一定非得OEP,程序領(lǐng)空導(dǎo)入表一般都是處于還原狀態(tài),OEP要知道),這時候可以用PE DUMP脫殼插件或者用LordPe等工具脫殼,程序當前的內(nèi)存映像被dump出來,里面IAT結(jié)構(gòu)完整很容易被發(fā)現(xiàn)。
dump后程序不能正常運行很可能是導(dǎo)入表位置錯誤(也可能是程序有自校驗),因為dump出來的只是內(nèi)存中的映像快照,導(dǎo)入表目錄還是指向殼的導(dǎo)入表,這時,需要用導(dǎo)入表修復(fù)軟件查找dump出的PE文件原導(dǎo)入表首地址,然后修正導(dǎo)入表目錄中導(dǎo)入表的位置,或重建導(dǎo)入表。Import Fix導(dǎo)入表修復(fù)軟件會新建一個節(jié)來保存原導(dǎo)入表數(shù)據(jù),并將導(dǎo)入表目錄指向新節(jié)導(dǎo)入表位置。在搜索導(dǎo)入表時可能導(dǎo)入表被破壞,Import Fix會識別出一些無效的IAT項,可以將其剔除掉。
第一次脫殼的時候就不知道這點,以為直接就可以用了。哈哈。首先得說一下程序調(diào)用DLL導(dǎo)出函數(shù)的原理,PE調(diào)用DLL里的函數(shù),一般是先加載這個DLL模塊到它的進程地址空間,
然后在加載后的地址范圍內(nèi)找到每個調(diào)用函數(shù)的地址,在程序中你可以使用LoadLibrary()這個系統(tǒng)API去動態(tài)去加載某個DLL,再通過GetProcAddress()系統(tǒng)API來找到DLL導(dǎo)出的某個函數(shù)地址,得到函數(shù)地址了你才能使用這個函數(shù)。用戶DLL被加載后的基址可發(fā)生變化,導(dǎo)入的函數(shù)地址不是固定的,你不能使用固定的地址。系統(tǒng)DLL雖然基址固定,函數(shù)地址固定,但是一般不會直接使用函數(shù)硬地址,還是要GetProcAddress()這個API來得到地址,因為XP、win7等每個系統(tǒng)的這些地址是不一樣的,會導(dǎo)致兼容性問題。所以,脫殼后修復(fù)IAT并關(guān)閉ASLR。下面舉個簡單的案例。
1. 尋找OEP
這個非常簡單,就不細說了。
2.加殼程序的IAT
脫殼后如遇到程序無法正常運行(XP環(huán)境),可能是因為導(dǎo)入表破壞,需要手動修復(fù)。
通過PC文件格式的學(xué)習(xí),可以知道導(dǎo)入表的RVA在可選頭的DataDirectory數(shù)組中存放
圖為加殼程序DESCRIPTOR的偏移 18008,大小64
根據(jù)節(jié)區(qū)頭的信息定位IAT在第6個節(jié)區(qū) .aspack 中
通過節(jié)區(qū)已知的虛擬偏移與物理偏移可以計算出DESCRIPTOR在文件中的位置。
offset = A008
找到導(dǎo)出表的位置,可以知道導(dǎo)入了兩個DLL文件,可以分別計算出Name和IAT的偏移
NAME(1) = 9FC8
NAME(2) = A044
IAT(1) = 9FB8
IAT(2) = A04F
如果對PC頭不了解,可以借助PE View進行查看。
就清晰的看到加殼后的程序在啟動時導(dǎo)入的函數(shù)
3.運行時壓縮的原理
在這里插入圖片描述
可能存在疑問,為什么脫殼后需要手動修復(fù)IAT。
IAT主要用于DLL文件的重定位,IAT的引入相較于 16位dos程序 不再需要包含庫文件,而是通過表的形式進行映射。如果IAT不準確,則程序無法執(zhí)行相關(guān)庫的函數(shù)。
壓縮殼對節(jié)區(qū)進行了壓縮,把IAT修改為殼自身的IAT,在解壓縮的最后一步會還原IAT使程序可以正常運行,所以脫殼后需要進行IAT的修復(fù)。
通過OD查看運行后程序的IAT。
相較于加殼程序的IAT,運行加殼程序后真正的IAT要多的多,如果我們只進行脫殼,而不進行IAT的修復(fù)(如下圖所示)
程序的IAT是被損壞的
4 IAT修復(fù)
使用ImportREC工具,加載處于OEP的程序進程
填寫正確的IAT信息
獲取到內(nèi)存中的IAT信息,然后刪除無效函數(shù)后轉(zhuǎn)存到脫殼后程序中,程序即可正常運行。
PS:windows vista / win7 系統(tǒng)就開始使用ASLR技術(shù)防止溢出攻擊。使得每次加載程序都加載到一個隨機虛擬地址。ASLR依賴于重定位表進行定位,對于EXE程序來說,重定位是可選的,通過關(guān)閉ASLR即可解決。