“CrackMe”是很多逆向論壇里十分流行的玩法。
一些人為了測試自己的軟件保護技術,就會制作一些CrackMe程序,讓別人來嘗試破解。
網上也經常會有一些CM(CrackMe)競賽。
根據設計者的意圖和加密技術水平,不同的CrackMe,破解難度天差地遠。
江寒點擊了一下下載鏈接,題目給出的CrackMe,很快就下載了下來。
然后,先將其運行了起來,觀察一下程序的外在表現。
這是個WindowsPE文件,界面十分樸素,只提供了兩個輸入框。
一個用來輸入UserName(用戶名),另一個用來輸入SN(serialnumber,序列號),下面還有個【Login】按鈕,用來檢測UserName和SN是否匹配。
看完了這些內容,對程序的結構心里有數之后,江寒就將窗口關掉了。
隨后,他就打開了著名的調試工具OllyICE,并在調試器中加載了這個CrackMe。
開始調試之前,先設置個斷點。
斷點是調試器的一種功能,可以讓程序中斷在需要的地方,以方便分析。
常用的斷點有INT3斷點、硬件斷點、內存斷點、消息斷點、條件斷點等。
例如LBUTTON_UP,就是很常用的消息斷點,功能是當鼠標左鍵抬起時,中斷程序運行。
又如GetDlgItemText斷點,當程序試圖調用Windows的對應API,獲取輸入框里的文本內容時,就會被攔下。
江寒先試著設置了GetDlgItemText和GetDlgItemTextA斷點,然后按了下F9,讓程序跑了起來。
CrackMe的窗口出現后,先隨便輸入一組UserName和SN,然后用鼠標點擊了一下【Login】按鈕。
結果……
程序直接彈出了一個MsgBOX(消息框),提示【用戶名和序列號不匹配】。
很遺憾,在這次嘗試中,斷點并沒有發揮作用。
這說明在這個CrackMe里,并沒有使用GetDlgItemText或者GetDlgItemTextA來讀取字符串。
否則的話,就會被調試器攔截下來,而不會執行關鍵Call了。
所謂關鍵Call,是指程序中用來計算用戶名和序列號的函數,通常執行完關鍵Call,很快就能找到一個條件跳轉語句。
如果序列號與用戶名匹配,就會繼續往下執行,否則就彈出出錯提示……
接下來,江寒又試了一下LBUTTON_UP斷點。
這次終于成功斷了下來。
接下來就很簡單了,交替使用F7(步入)、F8(步過)兩個快捷鍵,單步跟蹤即可。
這個程序是那種很老實的程序。
意思就是沒有什么亂七八糟迷惑人的東西,也沒有刻意增加難度,為難挑戰者。
以江寒的調試功力,跟蹤這么老實的程序,自然是易如反掌。
他只花了3分鐘,就找到了關鍵Call。
隨后,將這個Call語句,設為斷點,然后Ctrl+F2,重新運行。
再次填寫序列號、用戶名,點【Login】……
很快,程序中斷在了關鍵Call上。
江寒按了一下F7,進入了函數體內部,這樣就看到了一段以Ret結尾的反匯編代碼。
這段代碼的功能,就是根據UserName計算SN(序列號)。
到了這里,就比較考驗基本功了,必須讀懂反匯編指令。
當然,這對于訓練有素的人來說,也是Soeasy的一件事。
江寒花了十分鐘,將算法分析了出來。
看得出來,設計者的確沒有故意難為人,算法設計得十分簡明。
首先,把UserName進行BASE64變換,然后對新串中的字符,做ASCII碼值累加操作,再經過一番算不上十分復雜的數學運算后,就得到了一個新的字符串。
此字符串就是與UserName對應的SN,其允許包含大小寫字母和數字,以及一些特殊字符,算法保證其與UserName對應的唯一性……
這道題可以說是白給,只要稍微懂點逆向調試,基本功別太差,一般都能輕松搞定。
江寒估計,官方第一關弄得這么簡單,可能只是打算過濾一下參賽者,將那些沒事兒來湊熱鬧的人排除掉。
接下來是第二題。
仍然是CrackMe,但和第一題比起來,難度就突然提高了十倍不止。
什么花指令、虛擬機、靜態反匯編、動態反調試……
凡是當前流行的保護手段,幾乎一應俱全。
而其核心算法,更是動用了SHA1和Md5。