使用OllyDbg破解EasyCrackMe

實驗操作參考《C++黑客編程揭祕與防範》(作者: 冀雲)


對於軟件的破解來說,主要是取消軟件中的各種限制,如,比如時間限制、序列號限制……對於破解來說,無疑與逆向工程有着密切 的關係,想要突破任何一種限制都要去了解該種限制的保護方式或保護機制。

EasyCrackMe程序

根據《C++黑客編程揭祕與防範》一書中提供的EasyCrackMe程序,進行“破解”。

EasyCrackMe程序

從上圖中可以看出,整個程序只有兩個可以輸入內容的編輯框,和兩個可以單擊的按鈕,除此之外什麼都沒有了,更不會有什麼提示。在界面上輸入一個賬號和密碼,單擊“確定”按鈕後,執行生成密碼的算法,如果密碼匹配則提示“密碼正確”,否則提示“密碼錯誤”。生成密碼算法是通過輸入的賬號來生成密碼的,而不是有固定的賬號和固定的密碼進行一一對應的。(賬號的長度必須大於7位)

測試一下,輸入一個小於7位的賬號,再隨便輸入一個密碼,單擊“確定”按鈕,這時候程序不會有任何反應。那麼,輸入一個超過7位的賬號,單擊“確定”按鈕來試試,如下圖所示。

FristCrack

EasyCrackMe提示“密碼錯誤”。當然了,密碼是根據賬號算出來的,而且和賬號的長度是相等的。那麼該如何獲得這個EasyCrackMe的密碼呢?如果這個EasyCrackMe不是我們寫的,那我們該怎麼辦?接下來的工作,就交給OllyDbg來完成吧。


OllyDbg是一種強大的Win32調試工具,用戶界面直觀、簡潔,支持插件擴展功能,用戶可以免費下載。它體積小,運行速度快,很多逆向分析人員都喜歡使用。

用OD破解EasyCrackMe

對於破解來說,總是要找到一個突破點的,而對於這個簡單的EasyCrackMe來說,突破點是非常多的。下面會以不同的方式來開始這次破解之旅。

破解方法一

用OD打開EasyCrackMe

OD打開EasyCrackMe

首先來梳理一下思路。輸入了“賬號”及“密碼”後,首先程序會從編輯框處獲得“賬號”的字符串及“密碼”的字符串,然後進行一系列的比較驗證,再通過“賬號”來計算出正確的“密碼”,最後來匹配正確的“密碼”與輸入的“密碼”是否一致,根據匹配結果,給出相應的提示。

上面是EasyCrackMe代碼的流程和思路,我們也可根據這個思路合理地設置斷點(設置斷點也叫下斷點)。“斷點”就是產生中斷的位置。通過下斷點,可以讓程序中斷在需要調試或分析的地方。下斷點在調試中起着非常大的作用,學會在合理的地方下斷點也是一個技巧性的知識。

現在就可以選擇合適的地方設置斷點了。可以在API函數上設置斷點,比如在GetDlgltemText()行設置斷點,也可以選擇在strlen()上設置斷點,還可以在strcmp()上設置斷點,甚至可以在MessageBox()上設置斷點。上面的這些API函數都是可以設置斷點的,但是對於GetDlgItemText()和MessageBox()這兩個API函數來說,需要下斷點的時候指定是ANSI版本,還是UNICODE版本。也就是說系統中是沒有這兩個函數的,根據版本的不同存在系統的函數只有GetDlgltemTextA()、GetDlgltemTextW()、MessageBoxA()和MessageBoxW()這樣的函數。通常使用ANSI版本的即可。

上面有如此多的API函數可供我們設置斷點,那麼要選擇哪個進行設置呢?最好的選擇是strcmp()這個函數,因爲在比較函數處肯定會出現正確的“密碼”。而在GetDlgltemTexA()和strlen()上設置斷點,需要使用F8進行跟蹤。如果在MessageBoxA()上設置斷點,那麼就不容易找到正確的“密碼”存放的位置了。所以選擇在strcmp()上設置斷點。在“命令”窗口中輸入“bp strcmp”,然後回車,如下圖所示。

bp strcmp

如何知道斷點是否設置成功呢?按下Alt+B組合鍵打開斷點窗口可以查看,如下圖所示。

Alt+B

