使用ollydbg從0開(kāi)始crack版1-2201.第一章OD的各個(gè)窗口介紹_第1頁(yè)
使用ollydbg從0開(kāi)始crack版1-2201.第一章OD的各個(gè)窗口介紹_第2頁(yè)
使用ollydbg從0開(kāi)始crack版1-2201.第一章OD的各個(gè)窗口介紹_第3頁(yè)
使用ollydbg從0開(kāi)始crack版1-2201.第一章OD的各個(gè)窗口介紹_第4頁(yè)
使用ollydbg從0開(kāi)始crack版1-2201.第一章OD的各個(gè)窗口介紹_第5頁(yè)
已閱讀5頁(yè),還剩252頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

OllyDbgCracking第一章-OD第七章-call 第十三章-硬編碼序列號(hào)尋蹤-第十四章-硬編碼序列號(hào)尋蹤-第十五章-硬編碼序列號(hào)尋蹤-第十六章-序列號(hào)生成算法分析-第十七章-序列號(hào)生成算法分析-第十八章-序列號(hào)生成算法分析-第十九章-OllyDbgIsDebuggerPresent20.第二十章-OllyDbg反調(diào)試之檢測(cè)OD進(jìn)程名第二十一章-OllyDbgOD第二十二章-OllyDbgUnhandledExceptionFilterZwQueryInformationProcess23.第二十三章-OllyDbg反調(diào)試之ProcessHeapNTGlobalFlagOutputDebugStringA第二十四章-OllyDbgIAT第三十六章-IATIATYoda'sCrypterv1.339.第三十九章-何謂stolenbytes第四十章-OllyDbg的編第四十二章-ACProtectV1.09OEPStolen第四十三章-ACProtectV1.09脫殼(編寫(xiě)修復(fù)IAT)44.第四十四章-ACProtectV1.09脫殼(修復(fù)AntiDump)45.第四十五章-ReCryptv0.80脫殼45.第四十五章補(bǔ)充章節(jié)-ReCryptv0.8046.第四十六章-PatrickCrackMe-Part147.第四十七章-PatrickCrackMe-Part250.第五十章-再談ReCryptv.0.80脫殼(OutputDebugString)51.第五十一章-ASProtectv2.3.04.26脫殼-Part153.第五十三章-TPPpack 脫殼54.第五十四章-EXECryptorv2.2.50.a脫殼-Part156.第五十六章-EXECryptorv2.2.50.b脫殼57.第五十七章-EXECryptorv2.2.50.c.d.e.f.g58.第五十八章-EXECryptorv2.2.50第?章-OD(《使用OllyDbg從零開(kāi)始Cracking》 的目的是為那些想精通Cracking(譯注1)藝術(shù)的人提供必要的基礎(chǔ)知識(shí)。有了這些基礎(chǔ) 寫(xiě)這個(gè)想法的產(chǎn)生,是由于了《INTRODUCCIóNALCRACKING中的很多對(duì)于新手來(lái)說(shuō)太過(guò)于復(fù)雜。而新手們還未《INTRODUCCIóNALCRACKING中的(它里面的數(shù)量已逾500),而是為學(xué)完這個(gè)課程后的讀者打下一個(gè)良好的基礎(chǔ),以便去學(xué)習(xí)閱讀日益復(fù)雜的資料。它的主要目的是減少課程數(shù)量,提供必要的基礎(chǔ)知識(shí),從而使新的Cracker對(duì)更復(fù)章資料為什么使?SoGICE和OllyDbg之間的對(duì)抗,我認(rèn)為即使是SoGICE的狂熱追隨者也可以很容易的入手OllyDbg。而OllyDbg擁有的資料且更容易學(xué)習(xí)。我們需要從OllyDbg這扇大門(mén)進(jìn)入Cracking的世界。以后可能會(huì)在必要的時(shí)候換成其它調(diào)試器,但變化的只是它們的使用方法,不變的是它們的本質(zhì)。首先,需要裝備我們以后將主要使用的工具(OllyDbg),點(diǎn)此(譯注3)成功后,將其解壓到你容易的硬盤(pán)文件夾內(nèi),一個(gè)好的辦法是在C盤(pán)創(chuàng)建一個(gè) 盡管它在哪里都可以運(yùn)行,在這里我選擇了C:/。它的可執(zhí)行文件是OLLYDBG.exe好的,啟動(dòng)軟件,點(diǎn)擊OllyDbg上圖的消息框顯示,PSAPI.DLL,一個(gè)庫(kù)文件舊于我們系統(tǒng)上的同名DLL文件。如果你點(diǎn)擊Yes,那么這個(gè)舊文件就會(huì)從你的文件夾內(nèi),然后使用系統(tǒng)自身的。盡管我看不出兩個(gè)文件有什么不同,但是最好選擇隨軟件包自帶的,所以要點(diǎn)擊No(譯注這是純凈的OllyDbg(譯注:未加載插件非修),為了逐漸熟悉OllyDbg,我們打開(kāi)的第一個(gè)程序來(lái)自著名的CrueHead'aCrackMeOllyDbgFileOpen隨后打開(kāi)一個(gè)窗口,找到CrackMeCrackMeOllyDbg心的只是是如何將它打開(kāi)。之后,當(dāng)學(xué)習(xí)下一節(jié)課程時(shí),當(dāng)說(shuō)到Dump,至少你應(yīng)該知道到哪里去找這個(gè)選項(xiàng)。這里,我們看一下OllyDbgOllyDbg在這里顯示反匯編代碼,要以O(shè)llyDbg的默認(rèn)配置調(diào)試分析你打開(kāi)的程序。調(diào)試選項(xiàng)可以在Options->Debuggingoptions里更改。如果勾選了自動(dòng)對(duì)主模塊進(jìn)行分析(譯注5),OllyDbg這是CrackMe在分析結(jié)果中,出現(xiàn)了大量的信息,盡管我們現(xiàn)在還不清楚這些信息是什么,但看起來(lái)很有趣。同時(shí),最好要知道,如果分析的不夠正確或有錯(cuò)誤,這些消息可以在任何時(shí)候去除。lyDbg顯示程序的某些部分時(shí)是不正確的,錯(cuò)誤的將可執(zhí)行代碼解釋為數(shù)據(jù)。然后,它會(huì)顯示類(lèi)似于下圖中的內(nèi)容。 ysis->Removeysisfrommodule手動(dòng)刪除分析結(jié)果umps和calls,你使用它可能會(huì)更為方便但我個(gè)人不喜歡(這會(huì)有不同的體驗(yàn)),擇pearane>Highligting->Jps’nCalls。這里,我們看到Call句變?yōu)榫G色,跳轉(zhuǎn)變?yōu)辄S色?,F(xiàn)在,反匯編窗口更加容易閱讀。雖然到現(xiàn)在為止,我們頭腦里對(duì)這些是什么意思還沒(méi)有概看一下這個(gè)在OllyDbg還有一些重要的信息我們沒(méi)有看到。但是你可以設(shè)置顯示模式的不同類(lèi)型。,ViewFPUregisters顯示FPU寄存器,View3DNow!registers顯示3DNow!寄存器。Viewdebugregisters顯示調(diào)試寄存器。默認(rèn)是第一個(gè)。ESPEBP寄存器指向地址的信ESP寄存器指向的信息(也是最重要的),但是你可以改變它的顯示模式來(lái)顯示來(lái)自涉及EBP的信息。這需要在這個(gè)窗口上點(diǎn)擊右鍵,選擇GOtoEBP。再次點(diǎn)擊右鍵選擇GotoESP,回到先前窗口。在后續(xù)課程中,我將更加詳細(xì)的解釋堆棧的功能。但目前,我們還只能通過(guò)修改配置選項(xiàng)看數(shù)據(jù)窗?這個(gè)窗口有很多顯示模式,可以在該出口選擇你需要的,默認(rèn)模式為8-byteHex/ASCII默認(rèn)的模式是最常用的,我們還可以改變它以顯示反匯編代碼(Disassemble),文本(Text)和其它格式(Short,Long,F(xiàn)loat)另外,選擇Special->PEHeader,會(huì)在下節(jié)課程中看到,非常有用現(xiàn)在我們了解了OllyDbg的最主要的四個(gè)窗口。還有一些窗口沒(méi)有直接顯示,可以通過(guò)菜單或控制面板上的圖標(biāo)按鈕。(CrackMe)的信息和它加載的庫(kù)文件。LogtofileEView>Executables顯示程序運(yùn)行使用的模塊:exe,,dll,,ocxM按鈕或View->Memory顯示我們的程序映射到內(nèi)存的信息,一個(gè)內(nèi)存塊可能被分為幾個(gè)部分??梢运阉鞑煌N類(lèi)的字符串,可以在上設(shè)置中斷T按鈕或View->ThreadsW按鈕或View->WindowsH按鈕或View->HandlesCView->CPUOllyDbg的主窗口,CPU/View->Patches,如果程序經(jīng)過(guò)了修改,這里顯示修改的信息,現(xiàn)在我們的程序還沒(méi)K按鈕或View->Callstack顯示調(diào)用堆棧的窗口信息,可以嘗試反向函數(shù)的調(diào)用順序B按鈕或View->BreakpointsRView->ReferenceOllyDbg“...”按鈕或View->Runtrace顯示RUNTRACE(RUN)命令的結(jié)果。這里我們也可以通過(guò)Logtofile保存輸出結(jié)果到文件JITJUSTINTIME當(dāng)然,我們不一定會(huì)用的實(shí)時(shí)調(diào)試,除非特殊情況。因?yàn)槿绻覀冞\(yùn)行的程序出現(xiàn)時(shí),我們不需要使用OllyDbg(默認(rèn)為Dr.Watson)。OllyDbgOptionsJust-in-timedebuggingMakeOllyDbgjust-in-timedebuggerdoneRestoreoldjust-in-timedebuggerDone在OllyDbgOllyDbgCommandBar點(diǎn)擊這里(譯注:隨文附帶)插件。首先,你需要為插件建立文件夾,我將把它建立在C:\,名為PLUGINS當(dāng)然,此文件夾可以放在任何位置,但我喜歡將它放在C盤(pán),我們現(xiàn)在馬上配置OllyDbg,使OllyDbg將此文件夾認(rèn)可為所有插 要這樣做,選擇Options->Appearance然后在窗口中選擇Directories我們看到作為插件路徑 已被指定,即OllyDbg.exe所在 ,可以把插件放在那里,但是我喜歡將它們分開(kāi),點(diǎn)Pluginpath->BrowsePLUGINS出現(xiàn)上圖,說(shuō)明你需要重啟OllyDbg,它會(huì)認(rèn)可新的插件文件 ,但是首先你需要拷貝剛的插件所有文檔到PLUGINS現(xiàn)在CommandBar插件包里的所有文件都被到PLUGINS文件夾內(nèi)(通常不需要所有文件,只需DLL文件即可)OllyDbgPluginsCommandBar和它CommandBarOllyDbg這是一個(gè)供輸入命令的文本框,在很多情況下對(duì)我們很有用。以后,我們會(huì)看到它的用法。學(xué)習(xí)怎樣關(guān)聯(lián)插件這一部很重要。PLUGINSdllOllyDbg。然而,最好總是保持CommandBar被啟用。OllyDbgCrackMeOllyDbgF7執(zhí)行一行代碼,遇到CALL等子程序時(shí)會(huì)進(jìn)入其中,進(jìn)入后首先會(huì)停留在子程序的第一條F8CALL等子程序不進(jìn)入其代碼。F2F2我們想在確定位置40101A用鼠標(biāo)單擊此行,就會(huì)像圖中所示,此行被標(biāo)記為灰色,然后按F2F2則刪除斷點(diǎn)。F9運(yùn)行調(diào)試程序,直到遇到斷點(diǎn)停止運(yùn)行。當(dāng)程序運(yùn)行時(shí),在OllyDbg的右下角(譯注6)會(huì)顯示單詞Running通過(guò)運(yùn)行CrackMeF12DebugPauseOllyDbgPausedF9Debug->Run。選擇DEBUG->CLOSE就可以關(guān)閉調(diào)試程序。以上就是lyDbg總的概貌,其它深入的設(shè)置,在探討后續(xù)章節(jié)時(shí)會(huì)有所涉及。譯注1крэкнингаCracking代替。:西班牙文,強(qiáng)大的Cracking,這個(gè)系列程目前已有1200請(qǐng)從,:譯者注4在這里,本人建議使用系統(tǒng)自帶的文件。譯注5:該選項(xiàng)在Debuggingoptions的ysis1中,AutoStartysisofmainmodule這個(gè)位置顯示當(dāng)前狀態(tài),通常我們習(xí)慣將其設(shè)置在左上角,可以在Options->Appearance,General下勾選Showstatusintoolbar。1.OllyDbg1.10,本文使用原版,請(qǐng)從官網(wǎng),:CrackMe:ollydbg01-插件該系列目前已更新到第47章。本文原文為俄語(yǔ),譯者不才,斗膽翻譯,采用了能用的所有。雖經(jīng)本人嚴(yán)加審校,但難免訛誤。有些詞句加入了譯者的理解,所以可能部分內(nèi)容與原文有所出入。翻譯本文也是譯者學(xué)習(xí)的過(guò)程,所以錯(cuò)誤在所難免。如發(fā)現(xiàn)錯(cuò)誤,敬請(qǐng)指正,以免誤人。該系列 :[C]РикардоНарваха,пер.Aquila譯 (OllyDbg0110個(gè)字符(從0到9),0到F(0-9,A,B,C,D,EF16個(gè)字符)通常,除非另有說(shuō)明,當(dāng)我們提及某一具體數(shù)字時(shí)都將其認(rèn)作十六進(jìn)制。我們不使用將數(shù)值從一種數(shù)制轉(zhuǎn)換為其它數(shù)制的令人不太愉快的數(shù)學(xué)。當(dāng)前,Cracker們一般使用Windows自帶的計(jì)算器,它將更加快捷和容易使用,以避免繁冗的工作。ViewHex,八進(jìn)制Oct,二進(jìn)制Bin。8Cracking中不太常用,但如果需要,也可在計(jì)算器中選擇使用。55555537ABC,D,E,,F(xiàn)時(shí),我們可以從鍵盤(pán)輸入這些信息。我認(rèn)為這種方法在實(shí)踐中更有用途,允許我們不費(fèi)力的將數(shù)字從一種數(shù)制轉(zhuǎn)換到另一種數(shù)制??紤]到這個(gè)問(wèn)題后,我希望所有的問(wèn)題將會(huì)逐漸變的如果到FFFFFFFF所有可能的十六進(jìn)制數(shù)都寫(xiě)出來(lái),我們?cè)鯓颖硎矩?fù)數(shù)?正數(shù) 到7FFFFFFF,負(fù)數(shù) 到正0仍然是十進(jìn)制中的7FFFFFFF為十進(jìn)制 負(fù)FFFFFFFF和十進(jìn)制-1等同于十進(jìn)制的 (也是最小負(fù)數(shù)CommandBar7FFFFFFF在右邊,我們看到它返回了十進(jìn)制 現(xiàn)在,我們想看 的值是否為負(fù),我們看到它不能顯示(譯注1)7FFFFFFF之后的值(這是CommandBar的一bug),OllyDbgEAX選擇EAX的值,這個(gè)窗口也可以完成不同的轉(zhuǎn)換功能。第一欄填入我們這里,我們看到十六進(jìn) 轉(zhuǎn)換為了十進(jìn)制 FFFFFFFF為十進(jìn)制-1CancelASCII在以下截圖中,看到的這種數(shù)據(jù)將是我們學(xué)習(xí)的內(nèi)容之一。每個(gè)字符都被賦予了十六進(jìn)制值。這允許它們視為字符組合,這張表拷貝自(嘿嘿)?Теорииассемблера?(CaosReptante),你可以看到十進(jìn)制值,相應(yīng)的十六OllyDbg20Hex32Dec)。CommandBar45E45,會(huì)發(fā)現(xiàn)它確實(shí)就是大寫(xiě)字母E的十六進(jìn)制值。ASCIIASCII 數(shù)據(jù),這些數(shù)據(jù)稍后不久就要恢復(fù)取出。就像在桌上放一疊信件或紙牌,的信件或紙牌 這是堆棧的主要性質(zhì),放在頂部的信件總會(huì)被最先取走。以后學(xué)習(xí)OllyDbg的堆棧怎樣工作。好的,我認(rèn)為這次的課程應(yīng)該結(jié)束了。在第三章,學(xué)習(xí)寄存器,標(biāo)志以及它們的意義。譯注2CrackMe1.CrackMe:ollydbg01-該系列目前已更新到第47章。本文原文為俄語(yǔ),譯者不才,斗膽翻譯,采用了能用的所有。雖經(jīng)本人嚴(yán)加審校,但難免訛誤。有些詞句加入了譯者的理解,所以部分內(nèi)容可能與原文有所出入。翻譯本文也是譯者學(xué)習(xí)的過(guò)程,所以錯(cuò)誤在所難免。該系列本文原文本文原 :[C]РикардоНарваха,пер.譯

