取密鑰生成算法(圖)
發(fā)布日期:2022-01-07 12:39 | 文章來源:腳本之家
從拷貝保護產(chǎn)品中剝?nèi)。╮ipping)算法通常是創(chuàng)建密鑰生成程序的一種簡單而行之有效的方法。其思路非常簡單:定位受保護程序內(nèi)計算合法序列號的函數(shù)(可能不止一個函數(shù)),并將它(們)移植到你密鑰生成程序中。這種方法的美妙之處在于你不需要真正理解這個算法,你只需要找到生成合法序列號這個(或些)函數(shù)并想辦法在自己的程序中調(diào)用它(們)。
你第一個必須要完成的任務(wù)是定位這個crackme程序內(nèi)的密鑰生成算法??梢圆扇〉霓k法有很多,但有一種方法很少會失敗,那就是尋找讀取你輸入用戶名和序列號的兩個文本框的那段代碼。假定KegenMe-3的主窗口是一個對話框(這一點通過查找程序初始化代碼中的創(chuàng)建對話框的API函數(shù)就可以很容易地得到證實),很可能程序會使用GetDlgItemText函數(shù)或者向文本框發(fā)送WM_GETTEXT消息。假定這個程序使用的是GetDlgItemText,你可以返回到OllyDbg的“Name(名稱)”窗口查找調(diào)用GetDlgItemTextA或調(diào)用GetDlgItemTextW的代碼。不出所料,你會發(fā)現(xiàn)程序調(diào)用了GetDlgItemTextA函數(shù)。打開“Find References to Import(查找導(dǎo)入項的引用)”窗口,你會看到有兩處代碼調(diào)用了這個GetDlgItemTextA函數(shù)(不計那條直接跳轉(zhuǎn)的JMP指令,它是這個函數(shù)的導(dǎo)入地址表中的項)。

列表11.1 KeygenMe-3中第一個輸入字符串的轉(zhuǎn)換算法



列表11.1
在試著從列表11.1給出的代碼中剝?nèi)〕鲛D(zhuǎn)換算法之前,讓我們先看一下在Key4.00401388處的這個函數(shù),它顯然也是算法的一部分。

列表11.2 KeygenMe-3中第二個輸入字符串的轉(zhuǎn)換算法

列表11.2
通過查看這段代碼,你可以明顯地看到好像有兩段代碼中包含了密鑰生成算法。第一段是列表11.1中Key4.0040130B部分,第二段是列表11.2給出的整個函數(shù)。列表11.1中的那部分代碼生成了ESI寄存器中的值,而列表11.2中的函數(shù)將返回值賦給了EAX寄存器。然后比較這兩個值,如果兩個值相等的話,程序就報告成功通過驗證(也就是我們剛才修補過的地方)。
我們從Key4.0040130B處的代碼片段開始,確定它要接收什么樣的輸入數(shù)據(jù)。這段代碼開始之前ECX寄存器已經(jīng)存放了輸入的第一個字符串(從上面那個文本框輸入的字符串)的長度,開始之后代碼中又出現(xiàn)了該字符串的地址(40303F)和一個未知的硬編碼地址(40351F)。首先要注意的是,這段代碼并沒有挨個地處理字符串中的每個字符。相反,它只是讀取字符串的前四個字符,并把它們當(dāng)作一個雙字來處理。要把這些代碼移植到自己的密鑰生成程序中,必須先弄清楚40351F中存放的到底是什么。首先,你可以看到這個地址在引用之前總是先與EAX寄存器中的值相加。在第一次迭代中,EAX寄存器的值為1,所以訪問的實際地址是403520。在接下來的迭代中,EAX的值一直為4,所以你現(xiàn)在應(yīng)該去查看403524這個地址。在OllyDbg中讀出403520處的內(nèi)存,你可以看到這個地址包含了下面這些數(shù)據(jù):

