OllyDbg 使用笔记 (十三)

OllyDbg 使用笔记 (十三)


参考

书:《加密与解密》

视频:小甲鱼 解密系列 视频


示例程序下载地址:http://pan.baidu.com/s/1hqBrJWo


方法一:内嵌补丁


加载程序,按F9运行,点击Enter Reg.Code 输入name,key等,先不要按OK ,到OD中 按Ctrl+N打开输入输出表,搜索KillTimer,设置断点。再点击注册窗口的OK,我们可以看见:

(也可以通搜索注册失败时弹出窗口中的“The registration code seems to be not valid” 来找到下面代码)

004DC19D   > \83F8 03       cmp     eax, 3
004DC1A0   .  75 1E         jnz     short 004DC1C0
004DC1A2   .  8B57 1C       mov     edx, dword ptr [edi+1C]          ;  Case 3 of switch 004DBDA4
004DC1A5   .  50            push    eax                              ; /TimerID
004DC1A6   .  52            push    edx                              ; |hWnd
004DC1A7   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC1AD   .  6A 00         push    0
004DC1AF   .  6A 00         push    0
004DC1B1   .  68 5C666400   push    0064665C                         ;  ASCII "The registration code seems to be not valid.",LF,"Please check if you didn't made any mistake."
004DC1B6   .  E8 919D0D00   call    005B5F4C
004DC1BB   .  E9 B7000000   jmp     004DC277
004DC1C0   >  83F8 04       cmp     eax, 4
004DC1C3   .  75 1E         jnz     short 004DC1E3
004DC1C5   .  50            push    eax                              ; /TimerID; Case 4 of switch 004DBDA4
004DC1C6   .  8B47 1C       mov     eax, dword ptr [edi+1C]          ; |
004DC1C9   .  50            push    eax                              ; |hWnd
004DC1CA   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC1D0   .  6A 00         push    0
004DC1D2   .  6A 00         push    0
004DC1D4   .  68 FC656400   push    006465FC                         ;  ASCII "Thank you for your support!",LF,"Please Exit the Software and start it again to validate the code."
004DC1D9   .  E8 6E9D0D00   call    005B5F4C
004DC1DE   .  E9 94000000   jmp     004DC277
004DC1E3   >  83F8 05       cmp     eax, 5
004DC1E6   .  75 15         jnz     short 004DC1FD
004DC1E8   .  8B4F 1C       mov     ecx, dword ptr [edi+1C]          ;  Case 5 of switch 004DBDA4
004DC1EB   .  50            push    eax                              ; /TimerID
004DC1EC   .  51            push    ecx                              ; |hWnd
004DC1ED   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC1F3   .  6A FF         push    -1                               ; /ExitCode = FFFFFFFF
004DC1F5   .  FF15 D0545E00 call    dword ptr [<&KERNEL32.ExitProces>; \ExitProcess
004DC1FB   .  EB 7A         jmp     short 004DC277
004DC1FD   >  83F8 06       cmp     eax, 6
004DC200   .  75 0D         jnz     short 004DC20F
004DC202   .  8B57 1C       mov     edx, dword ptr [edi+1C]          ;  Case 6 of switch 004DBDA4
004DC205   .  50            push    eax                              ; /TimerID
004DC206   .  52            push    edx                              ; |hWnd
004DC207   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC20D   .  EB 68         jmp     short 004DC277
004DC20F   >  83F8 0A       cmp     eax, 0A
004DC212   .  75 2D         jnz     short 004DC241
004DC214   .  50            push    eax                              ; /TimerID; Case A of switch 004DBDA4
004DC215   .  8B47 1C       mov     eax, dword ptr [edi+1C]          ; |
004DC218   .  50            push    eax                              ; |hWnd
004DC219   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC21F   .  8B17          mov     edx, dword ptr [edi]
004DC221   .  8BCF          mov     ecx, edi
004DC223   .  FF92 C0000000 call    dword ptr [edx+C0]
004DC229   .  85C0          test    eax, eax
004DC22B   .  74 4A         je      short 004DC277
004DC22D   .  8BC8          mov     ecx, eax
004DC22F   .  E8 772D0E00   call    005BEFAB
004DC234   .  85C0          test    eax, eax
004DC236   .  74 3F         je      short 004DC277
004DC238   .  8BC8          mov     ecx, eax
004DC23A   .  E8 F13EFEFF   call    004C0130
004DC23F   .  EB 36         jmp     short 004DC277
004DC241   >  83F8 0B       cmp     eax, 0B
004DC244   .  75 31         jnz     short 004DC277
004DC246   .  50            push    eax                              ; /TimerID; Case B of switch 004DBDA4
004DC247   .  8B47 1C       mov     eax, dword ptr [edi+1C]          ; |
004DC24A   .  50            push    eax                              ; |hWnd
004DC24B   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DC251   .  E8 F3570E00   call    005C1A49
004DC256   .  8B40 04       mov     eax, dword ptr [eax+4]
004DC259   .  6A 00         push    0
004DC25B   .  68 B03C6400   push    00643CB0                         ;  ASCII "ResetToolbars"
004DC260   .  68 1CF16300   push    0063F11C                         ;  ASCII "Settings"
004DC265   .  8BC8          mov     ecx, eax
004DC267   .  E8 255C0E00   call    005C1E91
004DC26C   .  85C0          test    eax, eax
004DC26E   .  74 07         je      short 004DC277
004DC270   .  8BCF          mov     ecx, edi
004DC272   .  E8 99190000   call    004DDC10
004DC277   >  8BCF          mov     ecx, edi                         ;  Default case of switch 004DBDA4
004DC279   .  E8 51040D00   call    005AC6CF
004DC27E   .  8B4D F4       mov     ecx, dword ptr [ebp-C]
004DC281   .  5F            pop     edi
004DC282   .  5E            pop     esi
004DC283   .  5B            pop     ebx
004DC284   .  64:890D 00000>mov     dword ptr fs:[0], ecx
004DC28B   .  8BE5          mov     esp, ebp
004DC28D   .  5D            pop     ebp
004DC28E   .  C2 0400       retn    4




这些代码其实是 swith,现在代码eax为3,正要运行case 3 处的代码。观察每个case,可以发现 case 4 中的"Thank you for your support!",我们可以知道可能case 4 就是注册成功。我们就要想办法把swith 3 改成 swith 4。


我们先前看看,看看swith开始的代码


004DBD80   .  55            push    ebp
004DBD81   .  8BEC          mov     ebp, esp
004DBD83   .  6A FF         push    -1
004DBD85   .  68 17B85D00   push    005DB817                         ;  SE 处理程序安装
004DBD8A   .  64:A1 0000000>mov     eax, dword ptr fs:[0]
004DBD90   .  50            push    eax
004DBD91   .  64:8925 00000>mov     dword ptr fs:[0], esp
004DBD98   .  81EC 68010000 sub     esp, 168
004DBD9E   .  8B45 08       mov     eax, dword ptr [ebp+8]
004DBDA1   .  53            push    ebx
004DBDA2   .  56            push    esi
004DBDA3   .  57            push    edi
004DBDA4   .  83F8 01       cmp     eax, 1                           ;  Switch (cases 1..B)
004DBDA7   .  8BF9          mov     edi, ecx
004DBDA9   .  75 53         jnz     short 004DBDFE
004DBDAB   .  50            push    eax                              ; /TimerID; Case 1 of switch 004DBDA4
004DBDAC   .  8B47 1C       mov     eax, dword ptr [edi+1C]          ; |
004DBDAF   .  50            push    eax                              ; |hWnd
004DBDB0   .  FF15 B4575E00 call    dword ptr [<&USER32.KillTimer>]  ; \KillTimer
004DBDB6   .  E8 8E5C0E00   call    005C1A49



在004DBD80   下断点,删除前面KillTimer设置的断点,重新运行程序。多按几次F9(下断点处的地方,在程序界面产生前就调用了,所以多按几次F9),可以看到程序的界面,打开注册窗口,输入信息,点击OK,发现程序断在前面下断点的地方。

按F8单步运行, 可以发现 mov     eax, dword ptr [ebp+8] ,就是设置swith中eax的值。可以尝试把它改成mov eax ,4,但是我们可以发现原来的代码占用3个字节,改后的代码占用5个字节,后面的代码push    ebx, push    esi被覆盖了。


这时我们可以用内嵌补丁,先把mov     eax, dword ptr [ebp+8]改成jmp xxx到空白的代码处,再在空白的代码处写上要执行的代码,再跳回来。


这里我们可以把mov     eax, dword ptr [ebp+8]  改成jmp     005E47CC

再在005E47CC 写上下面的代码

005E47CB      00            db      00
005E47CC      B8 04000000   mov     eax, 4
005E47D1   .  53            push    ebx
005E47D2   .  56            push    esi
005E47D3   .^ E9 CB75EFFF   jmp     004DBDA3
005E47D8      00            db      00


复制到可执行程序,正常运行程序,可以发现,程序打开时一直弹出"Thank you for your support!"的窗口。调试改后的程序,我们可以发现原来程序一直在循环的执行swith,因为我们改成了switch 4,所以一直弹出"Thank you for your support!"的窗口。其实这个程序只是因为过期后前面有一个让我们输入key的nag窗口而不可以使用,我们只要让这个nag窗口不出现就可以了。我们可以让他switc  0B,0b既不会弹出“The registration code seems to be not valid” 窗口,也不会弹出"Thank you for your support!"的窗口。把  mov     eax, 4  改成  mov     eax, 0b 复制到可执行程序,再正常运行程序,可以发现程序可以正常运行。



方法二: 查看调用堆栈


此程序,因为产生了一个不可以跳过的nag窗口而不能使用,可以通过改变跳转,使程序不执行nag窗口的代码,来破解。


查找产生nag窗口的代码


重新加载程序,删掉前面设置的断点,按F9运行程序,看到nag窗口出现时,暂停程序,按 alt+K 查看堆栈调用,


图片1

OllyDbg 使用笔记 (十三)

点击最下面的 ”调用来自“。查看代码(点击 函数过程 是看函数的具体代码,点击 调用来自 是看call)


在这个call上下断点,重新运行程序,

图片2

OllyDbg 使用笔记 (十三)


可以发现真是这个call产生了nag窗口。


查找这段代码的开头(即找push ebp)

图片3

OllyDbg 使用笔记 (十三)

在push ebp 下断点重新运行程序,按F9运行,来到断点处。

按F8单步运行,变按边注意跳转,改变寄存器 ,使程序跳过call    005ABE4D。


可以发现只要使 jnz     short 004DBDE6 不跳转即可以实现跳过call    005ABE4D。









OllyDbg 使用笔记 (十三)

上一篇:干货-vue 中使用 rxjs 进行非父子组件中传值


下一篇:源码编译 apache2.4