使用ollydbg從0開始crack版4258第四十二章ACProtectV1 09脫殼尋找_第1頁(yè)
使用ollydbg從0開始crack版4258第四十二章ACProtectV1 09脫殼尋找_第2頁(yè)
使用ollydbg從0開始crack版4258第四十二章ACProtectV1 09脫殼尋找_第3頁(yè)
使用ollydbg從0開始crack版4258第四十二章ACProtectV1 09脫殼尋找_第4頁(yè)
使用ollydbg從0開始crack版4258第四十二章ACProtectV1 09脫殼尋找_第5頁(yè)
已閱讀5頁(yè),還剩380頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第四十二章-ACProtectV1.09脫殼(尋找OEP,繞過(guò)硬件斷點(diǎn)檢測(cè),修復(fù)Stolen本章開始,討論更加復(fù)雜的殼-ACProtect1.09。我們直接運(yùn)行起來(lái),. 斷了下來(lái),在寄存器窗口中,單擊鼠標(biāo)右鍵選擇Viewdebugregisters,切換到調(diào)試寄存器顯示模式,如果沒(méi)有該選項(xiàng)的話,說(shuō)明當(dāng)前已經(jīng)是調(diào)試寄存這些就是調(diào)試寄存器組,Dr0~Dr7。Dr0,Dr1,Dr2,Dr3是用于設(shè)置硬件斷點(diǎn)的,由于只有4個(gè)硬件斷點(diǎn)寄存器,所以同時(shí)最多只能設(shè)式,Dr6是用于顯示哪個(gè)硬件調(diào)試寄存器的斷點(diǎn),如果是Dr0~Dr3的話,相應(yīng)位會(huì)被置1。即如果是Dr0的斷點(diǎn),則Dr6的第0位被置1,如果是Dr1的斷點(diǎn),則Dr6的第1位被置1,依次類推。因?yàn)橛布帱c(diǎn)同時(shí)只會(huì)觸發(fā)一個(gè),所以Dr6的低4位最多只有一位被置1,所LE和GE:P6family和之后的IA32處理器都不支持這兩位。當(dāng)設(shè)置時(shí),使得處理器會(huì)檢測(cè)觸發(fā)數(shù)據(jù)斷點(diǎn)的精確的指令。當(dāng)其中一個(gè)個(gè)。切換任務(wù)時(shí)LE會(huì)被清除而GE不會(huì)被清除。為了兼容性,In建議使用精確斷點(diǎn)時(shí)把LE和GE都設(shè)置為1。示1字節(jié)),否則會(huì)產(chǎn)生不確定的行為。LEN0到LEN3(1)001(2)012(3)10保留(4)114R/W0到R/W3:指定各個(gè)斷點(diǎn)的觸發(fā)條件。它們對(duì)應(yīng)于DR0到DR3中的地址以及DR6中的400只執(zhí)行01寫入數(shù)據(jù)斷點(diǎn)10I/O端口斷點(diǎn)(只用于pentium+,需設(shè)置CR4的DE位,DE是CR4的第3位11讀或?qū)憯?shù)據(jù)斷點(diǎn)GD位:用于保護(hù)DRx,如果GD位為1,則對(duì)Drx的任何都會(huì)導(dǎo)致進(jìn)入1號(hào)調(diào)試陷阱(int1)。即IDT的對(duì)應(yīng),這樣可以保證調(diào)試此時(shí)Dr0為4271B5,表示4271B5地址處被設(shè)置了硬件斷點(diǎn)。現(xiàn)在我們來(lái)看看CONTEXT恢復(fù)。第二種方案:在context中定位到程序的返回地址,在返回地址處設(shè)置一個(gè)斷點(diǎn),當(dāng)斷在返回地址處時(shí)恢復(fù)硬件斷點(diǎn),相當(dāng)于重新設(shè)12FC8C+0B8=最后再次取內(nèi)容就得到了異常的返回地址,好了,下面我們來(lái)看看執(zhí)行的效果,重啟程序。,,

