版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
在介紹如何修復(fù)IAT之前,我們首先來介紹一下IAT的相關(guān)基本概念,本章的實(shí)驗(yàn)對(duì)象依然是Cruehead的CrackMe。首先我們來定位該程序的IAT位于何處,然后再來看看對(duì)其加了UPX的殼后,IAT又位于何處。什么是我們知道每個(gè)API函數(shù)在對(duì)應(yīng)的進(jìn)程空間中都有其相應(yīng)的地址,例如:我們用OD加載Cruehead的CrackMe,在命令欄中輸入大家可以看到在我的機(jī)器上,MeageBoxA這個(gè)AI函數(shù)的地址為77504E,如果大家在自己的機(jī)器上面定位到這個(gè)地址的話,可能有部分人的機(jī)器上該地址對(duì)應(yīng)的還是MeageBoxA的地址,而另外一部分人的機(jī)器上該地址對(duì)應(yīng)的就不是MeageBoxA的地址了,這取決于大家機(jī)器的操作系統(tǒng)版本,以及打補(bǔ)丁的情況。眾所周知,操作系統(tǒng)動(dòng)態(tài)庫版本的更新,其包含的I函數(shù)地址通常也會(huì)改變。比如User32我們就拿Cuehead的CackMe中的MeageoxA這個(gè)PI函數(shù)來說吧,其地址為77504E,在我的機(jī)器上運(yùn)行的很好,那些跟作系統(tǒng)版本以及e32dll版本相同的童鞋的機(jī)器上該程序運(yùn)行可能也很正常,但是如果在操作系統(tǒng)版本或者e32dll的版本跟我的不同童鞋的機(jī)器上運(yùn)行,可能就會(huì)出錯(cuò)。為了解決以上兼容問題,操作系統(tǒng)就必須提供一些措施來確保該CackMe可以在其他版本的indos操作系統(tǒng),以及LL版本下也能正常運(yùn)行。這時(shí)IAT(ImportAddressTable:輸入函數(shù)地址表)就應(yīng)運(yùn)而生大家不要覺得其名字很霸氣,就會(huì)問是不是很難?其實(shí)不然。接下來我們一起來探討一下如何在脫殼過程中定位IAT我們現(xiàn)在通過在反匯編窗口中單擊鼠標(biāo)右鍵選擇-Searchfor-Allintermodularcalls來看看主模塊中調(diào)用了哪些模塊以及API函數(shù)這里我們可以看到有幾處調(diào)用了MessageBoxA,我們在第一個(gè)MessageBoxA調(diào)用處雙擊鼠標(biāo)左鍵反匯編窗口就會(huì)馬上定位到該調(diào)用處,OD提示窗口中顯示其實(shí)際調(diào)用的是4013A處的MPER32MeageBox,這里用尖括號(hào)括起來了,說明這里是直接調(diào)用,而非間接調(diào)用。這里其實(shí)CALL40143A,顯示為CALL<JMP&USER32MessageBoxA>大家可能會(huì)覺得不太直觀。這里我們Debuggingoptions菜單項(xiàng):Disasm頁中的Showsysmbolicaddresses選項(xiàng)被勾選上了,如果我們?nèi)サ粼搶?duì)勾,將不會(huì)顯示函數(shù)地址我們可以看到右邊的注釋窗口中同樣顯示了API函數(shù)的參數(shù)以及函數(shù)名稱,比剛剛顯示符號(hào)地址看起來更直觀,一眼就可以看出CALLSearchfor-Allintermodularcalls窗口中顯示如下我們可以看到這里有三處通過CALL40143A調(diào)用MessageBoxA,我們定位到40143A處看看是什么這里我們可以看到是一個(gè)間接跳轉(zhuǎn)。JMP這里我們再次勾選上顯示符號(hào)地址的選項(xiàng),可以更加直觀的看出其調(diào)用的API函數(shù)這里有意思的地方就來了,我們看到MP4031C4031C這個(gè)內(nèi)存單元中保存的數(shù)值才是MeageBoxA真正的地址)。我們還可以看到很多類似的間接MP。這就是為了解決各操作系統(tǒng)之間的兼容問題而設(shè)計(jì)的,當(dāng)程序需要調(diào)用某API函數(shù)的時(shí)候,都是通過一個(gè)間接跳轉(zhuǎn)來調(diào)用的,讀取某個(gè)地址中保存的API函數(shù)地址,然后調(diào)用之。我們現(xiàn)在在數(shù)據(jù)窗口中定位到4031AC地址處,看看該內(nèi)存單元中存放的是什這里我們可以看到,4031C中保存的是77504E,這一片區(qū)域包含了該程序調(diào)用的所有AI函數(shù)的地址,這塊區(qū)域我們稱之為T導(dǎo)入函數(shù)地址表這里就是解決不同版本操作系統(tǒng)間調(diào)用I兼容問題的關(guān)鍵所在,該程序在不同版本操作系統(tǒng)上都是調(diào)用間接跳轉(zhuǎn)到IAT表中,在IAT中到真正的API函數(shù)地址,然后調(diào)用之,所以說只需要將不同系統(tǒng)中的API函數(shù)地址填充IAT中,這樣就可以確保不同版本系統(tǒng)調(diào)用的都是正確的API函數(shù)。有些人可能會(huì)問,4031AC這個(gè)地址在不同機(jī)器上也可能會(huì)不同的吧呵呵,這個(gè)問題提的非常好,我們一起來看看操作系統(tǒng)將正確的API函數(shù)地址填充到IAT中的具體原理,大家就會(huì)明白了這里我們4031AC中保存的內(nèi)容,單擊鼠標(biāo)右鍵選擇-Viewexecutablefile,就能看到4031AC這個(gè)虛擬地址對(duì)應(yīng)于可執(zhí)行文件我們可以看到在可執(zhí)行文件對(duì)應(yīng)文件偏移處中的內(nèi)容為60330000,當(dāng)程序運(yùn)行起來的時(shí)候,0FAC這個(gè)文件偏移對(duì)應(yīng)的虛擬地址處就會(huì)被填EA04D577,也就是說該CrackMe進(jìn)程空間中的4031AC地址處會(huì)被填入正確的API函數(shù)地址。有這么神奇indos操作系統(tǒng)當(dāng)可執(zhí)行文件被加載到進(jìn)程所在內(nèi)存空間中時(shí),會(huì)將正確的I函數(shù)地址填充到T中,這里就是4031C中被填入了MeageBoxA的地址,其他T項(xiàng)也會(huì)被填入對(duì)應(yīng)的I函數(shù)地址。其作系統(tǒng)并沒有大家想象得的那么神奇,我們看到0FAC文件偏移處的值3360,該數(shù)值其實(shí)是RVA(相對(duì)虛擬地址),其指向?qū)?yīng)的API函數(shù)名稱。這里3360加上映像基址即403360,我們定位到403360處,看看是什么這里我們可以看到指向的是MeageBoxA這個(gè)字符串,也就是說操作系統(tǒng)可以根據(jù)這個(gè)指針,定位到相應(yīng)的AI函數(shù)名稱,然后通過調(diào)用etocddes獲取對(duì)應(yīng)I函數(shù)的地址,然后將該地址填充到T中,覆蓋原來的3360,IT中被填充了正確的AI函數(shù)地址。如果我們換一臺(tái)機(jī)器,定位到4031C處可能會(huì)看到里面存放著不同的地址。JMP這樣就能夠調(diào)用MeageBoxA了,大家可能會(huì)覺得這個(gè)過程很復(fù)雜,其實(shí)填充T的過程都是操作系統(tǒng)幫我們完成的,在程序開始執(zhí)行前,T已經(jīng)被填入了正確的I函數(shù)地址。也就是說,為了確保操作系統(tǒng)將正API函數(shù)地址填充到IAT中,應(yīng)該滿足一下幾點(diǎn)要求:1:可執(zhí)行文件各IAT項(xiàng)所在的文件偏移處必須是一個(gè)指針,指向一個(gè)字符串。2:該字符串為API函數(shù)的名稱如果這兩項(xiàng)滿足,就可以確保程序在啟動(dòng)時(shí),操作系統(tǒng)會(huì)將正確的I函數(shù)地址填充到T中后面會(huì)詳細(xì)介紹操作系統(tǒng)是如何填充T的。假如,我們當(dāng)前位于被加殼程序的EP處,我們接下來可以將程序dup出來,但是在dup之前須修復(fù),為什么要修復(fù)T呢?難道殼將T破壞了嗎?對(duì),的確是這樣,殼壓根不需要原程序的,因?yàn)楸患託こ绦蚴紫葧?huì)執(zhí)行例程,T中所需要的PI的名稱指針,然后定位到PI函數(shù)地址,將其填入到T中,這個(gè)時(shí)候,T中已經(jīng)被填充了正確的PI函數(shù)地址,對(duì)應(yīng)的I函數(shù)名稱的字符串已經(jīng)不需要了,可以清除掉。大部分的殼會(huì)將PI函數(shù)名稱對(duì)應(yīng)的字符串以密文的形式保存到某個(gè)地址處,讓Cacker們不能那么容易找到它們。下面我們來看看CackMeX這個(gè)程序,在dup之前我們需要修復(fù)T。我們定位到4031AC處-原程序MessageBoxA地址的存放處是空的,那么403360指向的字符串呢也是空的,我們跟到EP處,再來看看這幾個(gè)地址處有沒有內(nèi)容,我們知道原程序在運(yùn)行之前,T必須被填充上正確的AI函數(shù)地址。JMP如果此時(shí)IAT還是空的話,那么程序運(yùn)行起來就會(huì)出錯(cuò),我們現(xiàn)在定位到OEP我們在這個(gè)JMPOEP指令處設(shè)置一個(gè)斷點(diǎn),運(yùn)行起來,接著來看看我們可以看到殼的例程已經(jīng)將正確的API函數(shù)地址填充到原程序的T中,如果這個(gè)時(shí)候程序dup出來的話,運(yùn)行會(huì)出錯(cuò),因?yàn)閐up出來的程序啟動(dòng)所必須的數(shù)據(jù)是不完整的。我們現(xiàn)在來看看各個(gè)API函數(shù)名稱,定位到403360處,會(huì)發(fā)現(xiàn)是空的現(xiàn)在我們dump出來看看,dump出來的原程序代碼肯定是正確的,但是程序仍然無法正常運(yùn)行,因?yàn)槿鄙贁?shù)據(jù),操作系統(tǒng)無法Dump的話我們需要用到一個(gè)工具,名字叫做LordPE(PS:大家應(yīng)該用的很多吧)我們運(yùn)行LordPE,定位到需要dumpCRACKMEUPX所在的進(jìn)程,當(dāng)前該進(jìn)程處于OEP處選中CRACKMEUPX所在的進(jìn)程我們單擊鼠標(biāo)右鍵選擇-activedumpengine-InliDump-Select!。接著選擇dumpfulldump出來的程序命名為dumpedexe。如果我們直接運(yùn)行dumpedexe的話會(huì)發(fā)現(xiàn)無法啟動(dòng),嘗試用OD加載dumpedexe,OD會(huì)報(bào)錯(cuò),我們來看看日志窗口中的錯(cuò)誤信息這里我們機(jī)器上提示錯(cuò)誤發(fā)現(xiàn)在7C929913地址處,我們定位到該地址(大家可以根據(jù)自己機(jī)器上顯示的錯(cuò)誤地址自行定位)這里我們可以給這一行設(shè)置一個(gè)硬件執(zhí)行斷點(diǎn)或者INT3斷點(diǎn),即當(dāng)斷在這一行時(shí)看看錯(cuò)誤發(fā)生之前是什么狀況我們運(yùn)行起來,會(huì)發(fā)現(xiàn)沒有斷在這一行,這是因?yàn)楣催x了忽略異常選項(xiàng)的緣故,這里我們?nèi)サ艉雎援惓_x項(xiàng)的對(duì)勾,重新運(yùn)行起來斷了下來,我們可以看到該錯(cuò)誤是在到達(dá)點(diǎn)之前產(chǎn)生的,所以dumpedexe無法正常運(yùn)行,我們現(xiàn)在來看看IAT的情況我們可以看到當(dāng)前雖然在我的機(jī)器上API函數(shù)的地址被填I(lǐng)AT中,但是想要正常運(yùn)行在其他機(jī)器上的話,必須要指向各個(gè)API函數(shù)名稱字符串的指針,這樣才是確保操作系統(tǒng)能夠通過GetProcAddress獲取到正確的API函數(shù)地址并填充到IAT中。這里該dumpedexe缺少這些指向API函數(shù)名稱字符串的指針,所以運(yùn)行的時(shí)候會(huì)發(fā)生錯(cuò)誤。這里大家不要嘗試先dump出來,然后再恢復(fù)各個(gè)API函數(shù)的名稱字符串以及其指針,如果這樣手工修復(fù)的話,是一件極其的工作,你需要將4031AC地址處的內(nèi)容修改為MessageBoxA這個(gè)字符串的指針,IAT中的其他項(xiàng)也要進(jìn)行相應(yīng)的處理。比較明智的做法是,dump出來之前就將IAT修復(fù)了我們知道dump出來的代碼肯定是正確的,我們定位到401000處看一看我們看到API函數(shù)的調(diào)用處,40135C地址處應(yīng)該是調(diào)用的MessageBoxA我們定位到40143A處,這里依然是通過一個(gè)間接跳轉(zhuǎn)這些間接跳轉(zhuǎn)是無法正常運(yùn)行的因?yàn)樵谡G闆r,操作系統(tǒng)必須知道指向各個(gè)API函數(shù)名稱字符串的指針,然后通過GetProcAddress定位到各個(gè)API函數(shù)正確的地址并填充到IAT中,這樣這些間接跳轉(zhuǎn)才能起作用。下面我們來看看未加殼程序的IAT。我們用OD加載CrueheadCrackMe我們來定位該CrackMePE結(jié)構(gòu)中一些重要字段。首先在數(shù)據(jù)窗口中定位400000地址處單擊鼠標(biāo)右鍵選擇-Special-PEheader切換到PE頭的顯示模往下拉我們可以看到PE頭的偏移為100PE頭位于400100地址處繼續(xù)往下拉,我們可以看到IT(導(dǎo)入表)的指針,這里大家不要將其跟IAT搞了IT=IAT=輸入函數(shù)地址我們知道當(dāng)程序啟動(dòng)之前操作系統(tǒng)會(huì)將API函數(shù)的地址填充到IAT中,那么IT(導(dǎo)入表)又是怎么一回事呢?首先我們定位到導(dǎo)入表,該導(dǎo)入表偏移值為3000(即虛擬地址為403000),長度為670(十六進(jìn)制),403670為導(dǎo)入表的結(jié)尾。我們一起來看一看。這就是導(dǎo)入表了,我們來介紹一下導(dǎo)入表的結(jié)構(gòu)吧我們選中的這20個(gè)字節(jié)是導(dǎo)入表的描述符結(jié)構(gòu)。的叫法為IMAGE_IMPORT_DESCRIPTOR。每組為20個(gè)字節(jié),IMAGE_IMPORT_DESCRIPTOR包含了一個(gè)的字符串指針,該指針指向了某個(gè)的動(dòng)態(tài)庫名稱字符串。我們來看個(gè)例子這里IMAGE_IMPORT_DESCRIPTOR簡稱為IID。這里選中的部分為導(dǎo)入表中的第一個(gè)IID。其中5個(gè)DWORD字段的 時(shí)間 鏈表的前一個(gè)結(jié) 指向DLL名稱的指itThunk 指向的鏈表定義了針對(duì)ae1這個(gè)動(dòng)態(tài)庫引入的所有導(dǎo)入函數(shù)前三個(gè)字段不是很重要,對(duì)于我們Cacker來說,我們只對(duì)第4,5字段感。正如大家所看到的,第4個(gè)字段為指向DLL名稱字符串的指針,我們來看看403290處是哪個(gè)DLL的名稱這里我們可以看到是USER32DLL,5個(gè)字段指向了USER32DLL對(duì)應(yīng)IAT項(xiàng)的起始地址,403184這里就是IAT了,導(dǎo)入表的結(jié)束地址為403670。導(dǎo)入表中的每個(gè)IID項(xiàng)指明了DLL的名稱以及其對(duì)應(yīng)IAT項(xiàng)的起始地址。緊湊大量實(shí)驗(yàn)表明,T并不一定位于在導(dǎo)入表中。T可以位于程序中任何具有寫權(quán)限的地方,只要當(dāng)可執(zhí)行程序運(yùn)行起來時(shí),操作系統(tǒng)可以定位到這些ID項(xiàng),然后根據(jù)T中標(biāo)明的I函數(shù)名稱獲取到函數(shù)地址即可。下面我們來總結(jié)一下操作系統(tǒng)填充T的具體步驟:1:定位導(dǎo)入2:解析第一個(gè)IID項(xiàng),根據(jù)IID中的第4個(gè)字段定位DLL的名3:根據(jù)IID項(xiàng)的第5個(gè)字段DLL對(duì)應(yīng)的IAT項(xiàng)的起始地4:根據(jù)IAT中的指針定位到相應(yīng)API函數(shù)名稱字符5:通過GetProcAddress獲取API函數(shù)的地址并填充到IAT6:當(dāng)定位到的IAT項(xiàng)為零的時(shí)候表示該DLL的API函數(shù)地址獲取完畢了,接著繼續(xù)解析第二個(gè)IID,重復(fù)上面的步驟。定位導(dǎo)入定位到導(dǎo)入表的起始根據(jù)第一個(gè)IID項(xiàng)中的第段得到DLL名稱字符串的指針,這里指向的是USER32根據(jù)第五個(gè)字段的內(nèi)容定位到IAT項(xiàng)的起始地址,這里是403184,我們定位到該地址處這里我們可以看到已經(jīng)被填充了正確的AI函數(shù)的地址,跟我們dup出來的結(jié)果一樣,我們再來看看相應(yīng)的可執(zhí)行文件偏移處的內(nèi)容是什么。這里我們可以看到第一個(gè)API函數(shù)的名稱位于4032CC地址處,我們定位到該地址處第一個(gè)API函數(shù)是KillTimer,我們在OD中看到的KillTimer的地址是操作系統(tǒng)調(diào)用GetProcAddress獲取到的這里我們可以看到KillTimer的地址為77D18C42。該地址將被填充到IAT相應(yīng)單元中去覆蓋原來的值這里是IAT中的第一元我們再來看下一個(gè)元素,向后偏移4就是,來看一看該API函數(shù)名稱字符串的指針是多少定位到可執(zhí)行文件的相應(yīng)偏移
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度房屋買賣合同范本:成交價(jià)格及支付方式2篇
- 二零二五年度城市排水管道安裝與疏通合同3篇
- 二零二五年度個(gè)人婚前財(cái)產(chǎn)保護(hù)與離婚分配協(xié)議2篇
- 科學(xué)技術(shù)教學(xué)課件
- 2025年冀教新版九年級(jí)物理下冊階段測試試卷含答案
- 2025年魯教五四新版九年級(jí)科學(xué)上冊階段測試試卷
- 2025年統(tǒng)編版七年級(jí)數(shù)學(xué)上冊階段測試試卷
- 二零二五年度化工產(chǎn)品采購與供應(yīng)合同2篇
- 2025年人教版(2024)共同必修2物理上冊月考試卷
- 二零二五年度合伙購置商業(yè)地產(chǎn)協(xié)議3篇
- 妊娠期高血糖診治指南
- 2024壓鑄機(jī)安全技術(shù)規(guī)范
- 綿陽小升初數(shù)學(xué)試題-(綿中英才學(xué)校)
- 數(shù)據(jù)中心數(shù)據(jù)中心建設(shè)項(xiàng)目電氣工程設(shè)計(jì)方案
- 廣東省深圳市2022年中考英語真題(含答案)
- 四川省瀘州市(2024年-2025年小學(xué)四年級(jí)語文)統(tǒng)編版期末考試(上學(xué)期)試卷及答案
- 4 地表流水的力量 (教學(xué)設(shè)計(jì))-2023-2024學(xué)年 六年級(jí)下冊科學(xué)人教版
- 臨床彌漫性特發(fā)性骨肥厚癥(DISH)影像表現(xiàn)
- 【會(huì)議系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)7300字(論文)】
- 中國慢性冠脈綜合征患者診斷及管理指南2024版解讀
- 2023三常規(guī)學(xué)校管理心得體會(huì)3篇
評(píng)論
0/150
提交評(píng)論