[反彙編練習] 160個CrackMe之033.
本系列文章的目的是從一個沒有任何經驗的新手的角度(其實就是我自己),一步步嘗試將160個CrackMe全部破解,如果可以,通過任何方式寫出一個類似於註冊機的東西。
其中,文章中按照如下邏輯編排(解決如下問題):
1、使用什麼環境和工具
2、程序分析
3、思路分析和破解流程
4、註冊機的探索
----------------------------------
提醒各位看客: 如果文章中的邏輯看不明白,那你一定是沒有親手操刀!OD中的跳轉提示很強大,只要你跟蹤了,不用怎麼看代碼就理解了!
----------------------------------
1、工具和環境:
WinXP SP3 + 52Pojie六週年紀念版OD + PEID + 彙編金手指。
160個CrackMe的打包文件。
下載地址: http://pan.baidu.com/s/1xUWOY 密碼: jbnq
注:
1、Win7系統對於模塊和程序開啓了隨機初始地址的功能,會給分析帶來很大的負擔,所以不建議使用Win7進行分析。
2、以上工具都是在52PoJie論壇下的原版程序,NOD32不報毒,個人承諾絕對不會進行任何和木馬病毒相關內容。
2、程序分析:
想要破解一個程序,必須先了解這個程序。所以,在破解過程中,對最初程序的分析很重要,他可以幫助我們理解作者的目的和意圖,特別是對於註冊碼的處理細節,從而方便我們反向跟蹤和推導。
和上一節一樣,打開CHM,選擇第33個Cruehead.1.exe,保存下來。運行程序,程序界面如下:
有信息框,很好。
PEID:MASM32 / TASM32 [覆蓋]
彙編寫的程序啊!哎!要麼很簡單,要麼就很坑啦!
3、思路分析和破解流程
1、打開OD,將exe拖到OD窗口中,等程序暫停後,直接點擊運行按鈕(F9),不用理會。
2、點擊About->Register,隨意輸入僞碼:bbdxf 123123。點擊OK按鈕,彈出信息框,不要關閉,回到OD。
3、Ctrl+K查看堆棧信息:
選中Cruehead.0040137E,右鍵->Show calls
0040137E /$ 8B7424 04 mov esi,dword ptr ss:[esp+0x4] 00401382 |. 56 push esi ; // "bbdxf" 00401383 |> 8A06 /mov al,byte ptr ds:[esi] 00401385 |. 84C0 |test al,al 00401387 |. 74 13 |je short 0040139C 00401389 |. 3C 41 |cmp al,0x41 ; "A" 0040138B |. 72 1F |jb short 004013AC 0040138D |. 3C 5A |cmp al,0x5A ; "Z" 0040138F |. 73 03 |jnb short 00401394 00401391 |. 46 |inc esi 00401392 |.^ EB EF |jmp short 00401383 00401394 |> E8 39000000 |call 004013D2 ; // 如果在A-Z之間,則處理(+0x20) 00401399 |. 46 |inc esi 0040139A |.^ EB E7 \jmp short 00401383 0040139C |> 5E pop esi 0040139D |. E8 20000000 call 004013C2 ; // 處理完成在這裏處理 004013A2 |. 81F7 78560000 xor edi,0x5678 ; // 在這裏進行比較 004013A8 |. 8BC7 mov eax,edi 004013AA |. EB 15 jmp short 004013C1 004013AC |> 5E pop esi 004013AD |. 6A 30 push 0x30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL 004013AF |. 68 60214000 push 00402160 ; |Title = "No luck!" 004013B4 |. 68 69214000 push 00402169 ; |Text = "No luck there, mate!" 004013B9 |. FF75 08 push [arg.1] ; |hOwner 004013BC |. E8 79000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 004013C1 \> C3 retn
這段代碼只是將name分析處理了一下,如果不合格則跳轉到失敗。
我們選中這段代碼頭部,即0040137E地址處,OD提示:
Local call from 0040122D
我們轉到地址 0040122D,附近代碼如下:
00401228 . 68 8E214000 push 0040218E ; ASCII "BBDXF" 0040122D . E8 4C010000 call 0040137E 00401232 . 50 push eax ; // 比較之後來到這裏 00401233 . 68 7E214000 push 0040217E ; ASCII "123123" 00401238 . E8 9B010000 call 004013D8 0040123D . 83C4 04 add esp,0x4 ; // 再次處理之後 00401240 . 58 pop eax 00401241 . 3BC3 cmp eax,ebx 00401243 . 74 07 je short 0040124C 00401245 . E8 18010000 call 00401362 0040124A .^ EB 9A jmp short 004011E6 0040124C > E8 FC000000 call 0040134D ; // 這個跳轉到正確的提示 00401251 .^ EB 93 jmp short 004011E6
發現,這裏調用了大量的Call,我們一個個分析一下(註釋裏已經分析好了):
call 0040137E 內容: 0040137E /$ 8B7424 04 mov esi,dword ptr ss:[esp+0x4] 00401382 |. 56 push esi ; // "bbdxf" 00401383 |> 8A06 /mov al,byte ptr ds:[esi] 00401385 |. 84C0 |test al,al 00401387 |. 74 13 |je short 0040139C 00401389 |. 3C 41 |cmp al,0x41 ; "A" 0040138B |. 72 1F |jb short 004013AC 0040138D |. 3C 5A |cmp al,0x5A ; "Z" 0040138F |. 73 03 |jnb short 00401394 00401391 |. 46 |inc esi 00401392 |.^ EB EF |jmp short 00401383 00401394 |> E8 39000000 |call 004013D2 ; // 如果在A-Z之間,則處理(+0x20) 00401399 |. 46 |inc esi 0040139A |.^ EB E7 \jmp short 00401383 0040139C |> 5E pop esi 0040139D |. E8 20000000 call 004013C2 ; // 處理完成在這裏處理 004013A2 |. 81F7 78560000 xor edi,0x5678 ; // 在這裏進行比較 004013A8 |. 8BC7 mov eax,edi 004013AA |. EB 15 jmp short 004013C1 004013AC |> 5E pop esi 004013AD |. 6A 30 push 0x30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL 004013AF |. 68 60214000 push 00402160 ; |Title = "No luck!" 004013B4 |. 68 69214000 push 00402169 ; |Text = "No luck there, mate!" 004013B9 |. FF75 08 push [arg.1] ; |hOwner 004013BC |. E8 79000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 004013C1 \> C3 retn 其中,call 004013D2 內容: 004013D2 /$ 2C 20 sub al,0x20 004013D4 |. 8806 mov byte ptr ds:[esi],al 004013D6 \. C3 retn 其中,call 004013C2 內容: 004013C2 /$ 33FF xor edi,edi 004013C4 |. 33DB xor ebx,ebx 004013C6 |> 8A1E /mov bl,byte ptr ds:[esi] 004013C8 |. 84DB |test bl,bl 004013CA |. 74 05 |je short 004013D1 004013CC |. 03FB |add edi,ebx ; // edi=循環求和 004013CE |. 46 |inc esi 004013CF |.^ EB F5 \jmp short 004013C6 004013D1 \> C3 retn Call 004013D8 內容: 004013D8 /$ 33C0 xor eax,eax 004013DA |. 33FF xor edi,edi 004013DC |. 33DB xor ebx,ebx 004013DE |. 8B7424 04 mov esi,dword ptr ss:[esp+0x4] 004013E2 |> B0 0A /mov al,0xA 004013E4 |. 8A1E |mov bl,byte ptr ds:[esi] ; // "123123" 004013E6 |. 84DB |test bl,bl 004013E8 |. 74 0B |je short 004013F5 004013EA |. 80EB 30 |sub bl,0x30 ; // +0x30 004013ED |. 0FAFF8 |imul edi,eax ; // edi/10 004013F0 |. 03FB |add edi,ebx ; // edi+ebx 004013F2 |. 46 |inc esi 004013F3 |.^ EB ED \jmp short 004013E2 004013F5 |> 81F7 34120000 xor edi,0x1234 004013FB |. 8BDF mov ebx,edi 004013FD \. C3 retn call 0040134D 的內容: 0040134D /$ 6A 30 push 0x30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL 0040134F |. 68 29214000 push 00402129 ; |Title = "Good work!" 00401354 |. 68 34214000 push 00402134 ; |Text = "Great work, mate! Now try the next CrackMe!" 00401359 |. FF75 08 push [arg.1] ; |hOwner 0040135C |. E8 D9000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA 00401361 \. C3 retn
哈哈,大概流程是這樣的,地址00401228開始,將Name和Serial分別經過call運算,通過00401241 . 3BC3 cmp eax,ebx 比較,然後根據結果跳轉到不同的處理,其中,0040124C > E8 FC000000 call 0040134D 是提示正確的處理流程。所以,我們只要00401243 . 74 07 je short 0040124C改爲jmp 0040124C,試一試:
4、註冊機的探索
算法處理如下:
1、Name字符串,先判斷是否在A-Z之間,然後每個字符ANSII值加上0x20,然後對計算後的值求和,最後與0x5678異或。
2、Serial字符串,每個字符ANSII值加上0x30,然後加上上一次的和除以10的值,存到一個變量中,繼續下一個,最後與0x1234異或。
3、比較最後的結果。
…..我想想不出來這樣的兩個字符串,我也沒辦法反計算,所以,這有作罷!
BY BBDXF