首页 > 代码库 > OllyDbg 使用笔记 (八)
OllyDbg 使用笔记 (八)
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,即可破解。