天天看點

偶爾發個CrackMe的逆向~

朋友面試,和HR确認過眼神後,HR發了一個CrackMe給他,讓他逆向後給出算法和答案。出于練手的目的(剛接觸...),我把這個CM要過來,它長這樣,嗯,醜陋的MFC工程:

偶爾發個CrackMe的逆向~

先随便往文本框輸入個值,點旁邊的Button,得到顯示結果的MessageBox:

偶爾發個CrackMe的逆向~

朋友面逆向工程用的CM,可能會帶殼吧?用peid查殼,什麼都沒發現,莫非真有殼?

偶爾發個CrackMe的逆向~

想來這是我第一次做CM,怯場總不好吧,硬着頭皮把CM拖進IDA,發現自己想多了:

1.字元串"error"随手可以找到,毫無隐瞞的存放在".rdata"區:

偶爾發個CrackMe的逆向~
偶爾發個CrackMe的逆向~

2.點選"Xref to"可以馬上定位到對"error"的引用,更重要的,在"error"附近還能看到對字元串"ok"的引用。往上翻,可以看到call/cmp/jnz語句,應該先調用函數進行某種計算,将傳回值同輸入比較,相同就彈OK框,否則就彈error框。

偶爾發個CrackMe的逆向~

看來這個CM也沒有特别刁難我朋友,隻是簡單刷了一把投履歷的。繼續正題,cmp esi,eax中的esi來自哪?再往上看看,至少遇到三個GetDlgItemInt----從控件中獲得值。正好UI上有3個Edit框,十有八九就是從它們這獲得值。至于獲得的是什麼值,需要動态調試一把。

偶爾發個CrackMe的逆向~

實不相瞞,Ollydbg我不會,那就上windbg,先搜尋GetDlgItemInt,然後下函數斷點既是:

偶爾發個CrackMe的逆向~
偶爾發個CrackMe的逆向~

當windbg中斷時,檢視第一幀調用棧,程式壓入的傳回位址是0x00331303,反彙編傳回位址之後的代碼,并再次下斷點,用于獲得函數傳回值:

偶爾發個CrackMe的逆向~

當程式從GetDlgItemInt傳回時,獲得的傳回值是0x3039,16進制kanb看不懂,轉換成10進制吧,恩,居然是第一個左上角的Edit框中的值:12345,呵呵。同樣的手段,可以知道從左下角的Edit框獲得的數值用來和後面call/cmp/jnz進行比較。隻要獲得call的傳回值,就知道能産生OK消息框的數值了。

偶爾發個CrackMe的逆向~

在exe的偏移0x1330處下斷點,此時計算已經完成。(0x1330是IDA給出的偏移,IDA一般為32bit程式選擇加載基址是0x00400000,把這個偏移加上程式在windbg中的基址,就得到運作時call calc的傳回位址。PS:calc是我在IDA中修改的位址名,鬼知道真正的源碼中這個函數叫啥)。windbg很誠實的告訴我,calc傳回值是5040。呵呵,那就驗證一下是否如此?