CRC技術(shù)的實(shí)現(xiàn)與破解
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
CRC 在軟件加密保護(hù)中的應(yīng)用
或名(用CRC 打造軟件的外衣) 注:本文相關(guān)圖片沒收錄,帶圖PDF格式請(qǐng)到這下載:http://bbs.pediy.com/showthread.php?s=&threadid=17195 CRC(CyclicRedundancyCheck,直譯:循環(huán)冗余校驗(yàn))技術(shù)是一項(xiàng)很成熟的技術(shù),在眾多領(lǐng)域有廣泛的應(yīng)用,在數(shù)據(jù)存儲(chǔ)和通信傳輸應(yīng)用中處處都可以看到它的身影。最常用的CRC 校驗(yàn)形式有CRC-16,CRC-32兩種形式,采用CRC-16校驗(yàn),可以保證在1014 位碼元中只含有一位未被檢測出的錯(cuò)誤,采用CRC-32校驗(yàn)的出錯(cuò)概率比CRC-16還低105 倍。CRC的主要特點(diǎn) 就是:檢錯(cuò)能力極強(qiáng),開銷很小,易于實(shí)現(xiàn)。從性能和開銷上綜合考慮,其遠(yuǎn)遠(yuǎn)優(yōu)于奇偶校驗(yàn)及算術(shù)和校驗(yàn)等方式。因此,很多軟件在加密保護(hù)時(shí)都將CRC技術(shù)應(yīng)用其中。本文擬從 CRC校驗(yàn)的原理解剖入手,用實(shí)際代碼和應(yīng)用給大家解析CRC校驗(yàn)在軟件加密中的實(shí)際應(yīng)用,希望能給您的軟件加密保護(hù)提供一些幫助和建議。 CRC 校驗(yàn)的原理解析 在實(shí)際應(yīng)用中,根據(jù)環(huán)境和需求的變化,CRC形成了多種變形方式。比如:通訊協(xié)議X.25的幀檢錯(cuò)序列采用的是CRC-CCITT方式,ARJ、LHA、ZIP等壓縮軟件采用的是CRC-32方式,磁 盤驅(qū)動(dòng)器的讀寫采用的是CRC-16方式,GIF、TIFF等圖像存儲(chǔ)格式也使用CRC作為檢錯(cuò)技術(shù)。目前,比較流行的CRC形式主要是:CRC-16(CRC-CCITT)、CRC-32兩種,CRC-4、CRC-8 、CRC-12等形式的應(yīng)用比較少見。其實(shí),雖然有這么多種變形方式,但其原理是完全相同的,只是在實(shí)現(xiàn)上有一點(diǎn)變化而已,下面我們就對(duì)其原理進(jìn)行一番解剖,希求通透。 CRC的算法本質(zhì)是(模-2)除法的余數(shù)運(yùn)算,使用的除數(shù)不同,CRC的類型也就不一樣。怎么樣,不好理解吧?沒關(guān)系,我們繼續(xù)講解:CRC的算法其實(shí)是采用了多項(xiàng)式編碼的方法,您 可以將要被處理的數(shù)據(jù)塊M看成一個(gè)n階的二進(jìn)制多項(xiàng)式,其形式如下: a 是對(duì)應(yīng)的階數(shù)(位數(shù))的值; x是對(duì)應(yīng)的“模(進(jìn)制)”數(shù),由于我們處理的都是二進(jìn)制數(shù),所以x就是2 了。(模-2)的意思現(xiàn)在您明白了吧? 下面我們用一個(gè)數(shù)進(jìn)行解釋吧: 有一個(gè)二進(jìn)制數(shù)M=10010101,其對(duì)應(yīng)的多項(xiàng)式就可以表示為: CRC校驗(yàn)就是基于這種多項(xiàng)式進(jìn)行的運(yùn)算,其乘除法運(yùn)算過程與普通代數(shù)多項(xiàng)式的乘除法相同,其加減法運(yùn)算以2為模,加減時(shí)不進(jìn)(借)位,實(shí)際上與邏輯異或(XOR)運(yùn)算是一致 的。 通常,根據(jù)多項(xiàng)表達(dá)(運(yùn)算)式的不同,就形成了不同的CRC形式,以下是各種常用的多項(xiàng)表達(dá)(運(yùn)算)式: 這些多項(xiàng)表達(dá)式的值就是(模-2)除法的除數(shù),只要能確定使用哪一種多項(xiàng)式(也就是對(duì)應(yīng)除數(shù)),您就可以很簡單的獲取CRC檢驗(yàn)碼了。下面就給您介紹CRC檢驗(yàn)碼的計(jì)算過程(看 起來麻煩,其實(shí)簡單): 1、先確定您要使用的CRC校驗(yàn)形式,以此確定對(duì)應(yīng)除數(shù)(用G來表示)和選定階數(shù)(用r來表示)。(如果選擇CRC-4的話,r就等于4,選擇CRC-16話,r就等于16,以此類推。) 2、在待處理的數(shù)據(jù)塊M'后附加上r個(gè)0。假設(shè)原始數(shù)據(jù)塊的長度是m位的話,附加之后的長度就變成m+r位了,我們用M來代表附加后的值。 3、用第一步選擇的生成多項(xiàng)式的值(即對(duì)應(yīng)除數(shù)G)來除第二步附加0后生成的值(M),循環(huán)計(jì)算,一直到余數(shù)的階數(shù)小于等于r-1,這時(shí)所得到的余數(shù)(用Y表示)就是原始數(shù)據(jù) M'經(jīng)過所選擇的CRC校驗(yàn)形式所生成的CRC校驗(yàn)碼。 ●如果您想將生成的校驗(yàn)碼與原始數(shù)據(jù)進(jìn)行復(fù)合,只需要用第二步生成的(M)以模2的方法減去得到的CRC校驗(yàn)碼(Y),所得到的值就是包含了CRC校驗(yàn)碼的數(shù)據(jù)串M''。(不過在 軟件加密過程中可能用不到這一步)。 怎么樣,很簡單吧,只需要三步,就可以得到CRC 的校驗(yàn)碼。還不明白?舉個(gè)例子吧: 設(shè)原始數(shù)據(jù)M'=1100110100 選擇CRC-4的形式,則G=24+2+1=19=10011(二進(jìn)制) r =G 的二進(jìn)制位數(shù)減1=5-1=4 對(duì)原始數(shù)據(jù)M'進(jìn)行處理,在其尾部附加r個(gè)0,即: M=M'+0000=11001101000000 再用G 循環(huán)除M: 其實(shí)校驗(yàn)碼生成的過程就是一個(gè)循環(huán)移位的運(yùn)算,位與位之間就是異或(XOR)運(yùn)算。 ◆一個(gè)數(shù)據(jù)的校驗(yàn)過程是這樣的,如果有大量數(shù)據(jù)(比如說一個(gè)可執(zhí)行程序或一個(gè)壓縮包)將如何進(jìn)行校驗(yàn)?zāi)??其?shí)很簡單,只要將一個(gè)文件看成一個(gè)被一些數(shù)字分割的很長的位 字串就可以了,只是這個(gè)位字串比較TA而已,你只要按標(biāo)準(zhǔn)的方式對(duì)這個(gè)比較長的位字串進(jìn)行(模-2)除法運(yùn)算,就一定會(huì)得到一個(gè)余數(shù)---CRC校驗(yàn)碼,而這個(gè)校驗(yàn)碼就是這個(gè)文件 的CRC校驗(yàn)值。 CRC 校驗(yàn)的代碼實(shí)現(xiàn) 好了,理論上的準(zhǔn)備是很多了,現(xiàn)在要用進(jìn)入實(shí)踐了。下面,我們將給您提供一段很簡單而實(shí)用的代碼,用來實(shí)現(xiàn)CRC-32校驗(yàn),最終,我會(huì)用這段代碼實(shí)現(xiàn)軟件加密保護(hù)。 大家可以看到,上面生成CRC校驗(yàn)碼的過程中,使用了大量的位運(yùn)算和邏輯操作。而我想告訴大家的是,基于位運(yùn)算的算法是非常慢的而且效率很低。因此,在實(shí)際使用中不推薦使 用“計(jì)算法”來生成CRC校驗(yàn)碼,而建議使用“查表法”來進(jìn)行CRC校驗(yàn)碼計(jì)算。查表法又是什么方法呢?這里我不做過多的分析,簡單的說,它是利用預(yù)先計(jì)算出的標(biāo)準(zhǔn)碼表(對(duì) 應(yīng)不同的校驗(yàn)形式有不同的碼表,見附表1、2),用簡單的移位和XOR操作,快速計(jì)算出CRC校驗(yàn)碼的方法。 具體的算法就是: (1)將上次計(jì)算出的CRC校驗(yàn)碼右移一個(gè)字節(jié); (2)將移出的這個(gè)字節(jié)與新的要校驗(yàn)的字節(jié)進(jìn)行XOR 運(yùn)算; (3)用運(yùn)算出的值在預(yù)先生成碼表中進(jìn)行索引,獲取對(duì)應(yīng)的值(稱為余式); (4)用獲取的值與第(1)步右移后的值進(jìn)行XOR 運(yùn)算; (5)如果要校驗(yàn)的數(shù)據(jù)已經(jīng)處理完,則第(4)步的結(jié)果就是最終的CRC校驗(yàn)碼。如果還有數(shù)據(jù)要進(jìn)行處理,則再轉(zhuǎn)到第(1)步運(yùn)行。 看上面的過程是十分簡單的,不好理解的可能是“預(yù)先生成的碼表”。其實(shí)這個(gè)碼表就是2^8 的數(shù)組,為什么是8次方呢?因?yàn)槲覀兪怯米止?jié)來進(jìn)行運(yùn)算的,而一個(gè)字節(jié)是8位,所 以就是2的8次方了。因此這個(gè)碼表就是擁有256值的數(shù)組,對(duì)應(yīng)的每個(gè)值實(shí)際上就是0-255以對(duì)應(yīng)的CRC多項(xiàng)表達(dá)式(見原理分析)為權(quán)的CRC碼。如CRC-16的多項(xiàng)表達(dá)式就是 ,CRC-32的多項(xiàng)表達(dá)式就是: 附表1、2中分別給出了對(duì)應(yīng)兩種形式的碼表(匯編格式),您只要復(fù)制到您的代碼中即可使用(可能要做一些修飾)。 如果您不想將這么一大堆碼表復(fù)制到您的代碼中,也可以使用動(dòng)態(tài)生成碼表(不過是給256個(gè)數(shù)字進(jìn)行CRC計(jì)算而已)。下面是生成CRC-32碼表的代碼(c語言): //-------------------------------------- //GenCrc32Tbl函數(shù)動(dòng)態(tài)生成CRC-32的預(yù)置碼表 //Code:Chenji //-------------------------------------- unsignedintCRC.//在Windows下編程,int的大小是32位 unsignedintCRC_32_Tbl[256].//用來保存碼表 voidGenCrc32Tbl() { for(inti=0.i<256.++i){//用++i以提高效率 CRC=i; for(intj=0.j<8.++j) {//這個(gè)循環(huán)實(shí)際上就是用"計(jì)算法"來求取CRC的校驗(yàn)碼 if(CRC&1) CRC=(CRC>>1)^0xEDB88320; else //0xEDB88320就是CRC-32多項(xiàng)表達(dá)式的值 CRC>>=1; } CRC_32_Tbl[i]=CRC. } } //------------------------------------------------- ●上面的代碼其實(shí)就已經(jīng)實(shí)現(xiàn)了用“計(jì)算法”求取CRC校驗(yàn)碼的過程,只要做些修改就可以完全實(shí)現(xiàn)。您只要將上面的代碼復(fù)制到程序中,并調(diào)用GenCrc32Tbl函數(shù),就可以在 CRC_32_Tbl中生成CRC-32的預(yù)置碼表。有了碼表,用“查表法”計(jì)算CRC-32計(jì)算校驗(yàn)碼就易如反掌了。根據(jù)上面介紹的算法,用C語言只需要一行就可以實(shí)現(xiàn)。 CRC32=CRC_32_Tbl[(CRC32^((unsigned__int8*)p)[i])&0xff]^(CRC32>>8); 怎么樣?簡單吧。 下面是完整的一個(gè)實(shí)現(xiàn)函數(shù),更加簡單: //-------------------------------------------- //CalcCRC32函數(shù)計(jì)算出給定數(shù)據(jù)串的CRC-32校驗(yàn)碼 //Code : Chenji //-------------------------------------------- unsigned int CalcCRC32(void *DataBuff,unsigned int BufLen) {//DataBuff是指向數(shù)據(jù)串的指針,BufLen是數(shù)據(jù)串的長度 unsigned int CRC32=0xffffffff; //設(shè)置初始值 for(unsigned long i=0; i //如果你的編譯器不支持unsigned __int8定義,請(qǐng)?jiān)囉胾nsigned char return CRC32; } //----------------------------------------------------- 怎么樣,用查表法計(jì)算CRC校驗(yàn)碼是不是很簡單,很快捷?您只要將上面的代碼復(fù)制您的程序中,賦與對(duì)應(yīng)的參數(shù),就可以實(shí)現(xiàn)CRC-32校驗(yàn)了。還等什么,馬上開始現(xiàn)實(shí)之旅。 CRC 校驗(yàn)在軟件加密保護(hù)中的攻與防 上面用大篇幅介紹CRC的原理與實(shí)現(xiàn),都是為現(xiàn)在的實(shí)戰(zhàn)打基礎(chǔ),現(xiàn)在我們就要用實(shí)戰(zhàn)來校驗(yàn)了。 大家已經(jīng)知道,CRC校驗(yàn)生成的結(jié)果只是一個(gè)Long型的整數(shù),市面上一些軟件是如何將這個(gè)整數(shù)應(yīng)用在軟件加密保護(hù)中呢?這里我給大家介紹兩種常用的方式: 1、是對(duì)程序自身的進(jìn)行保護(hù)。首先對(duì)原始可執(zhí)行程序進(jìn)行CRC校驗(yàn),同時(shí)保存校驗(yàn)結(jié)果(可以保存在注冊(cè)表、配置文件或可執(zhí)行程序本身)。在程序運(yùn)行時(shí),對(duì)程序自身進(jìn)行CRC校 驗(yàn),并將運(yùn)算出的結(jié)果與保存的原始結(jié)果進(jìn)行比較,如果不相同,就說明程序已經(jīng)被修改(最有可能是被破解或被病毒感染)。即使只有1Bit的修改,都會(huì)被CRC檢查出來,所以用 CRC做自校驗(yàn)相當(dāng)有效。 2、用CRC校驗(yàn)算法,對(duì)注冊(cè)名和注冊(cè)碼進(jìn)行變形運(yùn)算和判斷,以此做為注冊(cè)保護(hù)和授權(quán)的手段。 這兩種方式在軟件保護(hù)上的運(yùn)用十分廣泛??梢哉f,每一種軟件加殼(加密)保護(hù)軟件(如upx,Aspack,FSG等)都使用了CRC進(jìn)行自身校驗(yàn)保護(hù)。 為了證明CRC在軟件加密保護(hù)上的效果,我制作了一套測試用例,大家可以在http://www.xxx.com上下載CRCTest.rar壓縮包,按本文進(jìn)行測試和分析。 壓縮包中有兩個(gè)可執(zhí)行程序:crctest.exe和Makecrc.exe。其中crctest.exe就是我們要進(jìn)行分析的對(duì)象,界面如下: 軟件已經(jīng)進(jìn)行了CRC外殼校驗(yàn)保護(hù),同時(shí),使用CRC-32算法做注冊(cè)碼校驗(yàn),可以說將CRC在軟件加密保護(hù)上的應(yīng)用全部發(fā)揮出來了。 MakeCrc.exe是配套工具,用來給上面的程序注入CRC保護(hù)碼和計(jì)算注冊(cè)碼。 現(xiàn)在,可以打開crctest.exe 文件,并隨意輸入注冊(cè)名和注冊(cè)碼,看一看! 您也可以用16進(jìn)制編輯器(如:Hiew,010Editor,RTA等),將crctest.exe的最后一個(gè)字節(jié)00修改成0F 保存修改后,再運(yùn)行程序,程序會(huì)提示被修改。 怎么樣,這就是CRC保護(hù)的效果。如果您試圖強(qiáng)行暴破來完成注冊(cè)的話,就必須修改原始文件,但是軟件將會(huì)在自校驗(yàn)時(shí)發(fā)現(xiàn)自己被修改了,然后自動(dòng)退出。除非您得到正確的注冊(cè) 碼或注冊(cè)算法,而軟件使用的注冊(cè)算法也是由CRC算法變形實(shí)現(xiàn)的。如果在不知道具體算法的情況,想要強(qiáng)行暴破是比較麻煩的,這就是CRC的威力。市面上大多數(shù)軟件大多是這樣 做的,畢竟誰也不想自己的軟件被人破解或修改,難道您不這么認(rèn)為嗎? 但是現(xiàn)在,我們就要挑戰(zhàn)這個(gè)難題,在不了解注冊(cè)算法的情況,如何實(shí)現(xiàn)強(qiáng)行暴破,徹底攻破CRC 的保護(hù)。這可能是您最希望了解的,還等什么,開始吧! 首先,您要準(zhǔn)備一些工具:Ollydbg1.10、DeDe、Peid全能插件版,也許還需要PE-tools1.50。這些軟件您可以在網(wǎng)上很輕松的找到,如果沒有可以與我聯(lián)系。 第一步:檢查 Peid是目前最流行,也是比較完善的檢測軟件??梢詸z測軟件是否加殼,使用了什么編譯器等諸多信息,同時(shí)其豐富的插件可以完成許多擴(kuò)展功能?,F(xiàn)在,我們先用Peid檢測 crctest.exe,查看程序的基本信息。Peid顯示軟件是用“BorlandC++1999”版的編譯器進(jìn)行編譯的,其實(shí)一般情況下,用BCB編譯的程序也會(huì)顯示為用“BorlandC++1999”編譯。 我們?cè)儆闷渲械牟寮癒ryptoANALyzer”,來分析程序中是否有通用的加密算法。我們可以看到,程序使用了CRC-32 算法: ◆這里想告訴大家的是,KryptoANALyzer是使用查詢數(shù)組(碼表)來確定軟件使用了什么算法,而軟件使用動(dòng)態(tài)生成數(shù)組(碼表)的話,它是無法檢測出算法來的。呵呵,這也是 它的漏洞了。你可以程序中保存一個(gè)其它算法的碼表來混淆檢測器。(crctest.exe中就定義了一個(gè)CRC32的數(shù)組,但我們并沒有使用它,而是使用了動(dòng)態(tài)生成的碼表) 第二步:分析 了解軟件沒有加殼,而且可能是由BCB編譯的之后,我們就要著手分析了。針對(duì)Borland公司出品的Delphi和BCB編譯器所生成執(zhí)行程序,可以使用DeDe反編譯器進(jìn)行分析,它可以很 好的恢復(fù)程序的原始代碼信息。 下面就是用DeDe將crctest.exe載入分析,現(xiàn)在我們切換到“過程”頁面,選擇“main”單元:btn_OKClick事件是我們感興趣的地方,當(dāng)按下“注冊(cè)”按鈕時(shí),這個(gè)事件會(huì)被調(diào)用 。雙擊這個(gè)事件,我們就可以看到這個(gè)事件的匯編代碼,在其中顯示的匯編代碼已經(jīng)被DeDe 處理過,對(duì)標(biāo)準(zhǔn)的函數(shù)調(diào)用已經(jīng)進(jìn)行了注釋,其可讀性很好。00401C90這個(gè)地址就是這 個(gè)事件函數(shù)的入口點(diǎn),如果您有一些基本功,可以認(rèn)真分析一下。您也許可以看出關(guān)鍵的代碼。不過,下面我們要進(jìn)入動(dòng)態(tài)調(diào)試了! 第三步:調(diào)試破解 在檢測和分析的基礎(chǔ)上,我們可以開始動(dòng)態(tài)調(diào)試了。我要用動(dòng)態(tài)的數(shù)據(jù)來解釋破解的思路與過程?,F(xiàn)在,請(qǐng)打開Ollydbg動(dòng)態(tài)調(diào)試器,將crctest.exe載入,停在程序的入口處。 按Ctrl+G,輸入00401C90,直接定位到“注冊(cè)”按鈕的點(diǎn)擊事件函數(shù)入口處,并按F2下斷點(diǎn)。 接下來,可以按F9運(yùn)行程序,進(jìn)入調(diào)試,然后在窗口中,隨便輸入注冊(cè)名和注冊(cè)碼,點(diǎn)擊“注冊(cè)”按鈕,程序?qū)?huì)中斷在00401C90處:不斷按F8單步運(yùn)行,其間您可以看到許多的 數(shù)據(jù)在變化,不用管它,一直按F8運(yùn)行,直到顯示注冊(cè)錯(cuò)誤的信息框,再看運(yùn)行的狀態(tài)。 可以看到,在運(yùn)行00401FDF這個(gè)地址的時(shí)候,軟件顯示了注冊(cè)錯(cuò)誤的信息框。顯然這個(gè)call00468C08指令就是顯示信息框的函數(shù)。我們只要找到調(diào)用這個(gè) Call的調(diào)用(有點(diǎn)繞舌),就可以找到關(guān)鍵點(diǎn)了。大家向上回溯代碼可以看到下面的內(nèi)容:我們將匯編代碼提取出來如下: =========================== /*401F65*/ lea edx,[local.2] /*401F68*/ lea eax,[local.4] /*401F6B*/ call crctest.00468DA0 // 對(duì)比注冊(cè)碼是否正確 /*401F70*/ test al, al /*401F72*/ je shortcrctest.00401FC7//如果不正確就跳走 /*401F74*/ mov eax,dwordptrds:[46EF94] /*401F79*/ push 40040 /*401F7E*/ lea ecx,dwordptrds:[edi+141] /*401F84*/ lea edx,dwordptrds:[edi+EB] /*401F8A*/ mov eax,dwordptrds:[eax] /*401F8C*/ call crctest.00468C08 // 顯示成功注冊(cè)的提示信息 /*401F91*/ mov wordptrds:[ebx+10],8C /*401F97*/ lea edx,dwordptrds:[edi+146] /*401F9D*/ lea eax,[local.14] /*401FA0*/ call crctest.00468C18 /*401FA5*/ inc dwordptrds:[ebx+1C] /*401FA8*/ mov edx,dwordptrds:[eax] /*401FAA*/ mov eax,dwordptrds:[esi+2F8] /*401FB0*/ call crctest.00452658 /*401FB5*/ dec dwordptrds:[ebx+1C] /*401FB8*/ lea eax,[local.14] /*401FBB*/ mov edx, 2 /*401FC0*/ call crctest.00468CD0 /*401FC5*/ jmp shortcrctest.00401FE4 /*401FC7*/ mov eax,dwordptrds:[46EF94]//跳轉(zhuǎn)到這里 /*401FCC*/ push 40010 /*401FD1*/ lea ecx,dwordptrds:[edi+1B4] /*401FD7*/ lea edx,dwordptrds:[edi+16A] /*401FDD*/ mov eax,dwordptrds:[eax] /*401FDF*/ call crctest.00468C08 // 顯示錯(cuò)誤注冊(cè)的提示信息 =========================== 由此可以看到軟件的注冊(cè)檢查是很簡單的,只要將00401F72 處的代碼: jeshortcrctest.00401FC7 修改為: nopnop 就可以暴破了!大家可以在Ollydbg中將00401F72處的代碼修改成下面的形式: 然后,取消所有的斷點(diǎn),直接按F9運(yùn)行程序,再隨意輸入注冊(cè)名和注冊(cè)碼,點(diǎn)擊“注冊(cè)”??吹搅藛?? 軟件已經(jīng)成功注冊(cè)了!但是真的成功了嗎?不要高興的太早,還有CRC自校驗(yàn)沒有解決呢!請(qǐng)先將修改過的程序保存為另一個(gè)文件crctest_1.exe。 ●方法:在匯編代碼上點(diǎn)右鍵,選擇“復(fù)制到可執(zhí)行程序”--“所有改動(dòng)”,再選擇“全部復(fù)制”打開新的窗口。在新的窗口中點(diǎn)右鍵,選擇“保存文件”,輸入文件名就可以保 存。 現(xiàn)在,請(qǐng)暫時(shí)關(guān)閉ollydbg,運(yùn)行新保存的文件crctest_1.exe。怎么樣,沒有成功吧!軟件發(fā)現(xiàn)自己被修改了。目前,我們只完成了注冊(cè)碼校驗(yàn)的暴破,還沒有解決CRC 的校驗(yàn)保 護(hù),這才是我們的重頭戲,而這其實(shí)很簡單。馬上動(dòng)手! 再次打開ollydbg,這次就要載入crctest_1.exe了,因?yàn)樗呀?jīng)暴破了注冊(cè)校驗(yàn)的部分。在開始之前,我們要分析一下思路:軟件要進(jìn)行自校驗(yàn),就一定要讀文件到內(nèi)存中,我們 只要找到讀文件的函數(shù),就可以順藤摸瓜找到校驗(yàn)的核心部分了。好,在ollydbg中按ctrl+n打開函數(shù)導(dǎo)入導(dǎo)出表,找到ReadFile函數(shù)。在ReadFile這一行上點(diǎn)右鍵,選擇“在每個(gè) 參考上設(shè)置斷點(diǎn)”,狀態(tài)條上顯示有六個(gè)斷點(diǎn)被設(shè)置。不管它了,按F9開始運(yùn)行!很快軟件就被斷下來: 大家不用花時(shí)間在這些匯編代碼上,我們的目標(biāo)是關(guān)鍵跳轉(zhuǎn)點(diǎn)。一直按F8返回到上級(jí)調(diào)用: 最終我們會(huì)返回到00401A8B 這個(gè)地址,而在其上、下方有兩個(gè)調(diào)用: /*401A86*/ call crctest_.00401B8C //計(jì)算當(dāng)前的CRC校驗(yàn)碼 /*401A8B*/ mov esi,eax /*401A8D*/ mov eax,ebx /*401A8F*/ call crctest_.00401AA0 //讀取原始的CRC校驗(yàn)碼 這兩個(gè)調(diào)用分別返回當(dāng)前的CRC校驗(yàn)碼和原始的CRC校驗(yàn)碼,具體過程大家可以進(jìn)入其中進(jìn)行分析,這里不做詳解。接下來,繼續(xù)按F8,直到返回到更上級(jí)的調(diào)用(建議按Alt+B,關(guān) 閉所有中斷): 經(jīng)過三次返回,我們終于看到了關(guān)鍵點(diǎn): /*40193E*/ call crctest_.00401A80 // 這個(gè)調(diào)用進(jìn)行自校驗(yàn) /*401943*/ test al, al // 檢查校驗(yàn)的結(jié)果 /*401945*/ jnz shortcrctest_.0040196F//如果通過就跳走 /*401947*/ mov eax,dwordptrds:[46EF94] /*40194C*/ push 40010 /*401951*/ mov ecx,crctest_.0046A5E0 /*401956*/ mov edx,crctest_.0046A5BC /*40195B*/ mov eax,dwordptrds:[eax] /*40195D*/ call crctest_.00468C08 /*401962*/ mov edx,dwordptrds:[46EF94] /*401968*/ mov eax,dwordptrds:[edx] /*40196A*/ call crctest_.004488FC /*40196F*/ mov edx,[local.10]//通過以后,就跳到這里 /*401972*/ mov dwordptrfs:[0],edx /*401979*/ mov eax,[local.1] /*40197C*/ test bl, bl /*40197E*/ je shortcrctest_.00401985 /*401980*/ call crctest_.00468F61 /*401985*/ pop esi /*401986*/ pop ebx /*401987*/ mov esp,ebp /*401989*/ pop ebp /*40198A*/ retn 很顯然,我們只要將00401945 處的代碼: jnzshortcrctest_.0040196F 修改為:jmpshortcrctest_.0040196F//強(qiáng)行跳轉(zhuǎn) 就可以強(qiáng)制為自校驗(yàn)通過的狀態(tài)。好了,接下來的保存工作就不用我多說了。最后,再用Keymake軟件制作出破解補(bǔ)丁就可以完成注冊(cè)了!軟件包中就保存了破解補(bǔ)丁 crctest_patch.exe,大家只要運(yùn)行就可以看到效果了! OK,到目前為止,我為您制作的CRC保護(hù)實(shí)際已經(jīng)被完全破解了,整個(gè)過程比較啰嗦,只是力求詳盡。在看過這一部分后,您應(yīng)該對(duì)破解CRC保護(hù)的軟件有了感性和理性的認(rèn)識(shí)。 附表1 CRC-16 的碼表 dw 00000h,0C0C1h,0C181h,00140h,0C301h,003C0h,00280h,0C241h dw 0C601h,006C0h,00780h,0C741h,00500h,0C5C1h,0C481h,00440h dw 0CC01h,00CC0h,00D80h,0CD41h,00F00h,0CFC1h,0CE81h,00E40h dw 00A00h,0CAC1h,0CB81h,00B40h,0C901h,009C0h,00880h,0C841h dw 0D801h,018C0h,01980h,0D941h,01B00h,0DBC1h,0DA81h,01A40h dw 01E00h,0DEC1h,0DF81h,01F40h,0DD01h,01DC0h,01C80h,0DC41h dw 01400h,0D4C1h,0D581h,01540h,0D701h,017C0h,01680h,0D641h dw 0D201h,012C0h,01380h,0D341h,01100h,0D1C1h,0D081h,01040h dw 0F001h,030C0h,03180h,0F141h,03300h,0F3C1h,0F281h,03240h dw 03600h,0F6C1h,0F781h,03740h,0F501h,035C0h,03480h,0F441h dw 03C00h,0FCC1h,0FD81h,03D40h,0FF01h,03FC0h,03E80h,0FE41h dw 0FA01h,03AC0h,03B80h,0FB41h,03900h,0F9C1h,0F881h,03840h dw 02800h,0E8C1h,0E981h,02940h,0EB01h,02BC0h,02A80h,0EA41h dw 0EE01h,02EC0h,02F80h,0EF41h,02D00h,0EDC1h,0EC81h,02C40h dw 0E401h,024C0h,02580h,0E541h,02700h,0E7C1h,0E681h,02640h dw 02200h,0E2C1h,0E381h,02340h,0E101h,021C0h,02080h,0E041h dw 0A001h,060C0h,06180h,0A141h,06300h,0A3C1h,0A281h,06240h dw 06600h,0A6C1h,0A781h,06740h,0A501h,065C0h,06480h,0A441h dw 06C00h,0ACC1h,0AD81h,06D40h,0AF01h,06FC0h,06E80h,0AE41h dw 0AA01h,06AC0h,06B80h,0AB41h,06900h,0A9C1h,0A881h,06840h dw 07800h,0B8C1h,0B981h,07940h,0BB01h,07BC0h,07A80h,0BA41h dw 0BE01h,07EC0h,07F80h,0BF41h,07D00h,0BDC1h,0BC81h,07C40h dw 0B401h,074C0h,07580h,0B541h,07700h,0B7C1h,0B681h,07640h dw 07200h,0B2C1h,0B381h,07340h,0B101h,071C0h,07080h,0B041h dw 05000h,090C1h,09181h,05140h,09301h,053C0h,05280h,09241h dw 09601h,056C0h,05780h,09741h,05500h,095C1h,09481h,05440h dw 09C01h,05CC0h,05D80h,09D41h,05F00h,09FC1h,09E81h,05E40h dw 05A00h,09AC1h,09B81h,05B40h,09901h,059C0h,05880h,09841h dw 08801h,048C0h,04980h,08941h,04B00h,08BC1h,08A81h,04A40h dw 04E00h,08EC1h,08F81h,04F40h,08D01h,04DC0h,04C80h,08C41h dw 04400h,084C1h,08581h,04540h,08701h,047C0h,04680h,08641h dw 08201h,042C0h,04380h,08341h,04100h,081C1h,08081h,04040h 附表2 CRC-32 的碼表 dd000000000h,077073096h,0EE0E612Ch,0990951BAh,0076DC419h,0706AF48Fh,0E963A535h,09E6495A3h,00EDB8832h,079DCB8A4h dd0E0D5E91Eh,097D2D988h,009B64C2Bh,07EB17CBDh,0E7B82D07h,090BF1D91h,01DB71064h,06AB020F2h,0F3B97148h,084BE41DEh dd01ADAD47Dh,06DDDE4EBh,0F4D4B551h,083D385C7h,0136C9856h,0646BA8C0h,0FD62F97Ah,08A65C9ECh,014015C4Fh,063066CD9h dd0FA0F3D63h,08D080DF5h,03B6E20C8h,04C69105Eh,0D56041E4h,0A2677172h,03C03E4D1h,04B04D447h,0D20D85FDh,0A50AB56Bh dd035B5A8FAh,042B2986Ch,0DBBBC9D6h,0ACBCF940h,032D86CE3h,045DF5C75h,0DCD60DCFh,0ABD13D59h,026D930ACh,051DE003Ah dd0C8D75180h,0BFD06116h,021B4F4B5h,056B3C423h,0CFBA9599h,0B8BDA50Fh,02802B89Eh,05F058808h,0C60CD9B2h,0B10BE924h dd02F6F7C87h,058684C11h,0C1611DABh,0B6662D3Dh,076DC4190h,001DB7106h,098D220BCh,0EFD5102Ah,071B18589h,006B6B51Fh dd09FBFE4A5h,0E8B8D433h,07807C9A2h,00F00F934h,09609A88Eh,0E10E9818h,07F6A0DBBh,0086D3D2Dh,091646C97h,0E6635C01h dd06B6B51F4h,01C6C6162h,0856530D8h,0F262004Eh,06C0695EDh,01B01A57Bh,08208F4C1h,0F50FC457h,065B0D9C6h,012B7E950h dd08BBEB8EAh,0FCB9887Ch,062DD1DDFh,015DA2D49h,08CD37CF3h,0FBD44C65h,04DB26158h,03AB551CEh,0A3BC0074h,0D4BB30E2h dd04ADFA541h,03DD895D7h,0A4D1C46Dh,0D3D6F4FBh,04369E96Ah,0346ED9FCh,0AD678846h,0DA60B8D0h,044042D73h,033031DE5h dd0AA0A4C5Fh,0DD0D7CC9h,05005713Ch,0270241AAh,0BE0B1010h,0C90C2086h,05768B525h,0206F85B3h,0B966D409h,0CE61E49Fh dd05EDEF90Eh,029D9C998h,0B0D09822h,0C7D7A8B4h,059B33D17h,02EB40D81h,0B7BD5C3Bh,0C0BA6CADh,0EDB88320h,09ABFB3B6h dd003B6E20Ch,074B1D29Ah,0EAD54739h,09DD277AFh,004DB2615h,073DC1683h,0E3630B12h,094643B84h,00D6D6A3Eh,07A6A5AA8h dd0E40ECF0Bh,09309FF9Dh,00A00AE27h,07D079EB1h,0F00F9344h,08708A3D2h,01E01F268h,06906C2FEh,0F762575Dh,0806567CBh dd0196C3671h,06E6B06E7h,0FED41B76h,089D32BE0h,010DA7A5Ah,067DD4ACCh,0F9B9DF6Fh,08EBEEFF9h,017B7BE43h,060B08ED5h dd0D6D6A3E8h,0A1D1937Eh,038D8C2C4h,04FDFF252h,0D1BB67F1h,0A6BC5767h,03FB506DDh,048B2364Bh,0D80D2BDAh,0AF0A1B4Ch dd036034AF6h,041047A60h,0DF60EFC3h,0A867DF55h,0316E8EEFh,04669BE79h,0CB61B38Ch,0BC66831Ah,0256FD2A0h,05268E236h dd0CC0C7795h,0BB0B4703h,0220216B9h,05505262Fh,0C5BA3BBEh,0B2BD0B28h,02BB45A92h,05CB36A04h,0C2D7FFA7h,0B5D0CF31h dd02CD99E8Bh,05BDEAE1Dh,09B64C2B0h,0EC63F226h,0756AA39Ch,0026D930Ah,09C0906A9h,0EB0E363Fh,072076785h,005005713h dd095BF4A82h,0E2B87A14h,07BB12BAEh,00CB61B38h,092D28E9Bh,0E5D5BE0Dh,07CDCEFB7h,00BDBDF21h,086D3D2D4h,0F1D4E242h dd068DDB3F8h,01FDA836Eh,081BE16CDh,0F6B9265Bh,06FB077E1h,018B74777h,088085AE6h,0FF0F6A70h,066063BCAh,011010B5Ch dd08F659EFFh,0F862AE69h,0616BFFD3h,0166CCF45h,0A00AE278h,0D70DD2EEh,04E048354h,03903B3C2h,0A7672661h,0D06016F7h dd04969474Dh,03E6E77DBh,0AED16A4Ah,0D9D65ADCh,040DF0B66h,037D83BF0h,0A9BCAE53h,0DEBB9EC5h,047B2CF7Fh,030B5FFE9h dd0BDBDF21Ch,0CABAC28Ah,053B39330h,024B4A3A6h,0BAD03605h,0CDD70693h,054DE5729h,023D967BFh,0B3667A2Eh,0C4614AB8h dd05D681B02h,02A6F2B94h,0B40BBE37h,0C30C8EA1h,05A05DF1Bh,02D02EF8Dh 該文章在 2014/4/10 10:49:03 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |