OllyDbg 使用筆記 (八)
參考
書:《加密與解密》
視頻:小甲魚 解密系列 視頻
示例程序下載:http://pan.baidu.com/s/1jG5NKBs
分析
這個程序,未註冊版本限制了一些功能。
嘗試在register界面寫入email和密鑰
會彈出註冊未成功的窗口。可以利用窗口中的文字作爲突破口。在OD中 查找 所有參考文本字串
圖片1
暴力破解
查看 未註冊成功後彈出窗口中的字符串的代碼:
004299AB . 57 push edi
004299AC . 50 push eax
004299AD . E8 9AD7FDFF call 0040714C
004299B2 . 59 pop ecx
004299B3 . 33DB xor ebx, ebx
004299B5 84C0 test al, al
004299B7 . 59 pop ecx
004299B8 . 53 push ebx
004299B9 75 36 jnz short 004299F1
004299BB . 6A 30 push 30
004299BD . 68 70134C00 push 004C1370 ; ASCII "You have entered an invalid email address or license number. Please try again."
004299C2 . E8 74270800 call 004AC13B
004299C7 . 8D8E 20010000 lea ecx, dword ptr [esi+120]
004299CD . E8 567CFDFF call 00401628
004299D2 . 8BCF mov ecx, edi
004299D4 . E8 4F7CFDFF call 00401628
004299D9 . 53 push ebx
004299DA . 8BCE mov ecx, esi
004299DC . E8 D5A60700 call 004A40B6
004299E1 . 8D8E 7C010000 lea ecx, dword ptr [esi+17C]
004299E7 . E8 83D00700 call 004A6A6F
004299EC . E9 29010000 jmp 00429B1A
004299F1 > 6A 40 push 40
004299F3 . 68 50134C00 push 004C1350 ; ASCII "Thank you for registering!"
004299F8 . E8 3E270800 call 004AC13B
004299FD . 6A 01 push 1
004299FF . 8BCE mov ecx, esi
00429A01 . E8 2F8E0700 call 004A2835
00429A06 . E8 C1E9FDFF call 004083CC
可以發現 jnz short 004299F1 很關鍵。但是如果只是吧jnz short 004299F1 改成 jmp short 004299F1,只是在點擊註冊時,出現 "Thank you for registering!" 窗口,實質還是沒有註冊。
可以看看jnz short 004299F1 前面的代碼,影響它跳不跳的是 test al, al,影響al是前面的call 0040714C。call 0040714C很關鍵,下斷點,重新運行,F7進入。
進入call 0040714C可以看到下面的代碼
0040714C $ 55 push ebp
0040714D . 8BEC mov ebp, esp
0040714F . FF75 0C push dword ptr [ebp+C]
00407152 . FF75 08 push dword ptr [ebp+8]
00407155 . E8 77FEFFFF call 00406FD1
0040715A . 84C0 test al, al
0040715C . 59 pop ecx
0040715D . 59 pop ecx
0040715E . A2 A0765000 mov byte ptr [5076A0], al
00407163 . 75 1B jnz short 00407180
00407165 . FF75 0C push dword ptr [ebp+C]
00407168 . FF75 08 push dword ptr [ebp+8]
0040716B . E8 ADFEFFFF call 0040701D
00407170 . 84C0 test al, al
00407172 . 59 pop ecx
00407173 . 59 pop ecx
00407174 . A2 A0765000 mov byte ptr [5076A0], al
00407179 . A2 A2765000 mov byte ptr [5076A2], al
0040717E . 74 0D je short 0040718D
00407180 > FF75 0C push dword ptr [ebp+C]
00407183 . FF75 08 push dword ptr [ebp+8]
00407186 . E8 45F8FFFF call 004069D0
0040718B . 59 pop ecx
0040718C . 59 pop ecx
0040718D > 5D pop ebp
0040718E .^ E9 D6FEFFFF jmp 00407069
00407193 /$ 56 push esi
00407194 |. FF7424 08 push dword ptr [esp+8]
00407198 |. 8BF1 mov esi, ecx
0040719A |. 8366 04 00 and dword ptr [esi+4], 0
我們可以看到前面有兩個call :call 00406FD1跟call 0040701D。這個倆個call前後的代碼都差不多。邊觀察 eax寄存器,邊按F8單步運行,可以發現,如果第一個call之後如果al==0 就會執行第二個call,如果a!=0就不會執行第二個call,可以猜想,第二個call只是多一次驗證,防止錯誤。
在第一個call下斷點,重新運行進入。
進入call 00406FD1 可以看到:
00406FD1 /$ B8 AB374B00 mov eax, 004B37AB
00406FD6 |. E8 EDF00700 call 004860C8
00406FDB |. 51 push ecx
00406FDC |. 53 push ebx
00406FDD |. FF35 A4415000 push dword ptr [5041A4] ; MrBills.004BA704
00406FE3 |. 8D4D F0 lea ecx, dword ptr [ebp-10]
00406FE6 |. E8 84B1FFFF call 0040216F
00406FEB |. FF75 0C push dword ptr [ebp+C]
00406FEE |. 8365 FC 00 and dword ptr [ebp-4], 0
00406FF2 |. FF75 08 push dword ptr [ebp+8]
00406FF5 |. 8D45 F0 lea eax, dword ptr [ebp-10]
00406FF8 |. 50 push eax
00406FF9 |. E8 4DFFFFFF call 00406F4B
00406FFE |. 8B4D F0 mov ecx, dword ptr [ebp-10]
00407001 |. 83C4 0C add esp, 0C
00407004 |. 83C1 F0 add ecx, -10
00407007 |. 8AD8 mov bl, al
00407009 |. E8 3AA1FFFF call 00401148
0040700E |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00407011 8AC3 mov al, bl
00407013 |. 5B pop ebx
00407014 |. 64:890D 00000>mov dword ptr fs:[0], ecx
0040701B |. C9 leave
0040701C \. C3 retn
邊按F8,邊觀察al,可以發現call 00406F4B很關鍵,call 00406F4B後al就變爲0。可以發現,下面這段代碼也很關鍵
00407007 |. 8AD8 mov bl, al
00407009 |. E8 3AA1FFFF call 00401148
0040700E |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00407011 8AC3 mov al, bl
運行 call 00401148前它把al保存起來,然後又恢復al,說明 call 00401148要用到al。
可以利用mov al, bl,把它改成mov al, 1,即可破解。