有些殼會(huì)通過(guò)一些方法來(lái)清除硬件斷點(diǎn),現(xiàn)在我們就可以很完美的給stolenbytes設(shè)置硬件斷點(diǎn)了。首先我們來(lái)看看有沒(méi)有異常,我們從最后一次異常處開始。禁用 中用到的斷點(diǎn)現(xiàn)在我們重新啟動(dòng),斷在了最后一次異常處,給當(dāng)前區(qū)段設(shè)置內(nèi)存斷點(diǎn),讓其斷在異常處理程序中按ShiftF9現(xiàn)在我們就可以從471090處開始了,不一會(huì)兒完畢了,我們現(xiàn)在到達(dá)了OEP處。這里的指令的最后幾行,這里我們可以搜索PUSHEBP,一般是從上往下搜索,但這里前面位于系統(tǒng)DLL中的PUSHEBP過(guò)多,所以 了,這里我們就找到了stolenbytes,關(guān)于前面的通過(guò)設(shè)置硬件斷點(diǎn)的技巧在下一章節(jié)中使用。本章附件第四十三章-ACProtectV1.09(編寫修復(fù) 下面我們來(lái)隨便定位一個(gè)API函數(shù)的調(diào)用處,單擊鼠標(biāo)右鍵選擇SearchforAllintermodularcalls這里我們可以看到很多經(jīng)過(guò)重定向的項(xiàng),這些項(xiàng)直接就位于殼的區(qū)段中, 首先定位OEP的備份一下備份過(guò)的重命名為OEP.txt,接下來(lái)我們通過(guò)修改HBP.txt來(lái)定位修復(fù)IAT的關(guān)鍵跳轉(zhuǎn)。執(zhí)行上面的,不一會(huì)兒彈出了是否繼續(xù)執(zhí)行的消息框異或得到的結(jié)果就是API函數(shù)的地址,我們一起來(lái)計(jì)算一下。5BF11A9XOR793E0502=。 。址被保存在了堆棧中,確切點(diǎn)來(lái)說(shuō)是[ESP-0C]中。我們可以看到對(duì)于正常的IAT項(xiàng),[EBP-0C]處并不會(huì)保存正確的API函數(shù) 我們?cè)撛趺醋瞿?我們需要對(duì)寫入IAT項(xiàng)的指令設(shè)置硬件執(zhí)行斷點(diǎn),當(dāng)執(zhí)行到這里的時(shí)候,我們判斷EAX的值是正常的還是重定向 變量aux2來(lái)保存正確的API函數(shù)地址,正確的API函數(shù)地址保存在[ESP-0C]中。其寫入到EDI指向的IAT項(xiàng)中即可。下面我們就來(lái)執(zhí)行一下該,試試效果運(yùn)行 IAT=本章附件第四十四章-ACProtectV1.09脫殼(修復(fù)我們上一章節(jié)介紹了如何定位stolenbytes,以及IAT的修復(fù)。我們利用上一章編寫的可以很方便的修復(fù)IAT并且定位到OEP,接下接下來(lái)打開ImportReconstructor,定位到該程序所在進(jìn)程。OEP=271B5IAT的起始地址(RVA)IAT=460F28460818點(diǎn)擊GetImports我們會(huì)發(fā)現(xiàn)有一項(xiàng)是無(wú)效的,其他項(xiàng)都是有效的, 942C0892xor斷在了這里,另一種更加快捷的方法就是通過(guò)OD的自動(dòng)功能來(lái)定位,我們?cè)O(shè)置自動(dòng)的終止條件為EIP大于500000,也就是說(shuō)從當(dāng)前區(qū)段轉(zhuǎn)這里我們選中EIPisoutsidetherange。范圍設(shè)置為0~500000 等數(shù)據(jù)都填入到IMPREC停在了OEP處,我們準(zhǔn)備好stolenbytes 們從4271b0地址處開始寫入stolenbytes。OD加載剛剛保存的文件,我們可以通過(guò)在數(shù)據(jù)窗口中單擊鼠標(biāo)右鍵選擇-Goto-Expression,輸入400000定位到PE頭。好了,現(xiàn)在我們就修復(fù)完畢了,但是我們運(yùn)行修復(fù)后的程序會(huì)發(fā)現(xiàn)無(wú)法正常運(yùn)行,程序了。好,那么我們不勾選忽略異常的選項(xiàng),加載剛我們可以看到日志窗口中顯示了一 異常。我們通過(guò)單擊中的K按鈕查看調(diào)用堆棧我們到了這里,這里我的想法是用這6個(gè)字節(jié)替換掉那跳轉(zhuǎn)表中的6B這里將所有的代碼都以二進(jìn)制的形式拷貝出來(lái),接著保存所做的修改到文件,本章附件cmpjmpfinal//當(dāng)斷在硬件斷點(diǎn)處時(shí),就跳轉(zhuǎn)到finalto_clear:bphwc13ffc4to_recover:MSGYN是否繼續(xù)jebeginning//此時(shí)OD斷在硬件斷點(diǎn)處以搞定,但是我們整個(gè)的是OllyDbg,所以這里我們還是用OllyDbg來(lái)進(jìn)行調(diào)試,嘿嘿。->斷在了系統(tǒng)斷點(diǎn)處, 5這款OD吧,前面章節(jié)我們介紹過(guò),這款OD是打過(guò)補(bǔ)丁的,其內(nèi)存斷點(diǎn)僅僅在執(zhí)行代碼的時(shí)候才會(huì)斷下來(lái),或者寫入并不會(huì)斷 我們?cè)跀?shù)據(jù)窗口中單擊鼠標(biāo)右鍵選擇Goto-Expression,輸入400000(主模塊址)。 接下來(lái)我們?cè)谶x中該字段,單擊鼠標(biāo)右鍵選擇Copytoexecutablefile 很明顯有什么地方我們沒(méi)有繞過(guò)。提示正在一個(gè)不存在的區(qū)段地址,OD無(wú)法繼續(xù)運(yùn)行。好了,下面我就來(lái)給大家介紹一些思路,這里并不是每一種思路都能奏效,但是你需要熟悉這些思路,試:(PS:這個(gè)功能大家應(yīng)該不會(huì)陌生吧)當(dāng)有程序的時(shí)候,OD就會(huì)自動(dòng)附加上該程序。擊Restoreoldjust-in-timedebugger(恢復(fù)原來(lái)的即時(shí)調(diào)試器)按鈕。因?yàn)槊慨?dāng)應(yīng)用程序,就被OD附加上是很煩的。這里我們勾選上PEEditor以及Break&Enter分組中的Register 首先我們對(duì)這個(gè)程序具體情況一無(wú)所知。那我們就考慮一下常規(guī)情況的吧一般來(lái)說(shuō)針對(duì)于該程序大部分殼會(huì)從0地址處開始區(qū)段。我們可以嘗試修改某些區(qū)段的權(quán)限比如說(shuō)我們?nèi)サ裟硞€(gè)區(qū)段的可寫權(quán)限。當(dāng)殼嘗試寫入該區(qū)段的話就會(huì)報(bào)錯(cuò)此時(shí)我們之前設(shè)置dt這個(gè)區(qū)段中也就是緊隨其后的一個(gè)區(qū)段所以這里我們首先嘗試t這個(gè)單擊右上方的takeit(確定)按鈕。這里我們可以看到.rdata這個(gè)區(qū)段的權(quán)限已經(jīng)修改成功了。有可能殼的作者會(huì)在運(yùn)行時(shí)調(diào)用VirutalProtect之類的API函數(shù)將各個(gè)區(qū)段的權(quán)限修改回去。沒(méi)有關(guān)系,我們還是來(lái)看看先。,MssBx.rt,。我以掉段的寫當(dāng)?shù)綍r(shí)序生常即調(diào)器O就自加。鍵選擇Fullaccess,給該區(qū)段賦予所有權(quán)限。該指令成功執(zhí)行情形 0x402000,也就是說(shuō)我們修改的是虛擬地址范圍為0x402000~0x403000對(duì)應(yīng)的區(qū)段的屬性,嘿嘿。這里我們不要盲目的對(duì)OD中顯示的唯一的那一個(gè)區(qū)段設(shè)置內(nèi)存斷點(diǎn),OD這里對(duì)區(qū)段的解析是有誤的。這里我們?cè)跀?shù)據(jù)窗口中定 下面我們來(lái)定位IMPREC重建IAT所需要的數(shù)據(jù)。 IAT大小:0x1C路,劍走偏鋒往往能收到,嘿嘿。本章附件IMP第四十五章-ReCryptv0.80脫殼(續(xù)本章我們需要用到幾款工具,信息收集這些字段非常重要,因?yàn)楹芏鄽ぴ趨^(qū)段的過(guò)程中會(huì)修改這些字段。我們可以看到這里NumOfRvaAndSizes字段就被修改過(guò)了。 我們可以看到這3下面我們需要用到POKEMON這款工具,通過(guò)這款工具我們可以繞過(guò)該殼的AntiAttach(反附加),我們還記得恢復(fù)的那個(gè)偏移0xB4處 本章附件IMPREC.7zPatched5OD.7z ,這里我們打開O還記得之前介紹那款修改過(guò)的Pched4這款吧就它了配置好反反調(diào)試插件。這個(gè)Cck作者的要求不僅僅是脫殼還必須將D剝離讓EE單獨(dú)正常運(yùn)行。Pick序 的這是一個(gè)LL如果將這個(gè)L刪除掉的主程序?qū)o(wú)法正常運(yùn)行。好了現(xiàn)在我們用Pc這款D加載Px。 開主菜單中的Debuggingoptions-Events,選中Systembreakpoint。 這里我們可以看到ImportTable(縮寫:IT,俗稱:導(dǎo)入表)的RVA(相對(duì)虛擬地址)(PS:不要將ImportTable與IAT搞了,IAT是ImportAddressTable(輸入函數(shù)地址表)的縮寫,嘿嘿).這里6F3C+映像址(400000)就可以定位到ImportTable了不道家是還記得入表的式L占W。SE結(jié)不解的童鞋可以參看中的小黃書你懂得!嘿sPE指南)L4WL的名稱字符串40712E這個(gè)地址就指向了第一個(gè)LL我們一起來(lái)看一看。這我可以到第一個(gè)L我們假設(shè)在到達(dá)點(diǎn)之如果該LL被執(zhí)行了的話就終止。PS統(tǒng)D并不會(huì)進(jìn)行反調(diào)試的處理這里只是舉個(gè)例子) 我看斷了來(lái)這是由于76B08B8地處內(nèi)容導(dǎo)致的中。我們繼續(xù)運(yùn)行直到觸發(fā)內(nèi)存執(zhí)行斷點(diǎn)為止。LL的流程就是這樣的接下來(lái)我們重啟這次我們直接對(duì)的代碼段設(shè)置內(nèi)存斷點(diǎn)。也是不是檢測(cè)窗口名i它是檢測(cè)該進(jìn)程是由誰(shuí)創(chuàng)建的通過(guò)調(diào)用sN等函數(shù)來(lái)遍歷進(jìn)程判斷當(dāng)前進(jìn)程的父進(jìn)程是否為桌面進(jìn)程來(lái)達(dá)到反調(diào)試的目的。kee如果是的話那么就說(shuō)明正在被調(diào)試直接終止進(jìn)程。進(jìn)程父進(jìn)程零代表是mPcss這個(gè)進(jìn)程這個(gè)進(jìn)程并不是我們要定位的我們直接運(yùn)行起來(lái)。,程序終止了。怎么這樣就終止了呢道SysmPss這系統(tǒng)進(jìn)程有問(wèn)題不太可能,那么會(huì)不會(huì)i插件了的原因呢?我們?nèi)サ鬑iD中PcssNxt這一項(xiàng)的對(duì)勾試試。is2x這個(gè)選項(xiàng)的話當(dāng)該函數(shù)執(zhí)行完畢EA說(shuō)明出錯(cuò)了就直接退出了。這里我們不勾選這一項(xiàng)EA非零。函數(shù)執(zhí)行成功這樣程序就不會(huì)直接退出了。為我用粉紅色標(biāo)注出來(lái)了。為我用綠色標(biāo)注出來(lái)了。這里我們可以看到此時(shí)定位到了Picke這個(gè)進(jìn)程。P0x0AE4P0x8A這里我們對(duì)比著PE里面的進(jìn)程信息來(lái)看。我們單擊PUE中的Aciz刷新按鈕。Picke的父進(jìn)程并非l而是。所以Pticke會(huì)直接退出。這里我們直接對(duì)0x8A這,看什么地方會(huì)獲取該P(yáng)PD。EiPces其反試如果處修改并存文件話那如果其他其反調(diào)試話程序還是無(wú)法正常運(yùn)行。所以這里我們不進(jìn)行修改我們刪除掉之前設(shè)置的硬件斷點(diǎn)。給進(jìn)行比較的這一行指令設(shè)置硬件執(zhí)行斷點(diǎn)。當(dāng)程序斷在這里的時(shí)候,我們可以手動(dòng)修改PickeP,lreP更加方便的方法是斷在這一行的時(shí)候修改EA的值。ke0x7即用于判斷是不是重命名過(guò)的。 計(jì)數(shù),所在進(jìn)程范圍內(nèi)模塊計(jì)數(shù),模塊 這里我們可以看到關(guān)于模塊的相關(guān)信息,我們來(lái)一起看看通過(guò)該CrackMe 鍵執(zhí)行這個(gè)字符串比較函數(shù)。 EAX返回1,擇Followimmediateconstant(跟隨立即數(shù))。這這我再定位了實(shí)際碼處通過(guò)這方式就以不行的代碼接位實(shí)代碼了比方便。我們繼續(xù)。我們繼續(xù)耐心跟吧。EPLEEE其余的比較都不相等。這里我們直接按850LasErPSLasEo得到的值)的返回值為ERRRUCSS,也就是創(chuàng)建互斥體成功。接下來(lái)調(diào)用lLasWiE這個(gè)函數(shù)獲取AP函數(shù)執(zhí)行的錯(cuò)誤碼,這里我們可以對(duì)照著來(lái)看。這里EA的值為,也就是D中顯示的sE的值。這里我們可以看到這個(gè)WAIT互斥體是第一次創(chuàng)建,所以跳過(guò)了ExitProcess,如果WAIT不是第一次創(chuàng)建的話,那么就會(huì)調(diào) 這里如果我們按F8鍵創(chuàng)建該進(jìn)程的話,就算被創(chuàng)建了,該進(jìn)程也會(huì)立即結(jié)束掉,所以這里我們可以嘗試將進(jìn)程掛起,我們可以通過(guò) 我直接PsA件斷點(diǎn)來(lái)看為么創(chuàng)進(jìn)程失。也就說(shuō)此有兩個(gè)件斷點(diǎn),一個(gè)是父進(jìn)程與e進(jìn)行比較處另一個(gè)就是該CPcssA的調(diào)用處。現(xiàn)在我們?cè)賹的反反調(diào)試選項(xiàng)都勾選上。我們用PUPE查看一下進(jìn)程。 我可通過(guò)下方式重其在系斷點(diǎn)處我們i這模塊代碼段置內(nèi)存斷點(diǎn)我們運(yùn)行起來(lái)會(huì)斷在該D的點(diǎn)處。79111A4ALL往Aillll的 當(dāng)前程的領(lǐng)空屬于TLLLL,也就是當(dāng)新創(chuàng)建的進(jìn)程由掛起狀態(tài)恢復(fù)為運(yùn)行狀態(tài)后,就會(huì)運(yùn)行到該CA處我們要想辦法讓其在這里一直循環(huán)而不進(jìn)去。這里父進(jìn)程P修改leP,繼運(yùn)行隨即就斷在了CPcssA的調(diào)用處。7911A4S注意你本機(jī)的地址單擊獲取原始字節(jié)接著填寫上要替換的字節(jié)碼EBE擊按鈕。這樣就完畢了。現(xiàn)在我們需要將該進(jìn)程由掛起狀態(tài)恢復(fù)到運(yùn)行狀態(tài)。 這樣掛起的線程就被恢復(fù)了,并且一直在79111A4接下來(lái)我們來(lái)附加該進(jìn)程。接來(lái)設(shè)為即調(diào)試器我選新建的Pckxe標(biāo)擇調(diào)。這樣D的時(shí)調(diào)試功能就生效了。此時(shí)并沒(méi)有模塊列表中并沒(méi)有出現(xiàn)Aill這個(gè)模塊我們會(huì)斷在79111A4如果還是沒(méi)有出現(xiàn)Aill我繼續(xù)運(yùn)行直到ADDll這個(gè)模塊為止。如果為0xB7的話表示互斥體已經(jīng)存在,該進(jìn)程是并非第一次創(chuàng)建,如果不為0xB7的話,的INT3斷點(diǎn),運(yùn)行起來(lái),這樣就可以斷在AntiDebugDll.dll的點(diǎn)處了。 斷在了這里這里由于父進(jìn)程已經(jīng)創(chuàng)建了所以我們?nèi)绻麍?zhí)行了該函數(shù)Ls的錯(cuò)誤碼將返回即。這里我們執(zhí)行到返回驗(yàn)證一下。斷在了這里,這里是該錯(cuò)誤碼進(jìn)行比較。 IAT設(shè)置內(nèi)存斷點(diǎn)。 叫做第一個(gè)實(shí)例。這里要?jiǎng)?chuàng)建的互斥體叫做。顧名思義主體實(shí)例。TLLLLPssTLLLL的函數(shù)指針。iBin我們繼續(xù)運(yùn)行。 而是調(diào)用A來(lái)打開這個(gè)互斥體這里可以順利獲取到之前父進(jìn)程中創(chuàng)建的互斥體的句柄。我們繼續(xù)F9鍵運(yùn)行。里iFc的第二參數(shù)由0x1388修為了FFFFF1,。這里為了讓父進(jìn)程釋放號(hào)量的時(shí)候我們能夠子進(jìn)程能夠順利斷下我們給下一條指令處設(shè)置一個(gè)斷點(diǎn)。 量,子進(jìn)程就會(huì)調(diào)用ExitProcess退出了。所以超時(shí)時(shí)間修改為了FFFFFFFF(即INFINITE),那么子進(jìn)程只能的一直等們將之前設(shè)置的INT3都刪除掉。下面我們就不設(shè)置INT3斷點(diǎn)了,如果實(shí)在需要設(shè)置斷點(diǎn),我們就用內(nèi)存斷點(diǎn)替代。這明這個(gè)序想通過(guò)lA然通過(guò)ile相字節(jié)碼進(jìn)行比較看看是否被修改這里我們并沒(méi)有修改文件中的內(nèi)容我們修改的都是內(nèi)存中的內(nèi)容。這里大部分參數(shù)我們都不是很關(guān)系,我們只需要注意一下dwShareMode這個(gè)參數(shù),共享模式為FILE_SHARE_READ,我們來(lái)看 起始地址為9F0000,接著它將會(huì)怎么做呢?不它沒(méi)有只比較了起始的幾個(gè)字節(jié)。我們?cè)跀?shù)據(jù)窗口中定位到9地址處。而們前正運(yùn)行的的為 我們?cè)贁?shù)據(jù)窗口中定位到該地址我們可以看到兩者的內(nèi)容是一的。 修改FLESA_A讓開文件功接下會(huì)件后對(duì)到的文件內(nèi)容進(jìn)行應(yīng)的處理我們來(lái)看看對(duì)文件內(nèi)容處理以后后續(xù)流程會(huì)有什么影響。 入整個(gè)代碼段,貌似像是在區(qū)段的樣子。繼續(xù)。現(xiàn)在子進(jìn)程調(diào)用互斥體的信號(hào)量信號(hào)量的等待我們繼續(xù)子進(jìn)程繼續(xù)按鍵運(yùn)行。這又是跟父進(jìn)程一樣調(diào)用修改內(nèi)存權(quán)限為下一調(diào)用PsyWcs讀寫內(nèi)存做鋪墊。PiEP155我們現(xiàn)在來(lái)看看40155看到的確像是點(diǎn)的樣子說(shuō)明之前循環(huán)寫入的確是在主程序代碼段。 現(xiàn)在我們就不需要執(zhí)行AntiDebugDll.dll這個(gè)反調(diào)試模塊中的內(nèi)容了,所以我們可以直接將AntiDebugDll.dll 點(diǎn)處的指令修 。為第二個(gè)L這里我們?yōu)榱颂蕹粑覀兛梢詫⒌腄項(xiàng)修改得與這一個(gè)D項(xiàng)一致。嘿嘿,這個(gè)CrackMe四十八章-PeSpinV1.3.04脫殼-我們可以看到量調(diào)用處顯示了API函數(shù)名稱,我們隨便選擇一個(gè) 的OEP處時(shí),此時(shí)的棧頂指針也應(yīng)該是指向的12FFC4。我們知道通過(guò)情況下OEP處的第一個(gè)指令為PUSHEBP,執(zhí)行了這條指令斷在了這里,這里有條PUSHEBP指令,有點(diǎn)像OEP處的指令,嘿嘿,我們繼續(xù)往下單步,驗(yàn)證一下看看到底是不是OEP處的指令,對(duì)于無(wú)JMP指令我們并不會(huì)感,因?yàn)槠洳⒉挥绊懠拇嫫鹘M以及堆棧的狀態(tài)。 這里又是一條語(yǔ)句,繼續(xù)本章附件第四十九章-PeSpinV1.3.04脫殼- 大細(xì)觀的話會(huì)現(xiàn)我淺色注來(lái)這指令面創(chuàng)的段已執(zhí)過(guò)了不得話以減鍵往回)這做目很能防止者過(guò)在P的 點(diǎn)設(shè)斷以來(lái)斷不被定到該數(shù)這果們知該P(yáng)函是么話在中VEX,ODPRSS:P+]條令鼠右選擇wiine將EP指針向指。(P:實(shí)需這做,可直將編口內(nèi)地與器中的一線右拖,以看為了增們修復(fù)IAT的難度。我們?cè)撊绾蝸?lái)修復(fù)IAT呢? 寄存器中會(huì)出現(xiàn)7C9110ED這個(gè)值,我們利用OD的自動(dòng)功能來(lái)定位這個(gè)值。我們來(lái)設(shè)置一個(gè)自動(dòng)的條件作指令的話耗費(fèi)的時(shí)間可能會(huì)非常長(zhǎng),接下來(lái)我們選中Debug-Traceinto菜單項(xiàng)開始自動(dòng)。我們?cè)俅芜x擇Debug-traceinto菜單項(xiàng)進(jìn)行自動(dòng)點(diǎn)。接著給MOVDWORDPTRSS:[ESP+1C],ESI這一條指令處設(shè)置硬件執(zhí)行斷點(diǎn)。所以我們來(lái) 指令相當(dāng)于是費(fèi)的,其NOP掉。如下 項(xiàng)轉(zhuǎn)化為CALLIAT中的項(xiàng),下面我們就通過(guò)一個(gè)簡(jiǎn)單的來(lái)完成。首先varvar_callvarvar_tablevarvar_apivarvar_iatvarvar_programvarvar_endmovmovfindopvar_program,#FF15??#log$RESULT這里才是我們真正開始執(zhí)行的地方。TheStart是一個(gè),顧名思義:開始。接下來(lái)是通過(guò)findop命令從401000地址處開始查命令將movvar_call,$RESULTcmpvar_call,0jecmpvar_call,44904BjaeTheFinal接CALL,那么就直接跳轉(zhuǎn)到TheFinal處結(jié)束該的執(zhí)行,如果找到了,判斷間接CALL指令的地址是否高于代碼段中最后一項(xiàng)間addvar_call,2logvar_callmovvar_table,[var_call]logvar_tablemovvar_api,[table]logvar_apicmpvar_api,jbTheJmp這里將間接CALL指令的地址+2,然后4字節(jié)的內(nèi)容保存到變量var_table中,也就是IAT2中的表項(xiàng),接著表項(xiàng)的值也就是讀 cmpvar_api,[var_iat]jeTheSolveaddcmpvar_iat,460F28jaeTheJmpjmp logvar_iatlogmovmov不做,所以我們不得不添加一個(gè)STL命令,讓其單步執(zhí)行,相當(dāng)于F7,然后再將eip指向的OEP處。好了,現(xiàn)在我們來(lái)dump,然后用IMPREC修復(fù)IAT們單擊鼠標(biāo)右鍵選擇Searchfor-Allintermodularcalls。查看所有的API函數(shù)的調(diào)用處。但愿不需要我們編寫第二個(gè)來(lái)進(jìn)行修復(fù) 了VirtualProtect這個(gè)函數(shù)的地址。接著調(diào)用VirtualProtect給PE頭賦予寫入權(quán)限。該函數(shù)的參數(shù)如下:存單元中。接著將起始地址為45CAB0,長(zhǎng)度為的數(shù)據(jù)拷貝到起始地址為,長(zhǎng)度為1000的內(nèi)存單元(也就是PE頭)本章附件 段所在區(qū)域設(shè)置內(nèi)存斷點(diǎn)來(lái)定位OEP了,但是有了OllyAdvanced這個(gè)插件,這一切都可以省略了,嘿嘿。 這里我們可以看到BPOutputDebugStringA這個(gè)按鈕就出現(xiàn)了,我們只需要單擊一下BPOutputDebugStringA這個(gè)按鈕,就可以 說(shuō)吾愛的OD)重啟OD,接著在命令欄中輸入HEOutputDebugStringA給該API函數(shù)設(shè)置一個(gè)硬件執(zhí)行斷點(diǎn)試試看。我們可以看到量的API函數(shù)調(diào)用,IAT如下 我們打開IMPREC本章附件新版(PS:作者當(dāng)年的版)。本章就由我解決簡(jiǎn)單的部分,大家來(lái)完成復(fù)雜的部分,嘿嘿,給大家充分練手的機(jī)會(huì)。注意一點(diǎn),如果OD加載目標(biāo)程序以后,到達(dá)OEP之前就由于該殼的保護(hù)報(bào)錯(cuò)了的話,大家可以將其到別的路徑下,然后重啟加載試(PS:我實(shí)驗(yàn)的時(shí)候,采用XPSP3的虛擬機(jī),所有異常都忽略了,但是直接運(yùn)行起來(lái),還是報(bào)這個(gè)錯(cuò)誤框,后來(lái)我換成XPSP2的虛擬機(jī),忽略所有異常又是正確的,具體原因還不清楚。所以這里大家遇到這個(gè)問(wèn)題實(shí)在搞不定的話,就換XPSP2的系統(tǒng)吧)Copyollybone.dllandi386/ollybone.systoyourOllyDbgdirectory 大家在脫ASProtect這款殼的時(shí)候要格外,因?yàn)樗鼤?huì)對(duì)INT3斷點(diǎn)以及硬件斷點(diǎn)進(jìn)行檢測(cè),如果檢測(cè)到的話,就會(huì)報(bào)錯(cuò),那我們就只能據(jù)s的擴(kuò)展名來(lái)看就知道這是一個(gè)驅(qū)動(dòng)程序這個(gè)插件主要是用來(lái)模擬執(zhí)行斷點(diǎn)的協(xié)助我們的我們前面章節(jié)介紹的專門用于定位EP的那款)更快的定位到就是我們不能對(duì)程序進(jìn)行單步所以說(shuō)我們?cè)谡{(diào)試之前先要將igisitpek說(shuō)明如: 我們大概按4,5下F鍵就可以由第一個(gè)區(qū)段跳轉(zhuǎn)到起始地址為 置break-onexecute(執(zhí)行斷點(diǎn),該功能是OllyBone插件提供的)。我們來(lái)看看的說(shuō)明:可以看到確實(shí)啟用了DEP,未啟用DEP的時(shí)候這個(gè)選項(xiàng)卡的框是灰下去的,無(wú)法選擇。 我實(shí)驗(yàn)的環(huán)境是XPSP2。停在了殼的點(diǎn)處實(shí)上ASPrtct者伎。接來(lái) 略選勾可以看到,接下來(lái),忽略內(nèi)存異常這個(gè)選項(xiàng)的對(duì)勾去掉 ysisfrommodule選項(xiàng)重新分析代碼OEP=IAT=IAT=,擊Add按鈕來(lái)添加DLL,譬如這里的460F24這個(gè)IAT項(xiàng)所在的DLL就被遺漏了。我們來(lái)看看該項(xiàng)的參考。我們直接單擊Fixdump按鈕修改dump文件。能,我們單擊鼠標(biāo)右鍵選擇Fixntdll.dllcalls即可。給大家的任務(wù)就是15天之內(nèi)編寫出一個(gè)來(lái)修復(fù)AntiDump。完成任務(wù)的童鞋可以發(fā)郵件給我,我會(huì)一個(gè)一個(gè)的看并進(jìn)行點(diǎn)評(píng)。在下一個(gè)章節(jié)中,我會(huì)給出一個(gè)在我看來(lái)最簡(jiǎn)單最高效的。未修復(fù)IAT之前ASProtect將其替換成了一個(gè)占5個(gè)字節(jié)的CALL(很明顯第6個(gè)字節(jié)是指令)。未修復(fù)IAT的情況下4272D5這004272D5E8268D5801CALL004272DA 來(lái)的地方不是很像關(guān)鍵點(diǎn)的話,就繼續(xù)自動(dòng),直到確認(rèn)是關(guān)鍵點(diǎn)為止。我們還有另一個(gè)切入點(diǎn)可以更加精確的定位關(guān)鍵點(diǎn)。就是執(zhí)行完CALL019B0000這條指令后,正常情況下會(huì)返回到4272DA這個(gè)地址處,但是4272DA處這個(gè)字節(jié)是指令。所 本章附件: 地址輸入完以后,單擊OK,該就開始執(zhí)行了。 目的:修復(fù)ASProtectv2.3SKE:Scitv13x或者更高版本,執(zhí)行到EP處忽略所有異常日期:備注varvarvar_ini_iatvarvar_dirvarvar_sigvarvar_api //jbcmp$RESULT,0jemovvar_base_aip,$RESULT //保存用戶輸入的待修復(fù)的地址movvar_oep,eip gmieip,codebase //獲取主程序代碼段的址 // //movvar_base_aspr,[46C048] addvar_base_aspr,3B02E //在址的基礎(chǔ)上加上這個(gè)常量就可以定位到關(guān)鍵地址了 //如果沒(méi)有找到,就輸出總共找到的CALL個(gè)數(shù),并退出jeno_calls //movvar_sig,var_dir movvar_dest,var_dir addvar_sig,5 //計(jì)算該CALL下一條指令的地址并保存到變量var_sig中incvar_dest movvar_dest,[var_dest] //獲取操作碼E8后的偏移量,并保存到變量var_dest中addvar_dest,var_sig //計(jì)算CALL的目標(biāo)地址cmpvar_dest,var_base_aip je // //jmp // cmpeip,var_base_aspr // // // //判斷待修復(fù)的CALL的指令有沒(méi)有參考 eval"Calldword[{var_dir_iat}]"asmvar_dir,$RESULT //更新已修復(fù)項(xiàng)的計(jì)數(shù)incmov //eval"Jmpasmvar_dir,$RESULT incvar_countincmov //msg發(fā)生異常了,是否繼續(xù)"cmp$RESULT,0msg$RESULTbphwcmsg$RESULTbphwcvar_base_asprmoveip,var_oep附幾張的截圖movvar_base_aspr,[46C048] addvar_base_aspr,3B02E //在址的基礎(chǔ)上加上這個(gè)常量就可以定位到關(guān)鍵地址了 jmp // cmpeip,var_base_aspr // // // 首先判斷待修復(fù)CALL指令是否存在參考,如果不存在存在處則將其匯編為CALL[對(duì)應(yīng)IAT項(xiàng)的地址]的形式,如果存在參考引用,則將其匯編為JMP[對(duì)應(yīng)IAT項(xiàng)的地址]的形式。然后按照上面的步驟繼續(xù)修復(fù)其他的項(xiàng), Part1:編寫定位OEP并修復(fù)StolenbytesPart2:編寫修復(fù)IAT確實(shí)有點(diǎn)弱智,),嘿嘿)MartianTPPpack本章到此結(jié)束,感謝大家的本章附件上一章中最后留的那個(gè)小比賽最后的獲勝者是Ularteck童鞋。下面我們就用Ularteck童鞋編寫的第一個(gè)來(lái)定位OEP以及修stolenbytes。如下#############################################################################################################CracksLatinoS-作者描述:該的功能的定位TPPpack的OEP以及修復(fù)其stolen目標(biāo)程序配置要求:ODBGScript1.48,HideDebugger1.24,HideOD,停在點(diǎn)處,忽略Kernel32的異常,其他異常均不忽略.本以下關(guān)于該的詳細(xì)注vardir_excepvarNewoepvardir_JMPvardir_CALLvaroepvarStartScanvartempvartemp2vartemp3movNewoep, // 點(diǎn)保存到變量Newoepask"最后一次異常的地址是多少?"http://彈出一個(gè)框讓用戶輸入最后一次異常的地cmp je //如果用戶沒(méi)有輸入地址則跳轉(zhuǎn)到warningmovdir_excep, //將用戶輸入的地址保存到變量dir_excepjmp //跳轉(zhuǎn)到Initiationmsg"請(qǐng)重新執(zhí)行該,再次輸入一個(gè)有效的地址!"jmpfinal eoe //如果發(fā)生異常斷了下來(lái),就跳轉(zhuǎn)到checkcmp je //斷下來(lái)的地方剛好是最后一次異常處,則跳轉(zhuǎn)到last //忽略掉異常繼續(xù)執(zhí)行,相當(dāng)于在OD中按SHIFT+F9jmpIntiation: //跳轉(zhuǎn)Initiation處繼續(xù)定位最后一次異常處findopeip,#FFE0# //從最后一次異常處開始搜索JMPEAX指令,以便下面定位stolenbytesmovdir_JMP,$RESULT//將JMPEAX指令的地址保存到變量dir_JMP中bp //對(duì)JMPEAX //忽略掉異常繼續(xù)執(zhí)行,相當(dāng)于在OD中按了SHIFT+F9bcdir_JMP //刪除掉JMPEAX指令處的斷點(diǎn) //單步步入,相當(dāng)于在OD中按F7,單步以后就到了stolenbytes處movoep,eip //將stolenbytes的起始地址保存到變量oep中mov //將stolenbytes的起始地址保存到變量StartScan //開始搜索Stolenbytes中需要修正偏移量的findop //搜索以機(jī)器碼E8開頭的CALL指令,即待修正偏移量的CALLcmp$RESULT, //判斷是否搜索到了待修正偏移量的CALLje //沒(méi)有搜索到的話,則跳轉(zhuǎn)到finalmovdir_CALL, //將待修正偏移量CALL的地址保存到變量dir_CALLmovStartScan,$RESULT //將待修正偏移量的CALL指令的地址賦值給變量StartScanadddir_CALL,1 //指向偏移量movOpcodes, //獲取待修正的偏移量并保存到變量OpcodesaddOpcodes //將偏移量加上CALLadd //加上CALL這樣就得到了CALLmovtemp, //將CALL指令的地址保存到臨時(shí)變量tempsubtemp,oep //計(jì)算CALL指令距離stolenbytes起始地址的長(zhǎng)度,并保存到臨時(shí)變量temp中movtemp2,Newoep //將 addtemptemp //計(jì)算CALL指令新的地址,并保存到變量tempsubOpcodes, //將目標(biāo)地址減去CALLsubOpcodes, //然后減去5,就得到了CALL //將CALLmovtemp3, //將CALL指令所在的地址保存到臨時(shí)變量temp3add mov[temp3Opcod jmpLookForCall附的截圖下面我來(lái)給大家詳細(xì)講解這個(gè)的作用Part1:定位OEP并修復(fù)stolenbytes(byUlarteck)情下面我們利用最后一次異常法來(lái)定位OEP,對(duì)于最后一次異常法大家應(yīng)該很熟練了吧。我們經(jīng)常會(huì)用到它。此法同樣適用ASProtect2.1SKE,2.2SKE,2.3SKE以及帶VM接著將程序運(yùn)行起來(lái),然后打開日志窗口,這里后次異指令在地址為0046D36B,下我們可以用來(lái)位OEP在使用之前,我先演示一下如何手工定位。LT+M打開區(qū)段列表窗口。對(duì)代碼段設(shè)置內(nèi)存斷點(diǎn)。我們現(xiàn)在將修改一下,讓其自動(dòng)定位到最后一次異常處。將好,我們重啟OD以后,執(zhí)行該里彈了個(gè)框要我輸入后一異指令在的址這里輸入46D36B。單擊OK。我可看到行了我可以到剛斷在最一次常處。我們按ALT+M打開區(qū)段列表窗口。下來(lái)們不是剛才樣代碼設(shè)置存斷點(diǎn),次我對(duì)始地為8B0000的區(qū)段置內(nèi)存斷點(diǎn)。按SHIFT+F9忽略掉運(yùn)行起來(lái),斷在了stolenbytes處。下是據(jù)artian先在的中介的定位stlenbytes的路寫,定stlenbytes思路下:先位到后一次異常處,接著往下搜索機(jī)器碼為FFE0的JPEX指令,搜到該指令以后,對(duì)其設(shè)置斷點(diǎn),接著運(yùn)行起來(lái),斷到了MPEX,按F鍵單步一下,就可以到達(dá)stnbyts處了。我們?cè)谥刑砑右粋€(gè)變量變量dir_JMP用于保存JMPEAX指令的地址。我們執(zhí)行 看看效果我們可以看到成功定位到了stolenbytes處。下面我們要做的就是將stolenbytes拷貝 點(diǎn)處里我8B0E48開拷貝,一8B0EA4為,意是進(jìn)制。粘貼到點(diǎn)處。但是由于這是一個(gè)間接CALL,所以我們這里直接將其二進(jìn)制到別的地方的話,目標(biāo)地址就變了所以這個(gè)CALL被到別處的話,首先需要修正偏移量,我們來(lái)看看如何修正偏移量,首先我們?cè)跀?shù)據(jù)窗口中定位到該指令FFB784FC,為了下面列方便,這里其命名為OPCODES這里008B0E9F,即這個(gè)CALL指令所在的地址命名為DIR_CALL。我們來(lái)算一下目標(biāo)地址004293A0是如何得到的:目標(biāo)地址=OPCODES+DIR_CALL+好了現(xiàn)在我們已經(jīng)知道004293A0OCODES目標(biāo)地址-CL指令新的地址-5=新的CDCLL指令新的地址即該CLL如果Stolenbytes拷貝 點(diǎn)處里我看46B067個(gè)地。這地的計(jì)算下:原地址-tnbyts的起始地址+ 點(diǎn)stolenbytes所以說(shuō)新地址為好了現(xiàn)在我們來(lái)計(jì)算新的OCODE。目標(biāo)地址-新地址-5=FFB這里新的OPCODES我們有了。現(xiàn)在我們來(lái)手動(dòng)編輯它。我們定位到stolenbytes我們?cè)跀?shù)據(jù)窗口中定位到這個(gè)將其替換成新的 點(diǎn)處我們可以看到46B067CLL給添加一些內(nèi)容讓其自動(dòng)完成上述操作。執(zhí)行該里我可看到行了該后,面CALL的移都被正了。下面我們要做的就是將stolenbytes二進(jìn)制到 點(diǎn)處。 點(diǎn)處,EIP修改 點(diǎn)處修改為這里我不使用OllyDump來(lái)修復(fù)IAT,所以我去掉了RebuidImport的對(duì)勾。然后按dp按鈕進(jìn)行dp。,這里我們就dump完成了,,因?yàn)镮AT還沒(méi)有修復(fù)。下面我們來(lái)修復(fù)IAT。這里提一句,HideOD這款插件有時(shí)候會(huì)出錯(cuò)導(dǎo)致程序正常運(yùn)行,所以最好將其用HideDebugger和OllyAdvanced代替。好了,第一個(gè)已經(jīng)給大家介紹完了,接下來(lái)給大家介紹第二個(gè)。vardir_VirtualAllocvardir_VirtualProtectvardir_movgpa"VirtualAlloc","kernel32.dll" movdir_VirtualAlloc,$RESULTlogdir_Virtgpa"VirtualProtect","kernel32.dll"movdir_VirtualProtect,$RESULTbpdir_VirtualAlloclogbasebcdir_VirtualAllocbpdir_VirtualProtectcmpesi,bcdir_VirtualProtectmovReg_esp,[esp]bpReg_espfindbase,#897C24188B4424#movdir_mov,$RESULTlogdir_movjmpNopeobNop2msg"NOP完畢,請(qǐng)按F9鍵運(yùn)行."附第二個(gè)截圖是修IAT其一比較典的法,Martian生在的中細(xì)介過(guò)。到達(dá)OEP之前們可對(duì)IAT中定向項(xiàng)設(shè)置內(nèi)存寫入斷點(diǎn),IAT進(jìn)行寫入的話,首先得讓IAT,所會(huì)調(diào)VirtualProtect來(lái)改IAT所在存單的存屬性,予其入權(quán)。以我們以先對(duì)VirtualProtect這Martian先生 這張圖們可看到在了Virtualrotect這個(gè)AP函的處,其修改T在內(nèi)單元的屬性。我們執(zhí)行到返回,然后對(duì)重定向的T項(xiàng)設(shè)置內(nèi)存寫入斷點(diǎn),接著運(yùn)行起來(lái),斷在了寫入重定向值的地方。,EAX中保存了重定向的值,EBPIAT們面幾行處設(shè)置一個(gè)斷點(diǎn),一下,看看是什么情況。IT,而接下來(lái)會(huì)將正確的ITNOP掉。首先要做的第一件事情就是查找VirtualAlloc這個(gè)API函數(shù)的地址,首次斷到VirtualAlloc這個(gè)API函數(shù)時(shí),我們就可以獲取需NOP掉的指令所在內(nèi)存單元的首地址了,因?yàn)樵诓煌臋C(jī)器上,待NOP掉的指令的地址是會(huì)變的,vardir_VirtualAllocvardir_VirtualProtectvardir_movgpa"VirtualAlloc","kernel32.dll" movdir_VirtualAlloc,$RESULTgpa"VirtualProtect","kernel32.dll"movdir_VirtualProtect,bpdir_VirtualAlloclogbasebcdir_VirtualAllocbp接著對(duì)VirtualAlloc設(shè)置斷點(diǎn),運(yùn)行起來(lái),如果斷下來(lái)就跳轉(zhuǎn)到info處,將該程序剛申請(qǐng)的內(nèi)存單元的首地址保存到變base中,下面我們需要NOPcmpesi,jeReturnjmpArea下來(lái)的,斷ESI值是等460000IT的起地址,為程序調(diào)用irtualrotect修改T在內(nèi)單的屬性。如果等于6的話,就跳轉(zhuǎn)到rtrn處。bcdir_VirtualProtectmovReg_esp,[esp]bpReg_espfindbase,#897C24188B4424#movdir_mov,$RESULTlogdir_movjmpNopVirtualProtect調(diào)用返回后,NOP:897C24188B4424。搜索到了的話就跳轉(zhuǎn)到Nop處eobNop2msg"NOP完畢,請(qǐng)按F9鍵運(yùn)行.",這第二個(gè)也介完了感謝Ularteck童鞋供的兩個(gè)及Martian生提供的我從Martian先的中截了一張來(lái)解釋第二個(gè)。本章,大家應(yīng)該對(duì)于如何編寫更加了解了吧。SCRIPT.TPPpack-(S:的選什同等們?cè)摰膫€(gè)護(hù)研透了后再分我最的標(biāo)序就很。就該布版我對(duì)前深解分其應(yīng)不太因通來(lái)本改 這 我們應(yīng)該很熟悉了吧,可以說(shuō)幾乎本系列的每一個(gè)章節(jié)都可以看到。由謂,但是BreakonTLSCallback這個(gè)選項(xiàng)這里要記得勾選。如大O加載PckMxrytr....x的話會(huì)現(xiàn)沒(méi)達(dá)到程就出。是為Exrytr了TSABAK一性在點(diǎn)前行碼檢否在調(diào)試如則出程TSABAK以在點(diǎn)前Exrytr我們一運(yùn)行起來(lái)就會(huì)斷在TLSCALLBACK處。這是OllyAdvanced這個(gè)插件幫我們定位到的TLSCALLBACK回調(diào)函數(shù)的地址。下面我們來(lái)看看如何手工定位TLSCALLBACK回調(diào)函數(shù)的地址。 窗口中定位到該地址,我們往下面看就可以找到TLS回調(diào)函數(shù)的地址。這里我們就定位到了ExeCryptor在到達(dá)點(diǎn)之前要執(zhí)行代碼的起始地址了,使用OllyAdvanced插件的話,它可以幫助我們直接定位到 我們可以看到TLSTable起始地址的RVA為93110,大小為18。這右邊還有個(gè)TLS按鈕,單擊該按鈕我們就可以精確的查看TLS的回調(diào) 這里我們打開斷點(diǎn)窗口查看一下,盡管我們之前并沒(méi)有設(shè)置斷點(diǎn),我們可以看到這里有一個(gè)斷點(diǎn)CALLBACK回調(diào)函數(shù)的處。老規(guī)矩,刪除掉斷點(diǎn)列表窗口中的斷點(diǎn)。我們要的是執(zhí)行導(dǎo)致的中斷,而不是或者寫入導(dǎo)致的中斷)繼續(xù)給返回地址處設(shè)置一個(gè)斷點(diǎn),我們繼續(xù)往下單步來(lái)驗(yàn)證一下 本章一個(gè)來(lái)復(fù)的能童到這有頭的。嘿一來(lái)說(shuō)人編好的通都較起非復(fù)的子會(huì)覺(jué)頭發(fā)撒但我里換不直拿個(gè)成的大是著家零始寫個(gè)逐加樣家受來(lái)容的。varmovtable,460818 logtablevarmovtable,460818cmp[table],jaToSkiplogtablejmpstart這里我們已經(jīng)改過(guò)來(lái)了,再次執(zhí)行該看看效果vartablemovtable,460818cmpjaloglogcontentjmpstart令,然后停在斷點(diǎn)處。好了,現(xiàn)在我們關(guān)閉這個(gè)窗口,繼續(xù)給我們的添加新的內(nèi)容。varmovcmptable,460F28jafinalcmp[table],jaToSkiplogtablelogcontentjmpstartvartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkiplogtablelogcontentjmpstart這里我們就將logcontent后面ret命令去掉了,這樣處理之后,在記錄完重定向IAT項(xiàng)的地址以及值以后,會(huì)到達(dá)ToSkip處繼續(xù)遍歷后面的IAT項(xiàng),重復(fù)上面的過(guò)程,直到遍歷完整個(gè)IAT為止,我們來(lái)看看該執(zhí)行的效果。vartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablejmpstart -- cobToRepair-- cobToRepair 處,我們繼續(xù)wrn將A處執(zhí)后發(fā)二的沒(méi)被這是會(huì)異因也們的輯用OD的自動(dòng)功能),OD自動(dòng)大約要花5分鐘左右的時(shí)間。部分指令序列如下:00483C91MainMOVAL,1;00483C93MainJMP00483C7EMainPOPECX; ,00483C7FMainPOPECX;ECX=77DA6C75,00483C80MainPOPEBP;ESP=0012FE74,00483C81MainRETN;004833D5MainTESTAL,AL;004833D7MainJNZ0047CC50MainPOPECX; ,0047CC51MainPOPECX;ECX=77DA6C75,0047CC52MainPOPEBP;ESP=0012FE84,0047CC53MainRETN;CMainMOVEAX,DWORDPTRSS:[EBP-C];EAX=77DA6BF0FMainMOVESP,EBP;ESP=0012FFB0MainJMP004765DC004765DCMainJMP0047F15C0047F15CMainPUSH47C9B5;004737D4MainRETN;0047C9B5MainPOPEBP;ESP=0012FFB4,Memorybreakpointwhenwritingto CMainMOVEAX,DWORDPTRSS:[EBP-C];0046E81DC3RETN這里正確的IAT函數(shù)地址將被保存到EAX中,所以下面我們來(lái)修改,讓其斷在47691C這條指令處,執(zhí)行完這條指令后,EAX就保存了正確的API函數(shù)地址,接著其填充到對(duì)應(yīng)的IAT項(xiàng)中。vartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentcobToRepairlogeaxmov[table],eaxjmpstart好,那么現(xiàn)在table指針初始化為460988,然后執(zhí)行,看看還會(huì)不會(huì)報(bào)錯(cuò)。vartablemovtable,460988cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentcobToRepairlogeaxmov[table],eaxjmpstart導(dǎo)致我們無(wú)法繼續(xù)修復(fù),下面大家來(lái)看看我的解決方案,cmplogeaxmov[table],eax決定)。當(dāng)執(zhí)行的過(guò)程中觸發(fā)了異常的話,我們判斷該程序是不是在嘗試調(diào)用ZwTerminateProcess這個(gè)函數(shù)來(lái)結(jié)束進(jìn)程,如果是的經(jīng)修改后,我們的就變成了這個(gè)樣子cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentmov[47691F],0mov[476920],0cobToRepaircmpeip,7C91E88EjeToSkiplogmov[table],eaxjmpstart這里我們把忽略內(nèi)存異常這個(gè)選項(xiàng)的對(duì)勾去掉,執(zhí)行打開IMPREC進(jìn)一步分析,我個(gè)人感覺(jué)這個(gè)方法不是很通用,如果大家也搞不定的話,可以參考我之前發(fā)過(guò)的那套國(guó)外的脫殼全集,里面本章附件:第五十六章-EXECryptorv2.2.50.b 這里我們可以看到斷在了系統(tǒng)斷點(diǎn)處,我們打開斷點(diǎn)列表窗口,刪除里面的斷點(diǎn)我們可以看到D右下角狀態(tài)仍然是但是程序的主界面還是沒(méi)有彈出來(lái)所以我們?cè)俅螌⒃摼€程掛起繼續(xù)恢復(fù)下一個(gè)線程如面接著運(yùn)行起來(lái),發(fā)現(xiàn)并沒(méi)有斷下來(lái), 話,那就最好不過(guò)了,如果不是的話,我們就還需要定位讓程序正常運(yùn)行必需的第三個(gè)或者的線程。好,下面這兩個(gè)線程以外的其他線程都掛起 也就是說(shuō)該程序要想正常運(yùn)行,這里我給大家一些小小的建議:在脫一些強(qiáng)殼的時(shí)候,大家沒(méi)有必要按照一些的步驟來(lái)生搬硬套,大家要學(xué)會(huì)靈活變通有時(shí)候,看到網(wǎng)上的一些的脫殼步驟(譬如:按5次F8,3次F7就可以到達(dá)OEP處了+_+),說(shuō)實(shí)話這種有點(diǎn)滑稽可笑,不免有誤人子這里就拿我當(dāng)前的這個(gè)脫殼方案來(lái)說(shuō)吧說(shuō)不定換了一臺(tái)機(jī)器就行不通了也說(shuō)不定。不可控的因素太多了有時(shí)候可能同一款殼在不同反件的可會(huì),種東能我量以家平脫的程中要總結(jié)經(jīng)驗(yàn),活學(xué)活用。 對(duì)OEP下面調(diào)用的第一個(gè)API函數(shù)對(duì)應(yīng)的IAT項(xiàng)設(shè)置內(nèi)存寫入斷點(diǎn),接著利用OD的Traceinto功能來(lái)進(jìn)行自動(dòng),自動(dòng)的時(shí)間大這次MOVEAX,DWORDPTRSS:[EBP-C]這條指令的地址為483420,好,下面我們對(duì)上一章中編寫的那個(gè)進(jìn)行相應(yīng)的修改,上一章中的如下vartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentbphws47691F,"x"mov[47691F],0mov[476920],0cobToRepaircmpeip,7C91E88EjeToSkiplogmov[table],eaxjmpstart-CMainMOVEAX,DWORDPTRSS:[EBP-C];EAX=77DA6BF0FMainMOVESP,EBP;ESP=0012FFB0>8B45F4MOVEAX,DWORDPTRSS:[EBP-C];.|8BE5MOVvartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentmov[483423],0movcobToRepaircmpeip,7C91E88EjeToSkiplogmov[table],eaxjmpstart cmpeip,483423jnetoToSkiplogeaxmov[table],eax這里我們執(zhí)行該,會(huì)發(fā)現(xiàn)還是出錯(cuò)。沒(méi)有調(diào)用ZwTerminateProcess,難道是這里我們需要忽略內(nèi)存異常嗎?好,我們忽略掉內(nèi)存異常試試。完整的如下:vartablemovcmpjafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentmov[483423],0movcobToRepaircmpeip,483423jneToSkiplogmov[table],eaxjmpstart這里大家要記住在執(zhí)行該之前,需要手動(dòng)在ZwTerminateProcess這個(gè)API函數(shù) 將TLSTableaddress和TLSTablesizeUnPackMe會(huì)檢測(cè)是否存在表以及文件監(jiān)視工具,如果檢測(cè)到了會(huì)將它們關(guān)閉。EAX,DWORDPTRSS:[EBP-C]這條指令的地址為486DF7。00486DF78B45F4MOVEAX,DWORDPTRSS:[EBP-00486DFA CALL0049D560;00486DFF5BPOP00486E008B0424MOVEAX,DWORDPTR00486E0352PUSH如下vartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentbphws486DFA,"x"mov[486DFA],0mov[486DFB],0cobToRepaircmplogeaxmov[table],eaxjmpstart 執(zhí)行該修復(fù)IAT,IAT修復(fù)完畢以后就可以進(jìn)行dump了,然后打開IMPREC修復(fù)dump文件,這樣UnPackMeC就搞定了。UnPackMe我們可以看到調(diào)試消息這個(gè)選項(xiàng)開啟了,也就是說(shuō)會(huì)檢測(cè)調(diào)試消息。不知道對(duì)我們有沒(méi)有影響,我們用OD加載UnPackMeD,還是跟之 自動(dòng)需要一段時(shí)間0046D8DC8B45F4MOVEAX,DWORDPTRSS:[EBP-C];0046D8DF8BE5MOVvartablemovtable,460818cmpjafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentbphws46D8DF,"x"mov[46D8DF],0mov[46D8DF],0cobToRepairjneToSkiplogmov[table],eaxjmpstart個(gè)硬件執(zhí)行斷點(diǎn),接著執(zhí)行該。UnPackMe們直接來(lái)看UnPackMeG,UnPackMeG的話就會(huì)玩一些新花樣了。UnPackMe我們雙擊運(yùn)行UnPackMeG,可以看到這個(gè)等級(jí)反 EAX,DWORDPTRSS:[EBP-C]這條指令,不知道反 點(diǎn),接著運(yùn)行起來(lái),我們會(huì)發(fā)現(xiàn)在到達(dá)OEP之前,會(huì)斷下來(lái)5到6次(由于單步異常導(dǎo)致的),這是反這個(gè)選項(xiàng)帶來(lái)第一處影響。我們可以看到OD狀態(tài)欄中提示:發(fā)生了單步異常,需要我們手動(dòng)按Shift+F7/F8/F9忽略掉這個(gè)異常繼續(xù)往下執(zhí)行。這里我們不能夠勾選忽略單步異常這個(gè)選項(xiàng),如果我們勾選了這個(gè)選項(xiàng)的話,那么OllyBone插件就不起作用了,所以這里須手動(dòng)按Shift+F9忽略這些單步異常,大約按5到6次Shift+F9就可能斷到OEP處了。我們可以看到這里只有該程序運(yùn)行必需的兩個(gè)線程如果還存在其他線程這里我們姑且稱這些線程為線程的話,我們需要將這些線掛。由反式了以萬(wàn)一件面以及這個(gè)選 和 下面我們?cè)谌罩局卸ㄎ籑OVEAX,DWORDPTRSS:[EBP-C]這條指令00491E658B45F4MOVEAX,DWORDPTRSS:[EBP-C];kernel32.GetVersion00491E688BE5MOV 這 中硬件執(zhí)行斷點(diǎn)的地址替換掉vartablemovtable,460818cmptable,460F28jafinalcmp[table],jaToSkipcmpcontent,0jeToSkiplogtablemoveip,contentbphws491E68,"x"mov[491E68],0mov[491E68],0cobToRepairjneToSkiplogeaxmov[table],eaxjmpstart我們可以看到IMPREC中顯示有無(wú)效的項(xiàng),我們單擊該項(xiàng)左邊的加號(hào)將其展開,可以看到這些項(xiàng)修復(fù)后的值是錯(cuò)誤的。movtable,460818cmptable,460978jafinalcmp[table],jaToSkip 執(zhí)行了該以后,我們可以看到所有的項(xiàng)都被修復(fù)了本章附件ExeCryptor2.2.50.rar第五十八章-ExeCryptor我們可以看到點(diǎn)保護(hù)開啟了。也就是說(shuō),點(diǎn)可能被隱了貌似有點(diǎn)不對(duì)勁,我們?cè)賮?lái)看看之前脫過(guò)殼的版本的原理,對(duì)于大部分殼(PS:有少數(shù)殼可能會(huì)玩一些把戲,譬如說(shuō):ExeCryptor,它利用了TLS在點(diǎn)之前執(zhí)行代碼,所以此時(shí)的棧頂指針就我們當(dāng)前這個(gè)例子來(lái)說(shuō),點(diǎn)處時(shí)棧頂指針ESP指向的地址是12FFC4。大家在平時(shí)脫殼的時(shí)候也要多多留意點(diǎn)處的棧頂指面我們來(lái)執(zhí)行PUSHEBP這條指令。我們可以看到EBP的值被保存到12FFC0中了,這是原程序執(zhí)行的第一條指令。下面我們來(lái)看看UnPackMeH,此時(shí)的棧頂指針指向的 004271CD83C4A8ADDESP,-58已脫殼設(shè)置完內(nèi)存寫入斷點(diǎn)以后,我們運(yùn)行起來(lái),00496CBB01變成了000048E2C28F85C0A04700POPDWORDPTRSS:[EBP+47A0C0];EDI7C920738保存到47A4CCB89BDC0A44700MOVDWORDPTRSS:[EBP+47A4C0],EBX=7FFDB000保存到中00498D03899D8C114800MOVDWORDPTRSS:[EBP EAX=0012FFC0保存到0047B0D8中EAX=14F43E150047ACCC中00496CAB01變成了00EDI7C9207380047A888 ESIFFFFFFFF0047AC8800470F8289B5C0A84700MOVDWORDPTRSS:EBP+47A8C0ESIEDX=0047F3EF0047C0B4中EBX=7FFDB000保存到中00498D03899D8C114800MOVDWORDPTRSS: C],雖然我們已經(jīng)執(zhí)行了大量的指令,但是還是沒(méi)有遇到第一條該程序真正要執(zhí)行的指令,我們只能耐心的繼續(xù)往下跟EAX0012FFC40047B49400498D0B8985CCB04700MOVDWORDPTRSS:[EBP+47B0CC],0047B494C4FF1200C83ADCCB047000>SUBDWORDPTRSS:[EBP+47B0CC],0047B494C0FF120048E2C28F85C0A04700POPDWORDPTRSS:[EBP+47A0C0];大家應(yīng)該還記得吧-還沒(méi)有執(zhí)行該程序真正要執(zhí)行的指令呢,EDI=7C9207380047A848B89BDC0A44700MOVDWORDPTRSS:[EBP+47A4C0],EDI;ESI=FFFFFFFF0047AC4800470F8289B5C0A84700MOVDWORDPTRSS:[EBP+47A8C0],繼續(xù)耐心往下EBX= 00498D03899D8C114800MOVDWORDPTRSS: C],EBX;EAX=0012FFBC0047B454EAX=192082C00047B048我們明顯的看出這里實(shí)際上是一個(gè)循環(huán), EBX=0048F082保存到 00496D8A01變成了000048E2C28F85C0A04700POPDWORDPTRSS:[EBP+47A0C0];EDI=7C9207380047A60C中ESIFFFFFFFF0047AA0CEDX=0047F3EF0047BE38中ECX=0047F3EF0047BA2C中EAX=0047E97E0047B624中EBX=7FFDB000004812D800498D03899D8C114800MOVDWORDPTRSS:[EBP CEBXEAX=0012FFC0保存到0047B218中EAX=1B700602保存到0047AE0C中EAX=FFFFFFFF0047B6247EE94700中00496CEB00 還是沒(méi)有看到真正要執(zhí)行的第一條指令,EBX=7FFDB000保存到 004923C8871C24XCH

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論