斷點已經設置好了,按F9鍵運行程序。EasyCrackMe啓動了,輸入“賬號”爲“UserTest”,然後隨便輸入一個“密碼”爲“123456”,單擊“確定”按鈕,OD中斷在斷點,如下圖所示。

OD中斷在斷點

從上圖中可以看到,OD斷在了strcmp這個函數的首地址處,地址爲10218B80。斷在這裏如何找到真正的密碼呢?其實在提示的地方已經顯示出了正確的密碼,我們可以看棧窗口。函數參數的傳遞是依賴於棧的,對於C語言來說,函數的參數是從右往左依次入棧的。

對於strcmp()函數來說,該函數有兩個參數,這兩個參數分別是要進行比較的字符串。那麼在棧窗口中可以看到輸入的密碼及正確的密碼,如下圖所示。

密碼

可以看到,在調用strcmp()時,傳遞的兩個參數的值分別是“123456”和“VtfsUftu”兩個字符串。前面的字符串肯定是輸入的密碼,那麼後面的字符串肯定就是正確的密碼了。現在關閉OD,直接打開EasyCrackMe,現在仍然用剛纔的賬號“UserTest”,然後輸入密碼“VtfsUftu”,單擊“確定”按鈕,會提示“密碼正確”,如下圖所示。

密碼正確

破解方法二

在上一種方法中通過對API函數設置斷點找到了正確的密碼,現在通過提示字符串來完成破解。在不知道正確密碼的情況下輸入密碼,通常會得到的提示字符串是“密碼錯誤”,只要在程序中尋找該字符串,並且查看是何處使用了該字符串,那麼就可以對破解起到提示性的作用。

用OD打開EasyCrackMe程序,在反彙編界面處單擊鼠標右鍵,在彈出的菜單中依次選擇“超級字串參考”->“查找ASCII”命令,會出現“超級字串參考”窗口。

超級字串參考

在“超級字串參考”窗口中,雙擊“密碼正確”這個字符串

雙擊“密碼正確”

從上圖中可以看到3處比較關鍵性的內容,第一個是可以看到strcmp()函數,第二個是可以看到字符串“密碼正確”,第三個是可看到字符串“密碼錯誤”。由這3個內容可以讓我們聯想到這豈不是和C代碼基本上是對應的啊。根據strcmp()的比較結果,if……else…..會選擇不同的流程進行執行。也就是說,只要改變比較的結果,或者更換比較的條件,都可以改變程序的流程。

strcmp()是字符串比較函數,如果兩個字符串相等也就是說輸入的密碼與正確的密碼匹配,匹配則執行“密碼正確”流程,否則反之。那麼如果修改一下比較的條件,也就是說兩個密碼匹配不成功,使其執行“密碼正確”的流程。這樣,輸入錯誤的密碼,也會提示“密碼正確”的提示。

對於反彙編應該如何做呢?其實非常簡單,我們再回過頭來看一下上面截圖中的那幾條反彙編代碼。想要修改其判斷條件,那麼只要修改00401EA8處的指令代碼jnz short EasyCrac.00401EBD即可,該指令的意思是如果比較結果不爲0,則跳轉到00401EBD處執行。jnz結果不爲0則跳轉,只要把jnz修改爲jz即可,jz的意思剛好與jnz相反。修改的方法很簡單,選中00401EA8地址所在的行,按下空格鍵進行編輯

選中jnz

修改前

把jnz修改爲jz

把jnz修改爲jz

單擊窗口上的“彙編”按鈕,然後按F9鍵運行,隨便輸入一個長度大於7位的賬號,再輸入一個密碼,然後單擊“確定”按鈕,會提示“密碼正確”,如下圖所示。

修改指令後的流程

關掉OD和EasyCrackMe,然後直接運行EasyCrackMe,隨便輸入密碼和賬號,單擊“確定”按鈕後提示密碼錯誤。爲什麼呢?因爲剛纔只是在內存中進行了修改,需要對文件進行存盤在以後運行時我們的修改纔有效。


上面就是兩種破解該EasyCrackMe的方法,這兩種方法都是極其簡單的方法,現在可能已經很不實用了。這裏是爲了學習,爲了提高動手能力,而採用了這兩種方法。

發佈了177 篇原創文章 · 獲贊 78 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章