存器的一個(gè)例子(1)ESPCrueHead'aCrackMe(2)ESP12FFC4OllyDbg–CrackMe401000如果你按下F7現(xiàn)在為住OllyDbg在哪里顯示這些寄存器。它們都被稱(chēng)為32位寄存器。在OllyDbg中,它們的內(nèi)容以十六進(jìn)制顯示。例如,EAX的最小值為 ,最大值為FFFFFFFF,用二進(jìn)制表示將是320132位的。你可以在匯編語(yǔ)言中查閱參考這些32位寄存器?,F(xiàn)在,在OllyDbgOllyDbgCrackMe(也可以加載其它的程序)EAX在打開(kāi)的窗口的Hexdecimal處填 OK現(xiàn)在EAX寄存器的一部分,在這個(gè)例子中,AXEAX16,我們?cè)??AX(問(wèn)號(hào)也可用于查詢(xún)寄存器的值5678,AXEAX4ALAH(譯注:16AX的低八位和高八位),它們的值在OllyDbg中同樣能夠觀(guān)察到?;蛘哌@樣更直觀(guān),如果EAX ,那么AX就是它的后四位數(shù)字AH56的組合,AL同樣的,EBXBX,BLBH。幾乎所有其它寄存器都可以如此分割(3)我們已經(jīng)看到了,OllyDbgEAX你想要更改的,然后它選擇Modify。但EIP是唯一一個(gè)例外的,它指向下一條將要執(zhí)行的指令。EIP40101ANeworiginhere(漢化版翻譯為:此處為新的EIP),EIP就會(huì)改變?yōu)?0101A,這樣,程序就將會(huì)從這條指令執(zhí)行。在這里你會(huì)看到,EIP40101A就像我們?cè)诘谝徽驴吹降?,在OllyDbgC,P,A,Z,S,T,DO01。某一具體指令的執(zhí)行可以O(shè)標(biāo)志(溢出標(biāo)志溢出標(biāo)志在當(dāng)操作改變了符號(hào)位,返回錯(cuò)誤值時(shí)被設(shè)置(4)OllyDbgCrueHead'aEAX7FFFFFFF現(xiàn)在使其加1,其和將超過(guò)最大正數(shù),我們還知道, 對(duì)應(yīng)的是一個(gè)負(fù)數(shù)。這需要打開(kāi)一個(gè)能夠?qū)懭胫噶畹目颍ㄗg 指令上按空格鍵,或在反匯編代碼那一列的指令上雙擊)。 ADDEAX,1EAX1EAXF7將完成這條指令,O在F7后,看看發(fā)生了什么,EAX變 O標(biāo)志被設(shè)置為1。A標(biāo)志(輔助進(jìn)位標(biāo)志P標(biāo)志(奇偶標(biāo)志如果指令的結(jié)果用二進(jìn)制表示,該二進(jìn)制數(shù)中的的1的總個(gè)數(shù)為偶數(shù)時(shí),P標(biāo)志被設(shè)置。例如 為做個(gè)試驗(yàn),我們已經(jīng)在OllyDbg中設(shè)置了指令:ADDEAX,1(譯注5),再一次執(zhí)行該操作。選擇401000行,選NeworginhereF7現(xiàn)在,EAX中包含的值為 ,P標(biāo)志等于1,(這里是先前指令的結(jié)果),讓我們看一下,當(dāng)向EAX中加入1時(shí)發(fā)生了我們看到,P0,EAX11再次返回,選擇ADDEAX,1這行,該行,選擇Neworiginhere,按F7,再次加1。我們看到,EAX1210,1的個(gè)數(shù)為奇數(shù),P標(biāo)志未被設(shè)置。重復(fù)上述操作,再加1,于以下事實(shí):當(dāng)指令結(jié)果的二進(jìn)制格式含有偶數(shù)個(gè)1時(shí),被設(shè)置。Z標(biāo)志(零標(biāo)志Cracking0下F7運(yùn)行指令A(yù)DDEAX,1使,結(jié)果為-1+1,等于0,零F7后,EAX00,Z1現(xiàn)在應(yīng)該清楚了,當(dāng)指令的結(jié)果為0S標(biāo)志(符號(hào)標(biāo)志1EAXFFFFFFF8-F7執(zhí)行指令,S1SC(無(wú)符號(hào)運(yùn)算的結(jié)果)在超過(guò)最大數(shù)值時(shí)設(shè)置,可能是寄存器的值,例如,將EAXFFFFFFFF1T,D我現(xiàn)在還不打算解釋它們的用途,這是一個(gè)相對(duì)復(fù)雜的話(huà)題。我們對(duì)它們也不太感。所以目前可以先著手相對(duì)更簡(jiǎn)單問(wèn)題,此如果看完本文后,你還存有疑惑,請(qǐng)用指令A(yù)DDEAX,1跟隨本文的操作(以改變標(biāo)志位的值)來(lái)進(jìn)行實(shí)踐。寄存器是CPU內(nèi)部的高速單元,速度比常規(guī)內(nèi)存快很多。譯注2此CrackMe譯注3EAX,EBX,ECX,EDX16位寄存器,但不能進(jìn)一步再分。譯注4標(biāo)志被設(shè)置,意思是說(shuō)使其等于1,被清除,則使其等于0。譯注5更改寄存器EAX 處改為ADDEAX,1CrackMe:ollydbg01-該系列目前已更新到第47章。本文原文為俄語(yǔ),譯者不才,斗膽翻譯,采用了能用的所有。雖經(jīng)本人嚴(yán)加審校, 該系列:http本文原文: :[C]РикардоНарваха,пер.Aquila譯 運(yùn)行這條指令不會(huì)對(duì)寄存器,內(nèi)存以及堆棧造成任何影響,英文單詞的意思是”無(wú)操作”,也就是說(shuō),它沒(méi)有特殊的用途。例如,你用一個(gè)短指令來(lái)替換一個(gè)長(zhǎng)指令的話(huà),如果處理器沒(méi)有錯(cuò)誤多余的空間將會(huì)被NOP填充。我們可以看到反匯編的源代碼,如上圖第一條指令是 0,占兩個(gè)字節(jié),在這條指令上面單擊鼠標(biāo)右鍵選擇.或者直接使用快捷鍵-空格鍵,在彈出窗口的編輯框中輸入NOP寫(xiě)入NOP指令后單擊Assembe現(xiàn)在,在原來(lái)PUSH0的地方顯示的兩條NOP指令,單擊F7,指令一條NOP指令,可以看到,這里只改變了E保存了下一條要執(zhí)行指令的地址)寄存器的值,并沒(méi)有影響到其他寄存器,堆?;蛘邩?biāo)志位。在數(shù)據(jù)窗口中,鼠標(biāo)右鍵選擇-“Goto”-“”,,在數(shù)據(jù)窗口或者反匯編窗口中, 在數(shù)據(jù)窗口中的話(huà),我們之前,堆棧就像一個(gè)信箱一樣,越頂部的信越先被取出來(lái)H按下F7,堆棧頂部我們可以看到加入了0。下面的12FFC4中仍然是7C816D4F,PUSHEAX的話(huà),那么堆棧的頂部將保存EAXPUSH]注意,PUSH(沒(méi)有方括號(hào)如果你使用的“PUSH8”那么堆棧中將被放置401008執(zhí)行以后,我們可以看到下面的結(jié)果如果換成是“PUSH”存元中的個(gè)候們?nèi)?jù)窗中看的是少。o:這節(jié)是CA204000。按F7執(zhí)行這條PUSH執(zhí)行堆棧中我們可以看到在數(shù)據(jù)窗口中顛倒過(guò)來(lái)的值,即,現(xiàn)在我們知道,O中 [410]”的意思了]像這樣的,除非有明確規(guī)定,否則OD都是認(rèn)為你要操作的是4個(gè)字節(jié)的內(nèi)存,也就是DWORDP以下是執(zhí)行此操作,堆棧變化情況的說(shuō)明ESP中存放的是F我們可以看到,原來(lái)堆棧頂部的值了,現(xiàn)在ESP為12FFC8同樣地,如果用戶(hù)是“POPECX”,那么上面的值將會(huì)到ECX我們這里就研究了入棧和出棧指令。PUSHAD指令把所有通用寄存器的內(nèi)容按一定順序壓入到堆棧中PSHA也就相當(dāng)于H,HH DPUSHBPSHSUSHEPUSH,PUSHE按下F7鍵,看看現(xiàn)在堆棧的情況看到所有寄存器的值都被壓入堆棧了。12FFC4存放的是之前堆棧頂部的值,然后上面就是PSHAXC存放的是ECX的內(nèi)容,接下來(lái)是EDX寄存器的內(nèi)容,該指令與PUSHAD正好相反,它從堆棧中取值,并將它們放到相應(yīng)的寄存器中。POPAD等價(jià)于“POPEPOPPOPEPOP PPPP:因?yàn)橹皥?zhí)行了PUSA,:PUSHA等價(jià)于H,,,,,, ,D'。POPA等價(jià)于'p,,,,,,, US,PP和PSHAPPD就像姐妹一樣,只不過(guò)它們?cè)?6位程序中使用,所以我們不感,OyD是一個(gè)32位程序的調(diào)試器MOVEA兩個(gè)寄存器的值是不一樣的,我們只是看寄存器在我的機(jī)器上EX為B為7FFD7000。這些初始值有可能與你機(jī)器上的不一樣,我們只是看賦值的過(guò)程,按F7鍵B的值就賦值給了EAX明白了嗎MOVAL,寄存器賦值給和的其他內(nèi)容即的最后兩位數(shù)字。也o. ,按下F7鍵,看看會(huì)發(fā)生什么這里是1000,是從內(nèi)存中出來(lái)的?,F(xiàn)在,如果我們想寫(xiě)一個(gè)值到這個(gè)地址X:然后,按F7鍵發(fā)生異常注意異的描述是由我們要入這內(nèi)存地導(dǎo)致內(nèi)存異常。如果移動(dòng)的是4個(gè)字節(jié)使用DWORD,移動(dòng)兩個(gè)字節(jié)的話(huà)使用WORD。例如D].按F7賦值給AX的只有兩個(gè)字節(jié)。如下,]這種情況下,只有最后一個(gè)字節(jié)賦值給AL了,即08MOVSX帶符號(hào)擴(kuò)展的傳送指令第二個(gè)操作數(shù)可能一個(gè)寄存器也可能是內(nèi)存單元,第一個(gè)操作數(shù)的位數(shù)比第二個(gè)操作數(shù)多,同時(shí)可以看到,EAX的值為0,所以這些東西總是可以幫助我們理解OD要執(zhí)行的指令(我希望你已經(jīng)掌握了其中的概念和尋址方式,嘿嘿)。按鍵。看到B中存放的是F000,并且EAX剩余部分填充為了FF因?yàn)镕000是一個(gè)負(fù)的16位數(shù)字。如果BX存放1234,EAX將等 AX被賦值為了,其余部分被填充為0了-因?yàn)?FFF是正數(shù)。我們還可以把BX修改為8000(負(fù))MOVZX帶0擴(kuò)展的傳送指令MOVZX類(lèi)似于前面的語(yǔ)句,但是這種情況下,剩余的部分不根據(jù)第二個(gè)操作數(shù)的正負(fù)來(lái)進(jìn)行填充。我們這里不提供范例,因?yàn)楹蜕厦媸窍嗨频?剩余的部分總是被填充為0LEA取地址指令類(lèi)似于MOV指令,,OD中寫(xiě)入以下指令:在這種情況下,有括號(hào),但不需要獲取ECX+38指向內(nèi)存的值,只需要計(jì)算ECX+38的值即可。我這里EX在這個(gè)例子中LE指令就計(jì)算ECX+38的值,然后將計(jì)算的結(jié)果賦值給EAX。它表示,該操作數(shù)是12FFE8,也就是ECX+38的值,并且EAX的值為0。按鍵。,XCHG/該指令交換兩個(gè)操作數(shù)的值,例如XCHG在我的機(jī)器上EX的值為X的值為12FFB0按F7鍵,你也可以使用這個(gè)指令來(lái)交換寄存器和內(nèi)存單元的值,按下F7鍵這個(gè)例子我們?cè)贛OV指令使用過(guò),oydbg01-按F7鍵,執(zhí)行指令DECEAX,EAX將會(huì)由1變成0反過(guò)來(lái),就會(huì) ADD指令有兩個(gè)操作數(shù),相加后的結(jié)果存放到第一個(gè)操作數(shù)中。ADDEAX,1等價(jià)于INCEAXADD也將兩個(gè)寄存器相加,我們可以執(zhí)行該語(yǔ)句之前 變。因?yàn)椴⒉粫?huì)異常。在這種情況下,結(jié)果存放到405000內(nèi)存單元中,按下F7鍵,由于我們對(duì)該內(nèi)存單元沒(méi)有寫(xiě)權(quán)限,當(dāng)嘗試修改該內(nèi)存單元的值時(shí)候,發(fā)異在這種情況下,兩個(gè)操作數(shù)的和加上進(jìn)位標(biāo)志的值,我們通過(guò)修改進(jìn)位標(biāo)志,我們可以看到十進(jìn)制為-2另外也可以使用該指令來(lái)計(jì)算寄存器的值來(lái)寄存器的值,SUBEAX,SUBEAX,DWORDPTRSUBDWORDPTR這種情況下,由于我們對(duì)405000這個(gè)內(nèi)存單元沒(méi)有寫(xiě)權(quán)限,將結(jié)果存放到其中的話(huà),會(huì)一個(gè)異常MUL結(jié)果為下面的情況MULDWORDPTR IMULECX兩個(gè)數(shù),并且保存相乘的結(jié)果,結(jié)果必須保存在寄存器中。下面看到兩個(gè)和三個(gè)操作數(shù)的例子。F7EB EAXxEBX-> FFIMULEBP,DWORDPTR[ESI+74],FF800002[ESI+74]xFF800002->這是第二個(gè)例子,其中有三個(gè)操作數(shù):ESI+74內(nèi)存單元的值乘以FF800002,并且將結(jié)果到EBP中。我們可以在OD中執(zhí)行看看。把IMULEBP,DWORDPTR[ESI+74],FF800002拷貝到OD中。為了確保能夠ESI+74這個(gè)地址的值,ESI的值修改為401000見(jiàn)注釋這里表示 的值 這里 是指 IMULEBP,DWORDPTR[ESI+74],在計(jì)算器中我們計(jì)算 IMULEDX,DWORDPTR[EBP- EDXx[EBP-18]->指令經(jīng)常被使用。如果是一個(gè)操作數(shù)的話(huà)那么它和類(lèi)似只不過(guò)操作數(shù)是有符號(hào)的結(jié)果依然保存在EDX:EX中。兩個(gè)操作數(shù)的情況第一個(gè)操作數(shù)除以第二個(gè)操作數(shù),結(jié)果存放到第一個(gè)操作數(shù)中。三個(gè)操作數(shù)的情況第二個(gè)操作數(shù)除以第三個(gè)操作數(shù)結(jié)果存放到第一個(gè)操作數(shù)中。XADD在OD中寫(xiě)入NEGEAX指令,并將EAX的值改為32邏輯指令有兩個(gè)操作數(shù),兩操作數(shù)按位運(yùn)算, 按下F7鍵,看到ECX的值 1or1=1or0=0or1=0or0=1xor1=0xor0=例如:not0110例如:EAX=1200,其二進(jìn)制位1001000000000,其填充為32位,不足的時(shí)候補(bǔ)0NOT這里我們第5章就結(jié)束了,下一章介紹比較,跳轉(zhuǎn),函數(shù)調(diào)用,以及函數(shù)返回指令。附件接下來(lái),詳細(xì)介紹比較和跳轉(zhuǎn)指令我們知道,某些指令的指令會(huì)影響到標(biāo)志位,最常見(jiàn)的就是零標(biāo)志位Z寫(xiě)入CMPEAX,ECX指令并修改EAX和ECX如果有兩個(gè)序列號(hào)做比較,例如EAXEC存放的是正確的序列號(hào),該程序使用CM指令來(lái)比較,如果相零1,后面指就會(huì)跳轉(zhuǎn)到成功的部分。如果不等于EC的話(huà),那么零標(biāo)志位就會(huì)置0,那么就不會(huì)跳轉(zhuǎn)到成功的部分。重新寫(xiě)入CMPEAX,ECX指令,但是現(xiàn)在要求是EAX的值要大于ECX依然是CMPEAX,ECX指令,但這次是EAX小于ECX CMPAX,WORDPTR和CMPAL,BYTEPTR下面有幾個(gè)例子TEST與操作的表如下1and1=1and0=我們看到,零標(biāo)志位被置1了,兩個(gè)0做與操作,結(jié)果為0,所以零標(biāo)志位被置1如果EAX改為非零值,然后重復(fù)上面的操作呢零標(biāo)志位沒(méi)有被置1的話(huà),就說(shuō)明結(jié)果不等于0如果你使用計(jì)算器的話(huà),可以計(jì)算出390AND390結(jié)果依然是390,二進(jìn)制 JMPJNSJP,JPE–結(jié)果中1的個(gè)數(shù)為偶數(shù)則跳轉(zhuǎn)JO–結(jié)果溢出了則跳轉(zhuǎn)JNOJBJNAE–小于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù))JNBE,JA–大于則跳轉(zhuǎn)(無(wú)符號(hào)數(shù))JL,JNGE–小于則跳轉(zhuǎn)(有符號(hào)數(shù))JNLE,JG–大于則跳轉(zhuǎn)(有符號(hào)數(shù))進(jìn)入OPTIONS-DEBUGGING切換到CPU將3這兩個(gè)條件跳轉(zhuǎn)指令是等價(jià)的,只是書(shū)寫(xiě)的形式不同而已。我們可以看到零標(biāo)志位Z被置1我們來(lái)這個(gè)條件跳轉(zhuǎn)JNP或進(jìn)位/借位標(biāo)志位置1,當(dāng)兩個(gè)操作數(shù)的差值為負(fù)的時(shí)候,該標(biāo)志位將被置1,這里可以得出EAX小于ECX在這種情況下進(jìn)位/借位標(biāo)志位置1,因?yàn)榻Y(jié)果是負(fù)的,也就是說(shuō)EAX小于ECX。(此表由于是,就不翻譯了在任意一行點(diǎn)擊鼠標(biāo)右鍵選擇-“Goto”-“Expression在彈出的框中輸入401245 針對(duì)于指令D提供了一些有用的機(jī)制。如果想繼續(xù)跟進(jìn)子程序內(nèi)部你可以按7鍵跟進(jìn)。如果只是想先看看子程序里面的內(nèi)容再?zèng)Q定要不要跟進(jìn)的話(huà),可以單擊鼠標(biāo)右鍵”。最后,如果我們不想繼續(xù)該子程序了我們可以按下8鍵繼續(xù)執(zhí)行OD允許我們看我們感的子程序里面的內(nèi)容,但是不執(zhí)行,只需要在call指令上面單擊鼠標(biāo)右鍵選擇“Follow”我們繼續(xù)按F7鍵,執(zhí)行push0指令,看看這個(gè)0是不是壓入堆棧中并且存放到返回地址的上面了。頂存放的一般是子程序的返回地址。按F8不跟進(jìn)call指令里面,直到遇到了ret指令停止PUSH401256以轉(zhuǎn)移到401256地址處。這段代碼和JMP401256指令的功能是一樣的。出現(xiàn)了下面的窗口,隨便填我們處于程序的代碼中間,這里我們看到幾個(gè)RETURNTO指令。顯然,這些是我們?cè)诔绦蛑斜4娴姆祷氐刂?。我們現(xiàn)在在40124A這行按下回車(chē)鍵?,F(xiàn)在來(lái)看看另外一個(gè)例子。重新載入CrackMe,按下空格鍵,輸入一條指令:Call401245這個(gè)子程序起始于401245,到401288地址處結(jié)束(其中retn10指令跟我們熟悉ret指令略有不同,稍后詳細(xì)說(shuō)明)。注意嵌套調(diào)用(這個(gè)子這確實(shí)是一個(gè)返回地址,但是OD沒(méi)有以紅色顯示RETURNTO401005。要弄明白為什么這一次OD沒(méi)有以紅色顯示返回信息,我們回因?yàn)槲覀円呀?jīng)讓OD了 ysis”- ysecode” 點(diǎn)+5=401000+5=401005一般情況下,在改變程序代碼后了重新分析代碼。有的時(shí)候,代碼分析可能是錯(cuò)的,這個(gè)時(shí)候應(yīng)該選擇“ ysisfrommodule”。查看一下堆棧DEC該計(jì)數(shù)器每次遞減1其實(shí)就是循環(huán)體了,最后,你需要添加一個(gè)判斷計(jì)數(shù)器是否為0CMPJNEADDECX,15hTESTJNE然后繼續(xù)按F7鍵,直到DECECX,這個(gè)時(shí)候我們的計(jì)數(shù)器的值將減少至14h繼續(xù)F7單步直到TESTECX,ECX。該指令判斷ECX是否為0,為0零標(biāo)志位Z就置1,這樣就停止循環(huán), 地址處。下一步計(jì)數(shù)器繼續(xù)遞減,這一次減少見(jiàn)到灰色箭頭,意味著什么?-這里意味著跳轉(zhuǎn)不會(huì)發(fā)生。按F7鍵跳出循環(huán)繼續(xù)執(zhí)行下面的代碼LOOP指令可以幫我們完成前面例子中的事情將計(jì)數(shù)器ECX的值減1,判斷ECX的值是否為0,如果為0就跳轉(zhuǎn)到指定的地址-將像前面指令用一條LOOP401007指令替代。第一行突出顯示(401000)-單擊鼠標(biāo)右鍵選擇-Neworiginhere?,F(xiàn)在我們來(lái)執(zhí)行新的LOOP按F7鍵,再次看到計(jì)數(shù)器ECX首先被初始化為0了,然后又被設(shè)置為15h了。我們繼續(xù)單步,直到LOOP指令繼續(xù)單步。當(dāng)計(jì)數(shù)器為0時(shí),循環(huán)將結(jié)束LOOPZ,LOOPE重復(fù)循環(huán),直到零標(biāo)志位Z置1LOOPNZ,LOOPNE重復(fù)循環(huán),直到零標(biāo)志位Z清0下面,數(shù)?,F(xiàn)在我們?cè)贠D中寫(xiě)入MOVSDWORDPTRES:[EDI],DWORDPTRDS:[ESI]指令,樣子如下:在拷貝內(nèi)容之前,你可以在數(shù)據(jù)窗口中,單擊鼠標(biāo)右鍵選擇-Goto-Expression,然后輸入地址40366C。還有一個(gè)更加簡(jiǎn)單的方法:鼠標(biāo)右鍵選擇-FollowinDump-Immediateconstant,如下圖所示 源地址現(xiàn)在是40365C(說(shuō)明),目的地址和之前的一樣,是40369C。我們來(lái)到第一條指令處,單步到REPMOVS指令處請(qǐng)記住,MOVS指令不能將數(shù)據(jù)拷貝到?jīng)]有寫(xiě)入權(quán)限的內(nèi)存單元中,強(qiáng)制寫(xiě)入的話(huà)會(huì)異常當(dāng)循環(huán)執(zhí)行REPLODS指令時(shí),解釋窗口中會(huì)提示ECX的值,以及ESI指向的內(nèi)存單元中下一次將被拷貝到EAX我們單步直到執(zhí)行完STOS指令,在解釋窗口我們可以看到當(dāng)前EAX的值以及當(dāng)前EDI指向內(nèi)存單元中的值我們?cè)贠D中輸入CMPSDWORDPTRESI],DWORDPTREDI],OD中將顯示為CMPSDWORDPTRDS:[ESI],DWORDPTR解釋窗口中會(huì)提示要比較的值我們已經(jīng)介紹了很多有用的指令,但是浮點(diǎn)運(yùn)算指令我們還沒(méi)有介紹,在后面討論。大家需要重復(fù)練習(xí)前面介紹的內(nèi)容,直到大家MOVDWORDPTR[ MOVAX,WORDPTR[00510A25]MOVAL,BYTEPTR[ CALL452200JMPCALLEAXJMP[EBX+要想在指令執(zhí)行之前看到址,需要在該指令上下斷點(diǎn),斷下來(lái)以后查看寄存器的值或者查看解釋窗口中的提示信息這里我們來(lái)看一看間接尋址的例子:PUSHEBP 點(diǎn),在執(zhí)行PUSH[EBP+8]指令之前我們并不能預(yù)先直到EBP寄存器的值,我們?cè)谠撝噶钐?4010E9)按現(xiàn)在讓我們?cè)跀?shù)據(jù)窗口中看看EBP+8指向內(nèi)存單元的值,在數(shù)據(jù)窗口中單擊鼠標(biāo)右鍵選擇-Goto-Expression,輸入第九章我們會(huì)將基礎(chǔ)知識(shí)運(yùn)用到中去。本章開(kāi)始。我們先從基本的概念開(kāi)始一步步的來(lái)介紹所需要的步驟讓我們用調(diào)試器開(kāi)始之旅吧通過(guò)這個(gè)CrackMe點(diǎn):程序剛剛被加載第一條指令的地址。為了不和OEP(原始點(diǎn))相,我們稍后再來(lái)介紹OEP的概念。當(dāng)用OD加載應(yīng)用程序后,調(diào)試器就會(huì)停在點(diǎn)處,分析代碼并且等待用戶(hù)的進(jìn)一步提示。接下來(lái),讓我們來(lái)了解一下DLL(動(dòng)態(tài)庫(kù))的概念以及DLL導(dǎo)出函數(shù)的功能注意一下突出顯示的部分,舉個(gè)例子,比如我們要調(diào)用401020或者要跳轉(zhuǎn)到421367,CALL在最右邊的列中顯示了一些額外的信息,調(diào)用的是LoadIconA作系謂態(tài)(文正文同態(tài)出函DDLL中。如果一個(gè)功能的代碼量很大,那么這樣就可以縮減可執(zhí)行文件的大小,更重要的是可以節(jié)省內(nèi)存。Windows的基本功能:文件,內(nèi)存,進(jìn)程,線(xiàn)程,圖形,聲是態(tài)現(xiàn)。oA.l個(gè)應(yīng)??谝卜Q(chēng)之為API。讓我們來(lái)看看另一個(gè)APIMessageBoxA的例子。在命令欄中輸入:?MessageBoxA有個(gè)簡(jiǎn)單的提示,該函數(shù)的地址是77D504EA。我們單擊鼠標(biāo)右鍵選擇-Goto-Expression如果你是windows9x可以看到該函數(shù)屬于USER32.DLL,通常在調(diào)試器中顯示的函數(shù)名稱(chēng)前面會(huì)有DLL的名稱(chēng)(例如CallUSER32.MessageBoxA)。從當(dāng)前地址開(kāi)始到函數(shù)返回實(shí)現(xiàn)了MessageBoxA的功能。MessageBoxA便于我們的識(shí)別,但并不是機(jī)器碼,給者提供了一定的幫助。按減號(hào)-回到點(diǎn)。單擊鼠標(biāo)右鍵:選擇Searchfor-Name(label)incurrentmoduleCtrl+N菜單項(xiàng)。獲取該CakM的PI查找我們關(guān)注的API函數(shù)的話(huà),不需要一個(gè)個(gè)去看,只需要輸入API函數(shù)的名稱(chēng)即可。這里我們按M光標(biāo)定位到第一個(gè)函數(shù)名稱(chēng)以M開(kāi)始的API選擇FollowimportinDisassembler選項(xiàng),我們就可以轉(zhuǎn)到API函數(shù)的實(shí)現(xiàn)處。這也是另一種轉(zhuǎn)到API在這里新手普遍會(huì)犯一個(gè)錯(cuò)誤,現(xiàn)在單擊鼠標(biāo)右鍵選擇-Searchfor-Nae(label)inurrentmodue稱(chēng)是RLL庫(kù)中的函數(shù)名稱(chēng),并不是我們的Me主程序的導(dǎo)入表中的函數(shù)名。菜單項(xiàng)中明確是搜索當(dāng)前模塊,我們現(xiàn)在這種情況,當(dāng)前模塊是USR3Mssgeo是位于該模塊當(dāng)中的。WindowsNT:2000,XP或者這里我們的討論的是windowsNT/2000和XP,2003。對(duì)于NT系列的操作系統(tǒng)來(lái)說(shuō),OD是非常好用的。如果你是95/98系統(tǒng)的話(huà),你也可以參考附錄部分(windows9x的說(shuō)明).我們?cè)贑rackMe的API列表中單擊鼠標(biāo)右鍵選擇-Togglebreakpointonimport菜單項(xiàng)來(lái)給當(dāng)前選中的函數(shù)設(shè)置斷點(diǎn)。bpBP是在指定的函數(shù)的第一條指令處設(shè)置斷點(diǎn)。而不是在函數(shù)的調(diào)用處。我們可以來(lái)到MessageBoxA現(xiàn)在我們按下F9運(yùn)行CrackMe出現(xiàn)了CrackMe的主窗口。在菜單中選擇help-隨便輸入一個(gè)名詞和序列號(hào),然后單擊確定。這個(gè)時(shí)候MessageBoxA提示說(shuō):”中斷在USER32.MessageBoxA處”,這意味著USER32.MessageBoxA消息文本是:“Noluckthere,mate!”。由于我們輸入的用戶(hù)名和序列號(hào)不正確。所以即將彈出失敗的消息框?yàn)榱俗C明會(huì)彈出消息框,我們?cè)谙路降腞ETN10處設(shè)置斷點(diǎn)。我們對(duì)應(yīng)的地址可能不一樣。但是無(wú)論如何,第一個(gè)RET處就按F9消息框彈了出來(lái)。標(biāo)題文本為Noluck!,文本內(nèi)容為Noluckthere,mate!。表明輸入的用戶(hù)名或者序列號(hào)不正確。單擊”是”-觸發(fā)RETN10處的斷點(diǎn)。這里RETN10跟通常的RETN有點(diǎn)差別。通常的RET只是返回到4013C1返回以后,返回地址從堆棧中刪除。堆棧指針向下移動(dòng)4字節(jié)(更確切的說(shuō)是向高地址一側(cè))。對(duì)于RET10H來(lái)說(shuō),除了完成RET的操作之外,ESP還要增加10h。所以,ESP的增量為10h+4h=14h=20,讓我們按F7鍵看看?,F(xiàn)在CrackMe已經(jīng)知道了序列號(hào)不正確,我們按F9斷點(diǎn)再次觸發(fā)。CrackMe返回地址是40137D。讓我們來(lái)看看該地址處的代碼。單擊鼠標(biāo)右鍵選擇-FollowinDisassembler或者Goto-Expression輸來(lái)到了40137D處,上面是一個(gè)CALL指令,調(diào)用MessageBox(401378可以看到上面還有一個(gè)MessageBox,但是提示的是”Greatwork,mate!Nowtrythenext初步分析調(diào)試器顯示的代碼是函數(shù)的一部分,一個(gè)功能開(kāi)始于401362彈出Noluck的消息框。另一個(gè)功能開(kāi)始于40134D彈出Good如果突出顯示該函數(shù)的第一行(地址401362)調(diào)試器提示調(diào)用來(lái)至于401245,單擊鼠標(biāo)右鍵選擇-Goto-CALLfrom401245這里是典型的比較代碼:一個(gè)分支是Noluck!,另一個(gè)分支是Greatwork同時(shí)取消MessageBox處的斷點(diǎn)。這里我們可以單擊調(diào)試器窗口中的B按鈕,即顯示斷點(diǎn)窗口單擊鼠標(biāo)右鍵選擇-Remove。刪除兩個(gè)調(diào)用MessageBox的斷點(diǎn),只留下401243我們F9運(yùn)行起來(lái),彈出Noluck消息框,剛才我們已經(jīng)過(guò)一次了。單擊確定關(guān)閉消息框,然后繼續(xù)打開(kāi)窗口,輸入名稱(chēng)和序列單擊OK跳轉(zhuǎn)不會(huì)發(fā)生,因?yàn)镋AX和EBX的值不相等。因此CALL401362彈出Noluck消息框,如果你忘記了??梢詥螕羰髽?biāo)右鍵-Expression來(lái)到401362但是如果我們修改零標(biāo)志位Z的值呢?將ZZ標(biāo)志位為1表示EAX=EBX。即EAX與EBX按F9因此,比較是驗(yàn)證序列號(hào)的一個(gè)關(guān)鍵點(diǎn)。如果EAX和EBX的值相等則彈出Greatwork消息框,否則彈出Noluck消息框。我們注意到代碼中有兩處Noluck的消息框提示,只有一個(gè)是最后一次的提示。CrackMe當(dāng)名稱(chēng)中包含數(shù)字的時(shí)候會(huì)提示Noluck消息框,當(dāng)序列號(hào)錯(cuò)誤的時(shí)候還會(huì)提示Noluck消息框。輸入包含數(shù)字的名稱(chēng)。單擊OKF9返回地址為4013C1OD的分析顯示該子過(guò)程開(kāi)始于40137E,結(jié)束于4013C1。調(diào)用MessageBox請(qǐng)注意,4013AC的箭頭(’現(xiàn)在我們面對(duì)的是的比較和條件跳轉(zhuǎn)指令,可以導(dǎo)致彈出Noluck消息框。我們?cè)谶@里設(shè)置斷點(diǎn)這里的代碼會(huì)循環(huán)檢測(cè)用戶(hù)名的所有字母。一旦用戶(hù)名中包含數(shù)字的話(huà),就會(huì)跳轉(zhuǎn)到Noluck消息框處。每檢測(cè)一個(gè)字母,就會(huì)中斷 JB條件跳轉(zhuǎn)是根據(jù)進(jìn)位標(biāo)志位C來(lái)決定是否跳轉(zhuǎn)的,我們通過(guò)雙擊C接下來(lái)我依然要來(lái)比較EAX和EBX的值,向之前一樣通過(guò)修改零標(biāo)志位Z按F9這次我們不改變進(jìn)位標(biāo)志位C,而是直接簡(jiǎn)單的把該指令填NOP。在該指令上單擊鼠標(biāo)右鍵選擇-Assemble輸入NOP可以將斷點(diǎn)去掉了,只需要按下F2這里我們需要跳轉(zhuǎn)始終成立,所以JE改成JMP然后還是按F2刪除斷點(diǎn)。然后按F9在反匯編窗口的任意位置單擊鼠標(biāo)右鍵選擇-Copytoexecutable-Allmodifications選擇Copyall彈出一個(gè)新窗口,再次單擊鼠標(biāo)右鍵選擇-SaveFile這時(shí)候,我們可以關(guān)閉OD我們雙擊打開(kāi)我們CRACKME2選擇-help-Register單擊OK(下面的一個(gè)點(diǎn)點(diǎn)內(nèi)容是針對(duì)于windows9x系列系統(tǒng)的,考慮到windows9x已經(jīng)淘汰很久了。連XP系統(tǒng)前不久都已經(jīng)退役了。這里就 我們來(lái)看看斷點(diǎn)列表剛剛設(shè)置的斷點(diǎn),Editcondition:給斷點(diǎn)設(shè)置觸發(fā)條件,我們后面再來(lái)討論。Followindisassembler:Disableallorenableall:禁用/啟用列表中的全部斷點(diǎn)。這里沒(méi)有啟用的選項(xiàng),因?yàn)榱斜碇形ㄒ坏臄帱c(diǎn)沒(méi)有被禁用。CopytoClipboard:把選中斷點(diǎn)的信息到剪貼板。我們來(lái)實(shí)驗(yàn)一下。Breakpoints,item0Disassembly=OREAX,EAX暫停的原因如下單擊鼠標(biāo)右鍵選擇-FollowinDump-Selection我們初看一下數(shù)據(jù)窗口中的內(nèi)容和反匯編代碼中代碼是一樣的數(shù)據(jù)窗口和反匯編代碼中我們看到的都是0BC0,對(duì)應(yīng)的是OREAX,EAX。似乎代碼沒(méi)有什么變化,但是真的沒(méi)有變化嗎OREAX,EAX對(duì)應(yīng)的機(jī)器代碼出來(lái)然后寫(xiě)到別處在數(shù)據(jù)窗口中和提示框中顯示的都是相同的內(nèi)容:0BC0。但是,我們按下F7鍵看看EAX讀出來(lái)的4118處的內(nèi)容并不是D剛剛顯示的0BC0740(小端按雙字取出來(lái)是014C00而現(xiàn)在顯示的是014C0C,因此401018處字節(jié)值是CC。當(dāng)我們?cè)O(shè)置斷點(diǎn)后D會(huì)將對(duì)應(yīng)指令處第一個(gè)字節(jié)指令替換成CC。但是為了不影響界面顯示效果會(huì)我存中出容反方點(diǎn)我們?cè)O(shè)置的斷點(diǎn)有時(shí)候莫名其妙的了不要感到奇怪,或許說(shuō)這是調(diào)試器的本身的弱點(diǎn)吧。除BP還有一個(gè)比BP更加強(qiáng)大令BPX可以給或者調(diào)用了指定API函數(shù)的指令都下斷點(diǎn)還有一種設(shè)置斷點(diǎn)的方法:在反匯編窗口中你想設(shè)置斷點(diǎn)的那一行雙擊機(jī)器碼即可。如果想刪除的話(huà),內(nèi)存斷點(diǎn)有時(shí)候也稱(chēng)之為BPM,但是不要與SoftIce中的BPM弄了,這二者是完全不同的 我們?cè)?020CA處設(shè)置4個(gè)字節(jié)的內(nèi)存斷點(diǎn)。當(dāng)前有指令嘗試這幾個(gè)字節(jié)的時(shí)候,就會(huì)中斷下來(lái) 下面狀態(tài)欄清楚了描述了暫停的原因異常,OD會(huì)到這個(gè)異常,并中斷下來(lái),我們看到斷下來(lái)的時(shí)候,OD已經(jīng)將內(nèi)存頁(yè)的屬性設(shè)置正常了。400000h的值成功寫(xiě)入。我們運(yùn)行起來(lái),由于內(nèi)存斷點(diǎn)仍然存在,如果程序嘗試4020CA內(nèi)存單元的話(huà),會(huì)再次觸發(fā)異常正如你看到的,該指令嘗試4020CA內(nèi)存單元的內(nèi)容,證明內(nèi)存斷點(diǎn)又觸發(fā)了 “Memory,onaccess”是內(nèi)存斷點(diǎn)(讀或者寫(xiě)),“Memory,onwrite”是內(nèi)存寫(xiě)斷點(diǎn)OD也可以對(duì)區(qū)段設(shè)置內(nèi)存斷點(diǎn),我們選擇菜單項(xiàng)View-Memory,也可以按中的[M]按鈕打開(kāi)內(nèi)存窗口在選中部分上單擊鼠標(biāo)右鍵選擇-SetMemorybreakpointonaccess下面還有Setmemorybreakpointonwrite的選項(xiàng),但是這里我們選擇Setmemorybreakpointonaccess因?yàn)樵噲D執(zhí)行401002處的代碼,而當(dāng)前代碼段設(shè)置了內(nèi)存斷點(diǎn),嘗試執(zhí)行當(dāng)前代碼段的任何一條指令都會(huì)觸發(fā)內(nèi)存斷點(diǎn)我們對(duì)kernel32的代碼段設(shè)置內(nèi)存斷點(diǎn),列表的下面可以找到我們選擇-Setmemorybreakpointonaccess,當(dāng)試圖/寫(xiě)入/執(zhí)行Kernel32代碼段的時(shí)候就會(huì)中斷下來(lái),我們運(yùn)行起來(lái)在返回地址上單擊鼠標(biāo)右鍵選擇-FollowinDisassembler 這里Executetillusercode起作用了,此外,如果程序會(huì)檢測(cè)函數(shù)首字節(jié)是否為0xCC的話(huà),這個(gè)時(shí)候我們使用bpMessageBoxA命令下斷點(diǎn)就無(wú)效了,這個(gè)時(shí)候我們可以嘗試第一條指令被高亮顯示下一章,介紹硬件斷點(diǎn)和消息斷點(diǎn),條件斷點(diǎn)我們會(huì)在后面介紹面把剩下的類(lèi)型的斷點(diǎn)介紹完,本章先介紹硬件斷點(diǎn)和條件斷點(diǎn)。硬件斷點(diǎn)分為:硬件執(zhí)行斷點(diǎn)(ONEXECUTION),硬件寫(xiě)入斷點(diǎn)(ONWRITE),硬件斷點(diǎn)(ONACCESS)3種也可以在命令欄中輸入 在401000這一行單擊鼠標(biāo)右鍵選擇-Neworiginhere將EIP修改為401000,接著按F7單擊Delete按鈕將其刪除,然后給MessageBoxAAPI注意前4接下來(lái)我們選擇后面的1個(gè)字節(jié),單擊鼠標(biāo)右鍵選擇-Hardware,onaccess,可以看到只有1回到4020CA處,單擊鼠標(biāo)右鍵選擇-Hardware,onaccess-Byte。我們可以看到硬件斷點(diǎn)窗口中顯示的硬件斷點(diǎn)長(zhǎng)度為1個(gè)字節(jié)我們來(lái)看一個(gè)例子舉個(gè)例子,如果你想當(dāng)前EAX等于400000的時(shí)候,程序中斷下來(lái),那么條件應(yīng)該寫(xiě)成:“EAX400000選擇超Breakpoints,緊接著選擇超expression條件記錄斷點(diǎn)跟剛剛介紹的條件斷點(diǎn)差不多區(qū)別在于我們可以通過(guò)設(shè)置該斷點(diǎn)來(lái)記錄下設(shè)置的條件的精確值。我們舉個(gè)例子我們給一個(gè)函數(shù)設(shè)置條件記錄斷點(diǎn)程序中有很多地方調(diào)用了這個(gè)函數(shù)通過(guò)該條件記錄斷點(diǎn)我們可以精確的記錄程序中每處調(diào)用該函數(shù)傳遞給它的內(nèi)容。在反匯編窗口中單擊鼠標(biāo)右鍵選擇-Goto-Expression轉(zhuǎn)到MessageBoxA函數(shù)的這里我們只是記錄下我們關(guān)心的數(shù)據(jù),我們單擊中【L】按鈕打開(kāi)日志窗口我們單擊鼠標(biāo)右鍵選擇-Clearwindow如果需要想將日志保存到文件的話(huà),我們選擇Logtofile 如果程序中有大約100處調(diào)用了該API函數(shù),你可以指定相應(yīng)的條件,比如說(shuō)返回地址。設(shè)置條件為[ESP]40137D,那么這100個(gè)函行程序打開(kāi)窗口輸入用戶(hù)名 好了,eeGe eGettingASimpleTheMessageUsingsandModelessStandardCreatingasimpleToolandStatusGraphicsDeviceBitmapsandDeviceContextsText,FontsandTools Appendices.SolutionstoCAPIvs..ResourcefiletheForger'sWin32APIProgramming,,,{;t ;}understandwhythingshappenthewaytheydo....andsoon.Messagesareusedtocommunicateprettymucheverythinginwindowsatleastonbasiclevels. Eachwindowsmessagemayhaveuptotwoparameters, mandm.Originally mwas16bitmeachmessageusesthemdifferently.ForexampletheWM_CLOSEmessagedoesn'tuseeither,andyoushouldignorethemboth.The mcontainstwovalues,IO( )isthenotificationmessage(ifapplicable)andO( )isthecontrolor mistheHWND(windowhandle)tothecontrolwhichsentthemessageorNULLifthemessagesisn'tfromacontrol.IO)andO)aremacrosdefinedbywindowsthatsingleoutthetwohighbytes(HighWord)ofamakingDWORD(orDoubleWord)a32bitvalue.).)theMessageQueueandreturnsimmediatly.ThatmeansoncethecalltostMs)isdonethemessagemayormaynothavebeenprocessedyet.Ms)sendsthemessagedirectlytothewindowanddoesnotreturnuntillthewindowhasfinishedprocessingit.Ifwewantedtocloseawindowwecouldsendit,,,;clickingonthe mandmarebothThisisbecause,asmentioned,theyaren'tusedfor)andthenuseM,ORyoucanusetmMs)whichcombinesthesteps.Yougive))LetssayyouwerebusyhandlingtheWMITmessageandsuddenlytheusertypesabunchofstuffonmessagequeue,whenmessagesarepostedtheyareaddedtothemessagequeueandwhenyouhandleThemessageloopcallstMs,whichlooksinyourmessagequeue.Ifthemessagequeueisemptyyourprogrambasicallystopsandwaitsforone(itBlocks).)processed,andthatithasfilledinthemembersoftheMSGstructurewepassedit.Itreturns0ifithits,,additionalprocessing,translatingvirtualkeymessagesintocharactermessages.Thisstepisactuallyoptional,butcertainthingswon'tworkifit'snotthere.Oncethat'sdonewepassthemessagetost essage().Whatst essage()doesiswindow.Itthencallsthatprocedure,sendingasparametersthehandleofthewindow,themessage, mand.them!Ifyouaren'thandlingthespecificmessage,youalmostalwayscallfc)whichwillOnceyouhavefinishedprocessingthemessage,yourwindowsprocedurereturns,t system,ineffectyoucallityourselfindirectlybycallingst essage().Ifyouwanted,youcoulduset)onthewindowhandlethatthemessageisdestinedfortolookupthewindow'sprocedureandcallitdirectly!,,,{Wcs.,s.ms,. ,sm;}Unicode/ANSItranslation,callingtimercallbacksandsoforththatthismethodwillnotaccountfor,andveryNoticethatweuseW)toretreivethewindowprocedureassociatedwiththewindow.Whydon'twejustcallourWc)directly?WellourmessageloopisresponsibleforALLofthewindowsinoursamewindowprocedure,thefirstparameter(thehandletothewindow)isusedto whichwindowthemessageisintendedfor.))FALSE(aka0),theloopwouldendandwewouldreachtheendofourM)thusexitingtheprogram.ThisisexactlywhatsQtMs) plishes.It cesaWMQTmessageintothequeue,andinsteadofreturningapositivevalue,tMs)fillsintheMsgstructureandreturns0.Atthispoint, ignoreit,orreturnitfromM)whichwillthenbeusedastheexitcodewhentheprocessterminates.)catchyououtatsomepoint...eventhoughGMs)isdefinedasreturningaBOOL,itcanreturnT(d).ofcodethatmayseemtowork,butwillnotprocesscertianconditionscorrectly:,,,GtMsM,,,0)==sinceasIjustmentioned,itworksfineaslongasGtMs)neverfails,whichwhenyourcodeiscorrectitwon't.HoweverIfailedtotakeintoconsiderationthatifyou'rereadingthis,yourcodeprobablywon'tbecorrectalotofthetime,andGtMs)willfailatsomepoint:)I'vegonethroughand,,,Ihopeyounowhaveabetterunderstandingofthewindowsmessageloop,ifnot,donotfear,thingswillCopyright?1998-2013, (tut...@).All 環(huán)也會(huì)用到其他的API函數(shù)。想要深入了解Windows的消息的話(huà),可以參考下面的中的”理解消息循環(huán)”(該的中文版見(jiàn)附讓我們來(lái)看一個(gè)簡(jiǎn)單的例子:用OD加載CrueHead`s的CrackMe在反匯編窗口中單擊鼠標(biāo)右鍵選擇-Search-Name(labelincurrentmodule我們?cè)诿顧谥惺褂肂PGetDlgItemTextA設(shè)置斷點(diǎn)可以看到該函數(shù)有一個(gè)參數(shù)是緩沖區(qū),所以,我們?cè)跀?shù)據(jù)窗口中定位到該緩沖區(qū),堆棧窗口中選中該緩沖區(qū)參數(shù),單擊鼠標(biāo)右鍵選擇-FollowinDump?;蛘咴跀?shù)據(jù)窗口中單擊現(xiàn)在緩沖區(qū)還是空的,我們通過(guò)選擇主菜單項(xiàng)Debug-Executetillreturn現(xiàn)在緩沖區(qū)中保存了我們?cè)诖翱谥休斎氲挠脩?hù)名我們依然選擇主菜單項(xiàng)Debug-Executetillreturn,整個(gè)過(guò)程想必很清楚了吧為了找到正確的序列號(hào)在程序獲取我們輸入數(shù)據(jù)(這里是用戶(hù)名和序列號(hào)的時(shí)候應(yīng)該讓其中斷下來(lái)。更進(jìn)函數(shù)來(lái)獲取編輯框中文本我們單擊中【B】按鈕刪除所有的普通CC斷點(diǎn)F9鍵將程序運(yùn)行起來(lái),打開(kāi)窗口輸入用戶(hù)名和序列號(hào),但是不要點(diǎn)確定單擊中的【W(wǎng)】按鈕打開(kāi)Windows窗口(并不會(huì)暫停程序,依然顯示的是運(yùn)行)我們?cè)谡业降拇翱谶@一行單擊鼠標(biāo)右鍵選擇-MessagebreakpointonClassProc在打開(kāi)的窗口中,我們展開(kāi)下拉列表選擇我們感的消息類(lèi)型如下及Pauseprogram(中斷程序),還要選中下面的LogWinProcarguments(記錄消息過(guò)程函數(shù)的參數(shù)值)。我們知道主程序的代碼是401000開(kāi)頭的這個(gè)區(qū)段,我們選中這個(gè)區(qū)段,單擊鼠標(biāo)右鍵選擇-Setmemorybreakpointonaccess不要清除內(nèi)存斷點(diǎn),我們按F9鍵運(yùn)行,我們發(fā)現(xiàn)單步執(zhí)行了一行,我們繼續(xù)F9單步 序列號(hào)代碼的附近。對(duì)不對(duì),我們?cè)僖淮味ㄎ坏搅宋覀兏械拇a,這一次我們并沒(méi)有直接給API下斷點(diǎn)。為了讓我們確定的時(shí)候,程序能斷下來(lái),我們單擊鼠標(biāo)右鍵選擇-Breakpoint-Removememorybreakpoint來(lái)刪除內(nèi)存斷點(diǎn)我們單擊中【B】按鈕打開(kāi)斷點(diǎn)列表窗口,單擊鼠標(biāo)右鍵選擇-Remove刪除所有消息斷點(diǎn)我們?cè)俅芜\(yùn)行程序,打開(kāi)窗口,但是這次我們不輸入任何東西單擊中的[W]按鈕打開(kāi)窗口列表我們選擇中的【B】按鈕打開(kāi)斷點(diǎn)窗口,刪除所有斷點(diǎn)。然后設(shè)置一個(gè)針對(duì)于值為0x202的WM_LBUTTONUP的消息斷點(diǎn)。我們單擊中的[B]按鈕打開(kāi)斷點(diǎn)列表。在我們?cè)O(shè)置的消息斷點(diǎn)這一行上單擊鼠標(biāo)右鍵選擇-Editcondition我們可以看到消息斷點(diǎn)實(shí)際上也是一個(gè)條件斷點(diǎn),當(dāng)前條件為[ESP8]0x202,即WM_LBUTTONUP。我們看看堆棧的情況我們看看棧頂擇Always(總是記錄),Logfunctionarguments(記錄函數(shù)參數(shù))也選擇Always。單擊OK,然后打開(kāi)窗口輸入用戶(hù)名和序列號(hào),單擊OK,接著來(lái)看看日志中的消息在日志窗口中,我們可以看到首先是值為0x201的WM_LBUTTONDOWN消息,然后又是值為0x202的WM_LBUTTONUP消息。沒(méi) 和窗口,然后在第一個(gè)斷點(diǎn)上單擊鼠標(biāo)右鍵選擇-Followindisassembler。然后斷點(diǎn)這一行上單擊鼠標(biāo)右鍵選擇-Conditionallog這樣,因?yàn)橛涗浀慕Y(jié)果可能會(huì)很多,在日志窗口中單擊鼠標(biāo)右鍵選擇-Logtofile本章附件Win32API編 首先第一個(gè)最簡(jiǎn)單的CrackMe名為L(zhǎng)eccion_13_HARDCODED_1(原名稱(chēng)西班牙文,英文名稱(chēng)譯為:Lesson_13_Hardcoded_1),我們OD結(jié)果如下(MalMuyMAL:西班牙文譯為:錯(cuò)誤首先通過(guò)在反匯編窗口中單擊鼠標(biāo)右鍵選擇-Searchfor-Name(labelincurrentmodule來(lái)查看API單擊鼠標(biāo)右鍵選擇-Togglebreakpointonimport或者在命令欄中輸入bpGetDlgItemTextA,bpMessageBoxA我們?cè)谠搮?shù)上單擊鼠標(biāo)右鍵選擇-FollowinDump我們選擇主菜單中項(xiàng)Debug-Executetillreturn這里我們可以看到比較和條件跳轉(zhuǎn)指令,兩個(gè)分支分別為提示MalMuyMAL(錯(cuò)誤)的消息框和提示MuyBIEN(正確)401066地址處的指令將403010地址處的DWORD內(nèi)容保存到EBX中,我們?cè)谠撜Z(yǔ)句上單擊鼠標(biāo)右鍵選擇-FollowinDump-Memory E,在403010開(kāi)始的內(nèi)存單元中是倒序存放的,(小端我們前面章節(jié)已經(jīng)介紹過(guò)),這4個(gè)字節(jié)是錯(cuò)跳轉(zhuǎn)到提示”MuyBIEN”(正確)的消息框處,如果不相等的話(huà),就提示”MalMuyMAL”(錯(cuò)誤)的消息框。很明顯它們不相等,所以會(huì)直接提示”MalMuyMAL”(錯(cuò)誤)的消息框。我們按F9從參數(shù)我們可以看出是提示”MalMuyMAL”(錯(cuò)誤)。我們按F9跳轉(zhuǎn)到了”MuyBIEN”(正確)的消息框處。我們按F9雖然作者忘了修改窗口的標(biāo)題,但是我們還是找到了正確的序列號(hào),我們用OD打開(kāi)”Leccon13HARDCODED2”。這個(gè)例子和剛才那個(gè)例子非常的相似, ,對(duì)應(yīng)字符串”9898”,所以會(huì)跳轉(zhuǎn)到提示”MuyBIEN”(正確)的消息框處接下來(lái)的章節(jié),增加難度-兩個(gè)相對(duì)難一點(diǎn)的硬編碼序列號(hào)的CrackMe。 本章附件Leccion13HARDCODED1.7zLeccion13HARDCODED2.7z第十四章-硬編碼序列號(hào)尋蹤-函數(shù)比較重要BoxA用于顯示一條消息提示是正確或者錯(cuò)誤的序列號(hào)。我們通過(guò)在反匯編窗口中單擊鼠標(biāo)右鍵選擇-Searchfor-Allreferencedtextstrings碼附近?,F(xiàn)在我們?cè)凇盰ouenteredtherightpassword!”字符串上面雙擊鼠標(biāo)左鍵。 ”。我 我們直接運(yùn)行程序, 這個(gè)CrackMe并不是序列號(hào)直接進(jìn)行比較。用OD加載這個(gè)名為”crakmeeasy”的CrackMe我們?cè)诿顧诖翱谥休斎隻pGetDlgItemTextA這里我們可以注意到Buffer參數(shù):用于保存用戶(hù)輸入的序列號(hào),我們?cè)谶@個(gè)參數(shù)上單擊鼠標(biāo)右鍵選擇-FollowinDump這里緩沖區(qū)是空的,因?yàn)樵摵瘮?shù)還沒(méi)有執(zhí)行,我們選擇主菜單項(xiàng)-Debug-Executetillreturn我們可以看到,這里我們看到了一長(zhǎng)串?dāng)?shù)字字符串。有些人可能會(huì)問(wèn)這是正確的序列號(hào)嗎?呵呵,單步一行,EAX就等于401222MOVEDX,DWORDPTRMOVEDX,DWORDPTR我們按F鍵 實(shí)際上就是將4現(xiàn)在是最后的4堆棧中的內(nèi)容如下 下一條指令,EDXEAX保存了我們輸入的錯(cuò)誤序列號(hào)的首地址,EDX的初始值為零,現(xiàn)在創(chuàng)建一個(gè)循環(huán),EAXEDX,然后EDX依次遞增來(lái)獲取我們輸入我們知道MOVSX指令將指定字節(jié)保存到EDX中,如果該字節(jié)是正數(shù),補(bǔ)零,如果該字節(jié)為負(fù)數(shù)補(bǔ)下一條指令是這里我們看到ECX已經(jīng)被賦值為了零,然后EDXECX就指向了常量數(shù)字字符串的第一個(gè)字節(jié),我們來(lái)看看ODCMPCMP錯(cuò)誤的序列號(hào)的第一個(gè)字節(jié)-14常量數(shù)字字符串的第一個(gè)字節(jié)CMP25,31我們輸入的是一個(gè)錯(cuò)誤的序列號(hào),如果輸入的是一個(gè)正確的序列號(hào)的話(huà),CMP正確序列號(hào)的第一個(gè)字節(jié)值-判斷兩者相等的條件為正確序列號(hào)的第一個(gè)字節(jié)值-14常量數(shù)字字符串的第一個(gè)字節(jié)正確的序列號(hào)的第一個(gè)字節(jié)值=常量數(shù)字字符串第一個(gè)字節(jié)值+正確的序列號(hào)的第一個(gè)字節(jié)值=31+第一個(gè)字節(jié)值=常量數(shù)字字符串第一個(gè)字節(jié)值+14常量數(shù)字字符串第二個(gè)字節(jié)值+14常量數(shù)字字符串第三個(gè)字節(jié)值+14我們用這個(gè)來(lái)計(jì)算序列號(hào)(正確序列號(hào)字節(jié)值=常量數(shù)字字符串對(duì)應(yīng)字節(jié)值+14)的每個(gè)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符+=對(duì)應(yīng)字符本章附件:第十五章-硬編碼序列號(hào)尋蹤- 點(diǎn)處我們通過(guò)在反匯編窗口中點(diǎn)擊鼠標(biāo)右鍵選擇-Searchfor-Name(label)incurrentmodule查看API 單擊鼠標(biāo)右鍵選擇-Searchfor-Allreferencedtextstrings雙擊鼠標(biāo)左鍵,就可以來(lái)到了該字符串的代碼處。為了找到上面的硬編碼序列號(hào),我們隨便輸入一個(gè)錯(cuò)誤的序列號(hào),然后單擊CheckHardcoded是401353)。我們通過(guò)在該指令上面單擊鼠標(biāo)右鍵選擇-FollowinDump-Memoryaddress來(lái)在數(shù)據(jù)窗口中定位到401353 跳轉(zhuǎn)到4013D2地址處,彈出消息框提示”Sorrypleasetryagain.”。這里都為零,檢列號(hào)結(jié)束刪除之前設(shè)置的所有斷點(diǎn),然后按下CheckHardcoded彈出Congratulations,yougotthehardcodedserial 點(diǎn)處 讓我們來(lái)看看該程序的區(qū)段的情況,我們可以選擇菜單項(xiàng)中的View-Memory或者單擊中M按鈕 點(diǎn)開(kāi)始其他區(qū)段,然后會(huì)跳轉(zhuǎn)到真正的 我們可以看到程序正在內(nèi)存中各種區(qū)段,我們來(lái)分析一下代碼。單擊鼠標(biāo)右鍵選擇 ysecode我們可以看到”Youdidit!”-memorybreakpoint來(lái)刪除之前設(shè)置的內(nèi)存斷點(diǎn)。然后彈出一個(gè)提示成功的窗口,我們修改影響跳轉(zhuǎn)標(biāo)志位,彈出提示序列號(hào)正確的消息框,這里的TESTCL,CL指令判斷CL是否等于零,在判斷之前還一個(gè)CALL指令,我們?cè)谶@個(gè)CALL堆棧中我們可以看到我們剛剛輸入的錯(cuò)誤序列號(hào),我們通過(guò)單擊鼠標(biāo)右鍵選擇-FollowinDump我們可以看到一個(gè)字符串 處,我們?cè)跀嘣谶@一行上面單擊鼠標(biāo)選擇-Breakpoint-Conditional我們?cè)O(shè)置條件為MSG202WM_LBUTTONUP并且設(shè)置中斷程序方式為條件中斷,我們來(lái)到主窗口,由于之前的序列號(hào)還在內(nèi)存中,為了不和之前的,我們輸入一個(gè)不同的序列號(hào)我們通過(guò)選擇菜單項(xiàng)中Debug-Executetillreturn較的,我們可以看到,代碼量有點(diǎn)大。第二種選擇-就是在內(nèi)存搜索一下我們輸入的序列號(hào),我們單擊中的M按鈕打開(kāi)內(nèi)存窗口我們勾選上Entireblock(這個(gè)內(nèi)存塊),然后按下OK我們還可以使用CTRLL來(lái)看看有沒(méi)有其他內(nèi)存區(qū)域有該錯(cuò)誤序列號(hào),我們發(fā)現(xiàn)當(dāng)前區(qū)段中沒(méi)有,其他區(qū)段中也沒(méi)有找到錯(cuò)誤序列號(hào)擇-FollowinDump在數(shù)據(jù)窗口中定位到EDI指向的內(nèi)存單元。當(dāng)F8單步執(zhí)行到下面的CALL指令處時(shí),錯(cuò)誤序列號(hào)拷貝完畢,我們繼續(xù)在該錯(cuò)誤序列號(hào)上面設(shè)置內(nèi)存斷點(diǎn) 本章附件:本章,我們分析的CrackMe與之前的不同之處在于序列號(hào)是基于名稱(chēng)變化的,也就是說(shuō)討論序列號(hào)生成算法。我們停在了點(diǎn)處好了,現(xiàn)在緩沖區(qū)里面存放了我們輸入的錯(cuò)誤序列號(hào),從程序的角度出發(fā),列號(hào)進(jìn)行比較,所以我們可以對(duì)錯(cuò)誤序列號(hào)設(shè)置內(nèi)存斷點(diǎn),看看程序的哪些地方使用了。可以看到該程序嘗試錯(cuò)誤序列號(hào)的第一個(gè)字節(jié)并且將保存到BL寄存器中,我們按F7鍵因?yàn)锽L不為零,所以跳轉(zhuǎn)不會(huì)發(fā)生,將執(zhí)行SUBBL,30這兩個(gè)寄存器被初始化為以下值:EAX寄存器循環(huán)體開(kāi)始處被初始化為了0A,EDI寄存器在循環(huán)體之前被XOREDI,EDI指令初始化為零EDI的結(jié)果為9,下一條指令I(lǐng)NCESI,ESI遞增1,然后跳轉(zhuǎn)到循環(huán)開(kāi)始處,錯(cuò)誤序列號(hào)的下一個(gè)字節(jié)以上結(jié)果依然保存到EDI中,一步步這個(gè)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論