所謂暴力破解,就是通過修改匯編代碼進而控制程序的運行流程,達到不需注冊碼也能正常使用軟件的目的。相對於解出算法進而編寫注冊機,暴破的技術含量是比較低的。但也正是因為一本05年的雜志上介紹“暴力破解”的文章,讓我入了這個大坑。近來想重拾調試器,就先從最簡單的CrackMe入手,熟練一下各工具方法。
下載CrackMe3文件(我用的是看雪《加密與解密》中的CFF CrackMe #3 程序 http://pan.baidu.com/s/1dD9v9x3 )。
1.查看此程序是否加殼。加殼的話還得進行脫殼處理。將CrackMe拖到PEID上,顯示用Delphi編寫。無殼,甚好。
3.打開程序,看看注冊碼出現異常的時候有何提示。恩,輸入錯誤的注冊碼,確認。顯示了“Wrong Serial,try again!”。我們記下這一串字符,接下來用得到。
4.退出程序,打開OllyDbg,並載入此程序。(當年用的是W32Dasm,屬於靜態反匯編軟件,支持WIN API,具有強大的串式參考功能。因此成為破解入門軟件的最佳選擇。這次用OllyDbg實施爆破,只是復習一下操作。爆破原理都是相同的)下圖是OllyICE,是OllyDbg的漢化版。也一樣好用。
載入程序后,出現如下界面:
title上面的“模塊 — crackme3”標明了程序領空,我們當前是在crackme的代碼內。
5.我們在反匯編窗口“右鍵——查找——所有參考文本字符串”:
然后會彈出一個文本字符串的對話框,繼續“右鍵——查找文本”:
然后會彈出對話框,輸入前面記下來的那串“Wrong Serial,try again!”。其實為了方便,可以只輸入“Wrong”這個字符串,畢竟程序里帶“Wrong”的字符不會太多,如下圖:
點擊“確定”后,會高亮查找結果,此時在對應字符串處“右鍵——反匯編窗口中跟隨”,會在反匯編窗口中跳到對應此串字符的匯編指令:
看到上圖的指令,分析一下程序流程:輸入ID和注冊碼后,call調用子函數來判斷注冊碼是否正確(00440F51處,call 00403B2C處的子函數),如果不正確,一個jnz跳到00440F72,彈出“Wrong Serial ,try again!”,提醒說你丫注冊碼是錯的。
為了驗證我們的想法,我們在call的前面按F2下個斷點,然后一步步跟進,看看call了個什么函數過來:
然后F9讓程序跑起來,輸入假的ID “wwwwww” ,按下“注冊”。此時程序自然要去call子函數來驗證我們的注冊碼是否正確。可惜它還沒走到call的那一步,就停在了我們設的斷點上(可以看到信息窗口中的堆棧內容“wwwww”,不知會不會存在緩沖區溢出?XD):
然后按下幾次F8單步步過,直到了00440F34 call指令,程序就要召喚子程序來檢驗注冊碼是否正確了!此時改為F7單步步入,跟蹤到所call的函數(如圖,此函數地址在00403B2C處):
跟進去之后,這就是用來驗證注冊碼的程序(從 三個push壓入堆棧 開始,到 三個pop彈出堆棧+retn 結束):
從代碼中可以發現,程序將輸入的注冊碼與內置的注冊碼用cmp指令做了比較。(cmp指令執行后,將對標志寄存器ZF產生影響。比如 CMP AX , BX ,當AX=BX時,ZF=1;AX!=BX時,ZF=0。)
也就是說,如果注冊碼與輸入的字符串不相等,ZF=0。此時子程序返回,執行00440F39處的JNZ指令。因為輸入的注冊碼不對,ZF=0,開始執行JNZ,跳轉到00440F8C,彈出“Wrong Serial”對話框提示注冊碼錯誤。
這就是傳說中的“關鍵跳”,如果將JNZ(ZF=0時就跳轉)改為JE(ZF=1時就跳轉),得到的結果就會正好相反,即錯誤的注冊碼反而會提示注冊成功,對的注冊碼反而會提示錯誤。
6.那么現在找出那兩個“關鍵跳”(輸入ID時call了一下,然后一個jnz。輸入注冊碼時又call了一下,再一個jnz。),如下圖:
好,現在只剩下修改匯編代碼了。雙擊對應的JNZ指令,彈出“匯編於此處”的對話框。將只需將“jnz”改為“je”,點擊“匯編”即可。用同樣的方法修改另一處“jnz”:
修改完畢,“右鍵——復制到可執行文件——所有修改“:
在彈出的對話框中點擊“全部復制”:
然后在出現的新對話框中“右鍵——保存文件”,完畢。
此時打開新保存的文件,隨意輸入一個ID和注冊碼,點擊“注冊”,即彈出“注冊成功”的對話框:
小結:本次主要是重溫了OllyDbg的操作。爆破無外乎就是改變程序的驗證流程,譬如將關鍵處的jne改為je,或者jmp,比較不優雅。更優雅的是揣摩出程序作者的驗證算法,寫出內存補丁或者注冊機,這才是高大上的方法。無奈算法一類的是我的軟肋,仍需努力啊。