要注意的是,這一行代碼把這個地址當(dāng)作一個單字節(jié)來訪問,而不是按完整的DWORD訪問,所以實際上程序只訪問了第一字節(jié)(0x25)和第四字節(jié)(0x65)的內(nèi)容。
查看列表11.1中的第一個算法,你會發(fā)現(xiàn)這顯然是一個將用戶名轉(zhuǎn)換成一個32位數(shù)的密鑰生成算法(轉(zhuǎn)換完成后存放在ESI寄存器中)。那么,列表11.2中的第二個算法又在干什么呢?通過快速瀏覽就可以看出這段代碼中沒有任何復(fù)雜的處理。它只是逐個檢查我們輸入的序列號中的每一個數(shù)字,每檢查一個都把它的值減去0x30(0x30恰好就是ASCII碼中“0“的編碼)并將結(jié)果反復(fù)地乘以10,直到ECX寄存器中的值變成0為止。對源串中每一個字符進行乘10運算是在一個內(nèi)部循環(huán)中完成的,且乘以10的次數(shù)取決于這個數(shù)字在源串中的位置。
在調(diào)試器中單步調(diào)試這段代碼,我們會看到一些有經(jīng)驗的逆向工作者僅通過觀察這個函數(shù)就可以獲得的一些信息。這個函數(shù)實際上就是把通過參數(shù)傳入的字符串轉(zhuǎn)化成一個二進制的DWORD(雙字),它相當(dāng)于C運行庫中的atoi函數(shù),但它看上去更像是一個atoi函數(shù)的個人實現(xiàn)版本(atoi要稍微復(fù)雜一點,如果有相應(yīng)的庫文件,并且因為OllyDbg能夠識別出庫函數(shù)——如果程序中用了atoi函數(shù)的話,肯定會被OllyDbg識別出來,但OllyDbg沒有在KeygenMe-3中找到相關(guān)的任何信息)。
因此,好像第一個算法(列表11.1中的算法)使用了一個專門的算法將用戶名轉(zhuǎn)換成32位的DWORD,而第二個算法只是簡單地將下面的那個文本框中輸入的內(nèi)容轉(zhuǎn)換成數(shù)字形式。下面的那個文本框中所包含的應(yīng)該就是第一個算法生成的數(shù)。根據(jù)這一線索,好像我們只需要把第一個算法“剝?nèi) 背鰜矸诺轿覀兊拿荑€生成程序中,就可以讓它為我們生成序列號了。讓我們來試試看。
表11.3給出了我為密鑰生成程序創(chuàng)建的取出來的子程序。它實際上是一個C函數(shù)(用Microsoft的C/C 編譯器編譯),其中是一段從OllyDbg的反匯編器中拷貝而來的一段直接插入的(inline。譯注:用“_asm { }”括起來的部分)匯編代碼。用小寫字母表示的指令是我手工加上去的,還包括LoopStart這個名稱。

列表11.3 從KeygenMe-3中取出的處理第一個字符串的轉(zhuǎn)換算法

列表11.3
我把這個函數(shù)(函數(shù)名為ComputeSerial)插入到一個短小的控制臺模式的應(yīng)用程序中(console mode application),這個程序要求用戶輸入用戶名,并以十進制數(shù)形式顯示ComputeSerial函數(shù)的返回值。這個程序所要做的只是調(diào)用ComputeSerial函數(shù)并以十進制數(shù)的形式顯示ComputeSerial的返回值。下面是我的密鑰生成程序的入口程序:

似乎輸入任意一個名字到KeygenMe-3主界面的上面的那個文本框(這個名字應(yīng)與作為參數(shù)傳遞給ComputeSerial函數(shù)的名字相同),然后將ComputeSerial函數(shù)的返回值鍵入到KeygenMe-3主界面的第二個文本框,就可以讓KeygenMe-3顯示成功消息框了。讓我們來試試看。你可以將“John Doe”作為參數(shù)傳遞給我們的密鑰生成程序,并記下生成的序列號。圖11.9顯示了密鑰生成程序的輸出界面。

圖11.9 運行中的KeygenMe-3密鑰生成程序
最后得到的序列號為580695444。運行KeygenMe-3(未做補丁的那個版本),在第一個文本框中輸入“John Doe”,在第二個文本框中輸入“580695444”。又成功了!KeygenMe-3將這兩個輸入值作為合法的值接受了。恭喜你,你的第二節(jié)破解課程到此結(jié)束。
版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。
相關(guān)文章
上一篇:
HTML的七種加密解密
下一篇: