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,即可破解。