飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3885|回复: 2

[原创] CD/DVD Data Recovery V1.0.01281的算法分析

[复制链接]

该用户从未签到

发表于 2007-12-29 16:20:47 | 显示全部楼层 |阅读模式
查壳,无!
OD载入,输入试炼码,有提示,查找参考字符………………
找到关键段的段首后,F8单步:
====================================================
0041A980  /.  55            push    ebp
0041A981  |.  8BEC          mov     ebp, esp
0041A983  |.  83EC 20       sub     esp, 20

………………
0041A999  |.  E8 F210FFFF   call    0040BA90  //取用户名的长度
0041A99E  |.  83F8 02       cmp     eax, 2     ;  用户名必须大于2位
0041A9A1  |.  7D 13         jge     short 0041A9B6
0041A9A3  |.  6A 00         push    0
0041A9A5  |.  6A 00         push    0
0041A9A7  |.  68 F8E34400   push    0044E3F8                         ;  please input correct user name!


0041A9BC  |.  E8 CF10FFFF   call    0040BA90  //取注册码的长度
0041A9C1  |.  83F8 08       cmp     eax, 8                           ;  注册码必须>=8位
0041A9C4  |.  7D 13         jge     short 0041A9D9
0041A9C6  |.  6A 00         push    0
0041A9C8  |.  6A 00         push    0
0041A9CA  |.  68 18E44400   push    0044E418                         ;  please input correct registration code!


0041A9D9  |> \6A 00         push    0                                ; /Arg1 = 00000000
0041A9DB  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041A9DE  |.  83C1 70       add     ecx, 70                          ; |
0041A9E1  |.  E8 0ACEFFFF   call    004177F0                         ; \F7进入,频繁调用,涉及算法
        //下面一大堆都是调用这个函数,呵呵,调用的形式如:
            int func1(int i,char* str)
            作用:取指定字符串中的i位的字符

*****************************
子函数:CALL 004177F0:
*****************************
004177F3  |.  51            push    ecx
        //
004177F4  |.  894D FC       mov     dword ptr [ebp-4], ecx
004177F7  |.  837D 08 00    cmp     dword ptr [ebp+8], 0
004177FB  |.  7C 0D         jl      short 0041780A
004177FD  |.  8B4D FC       mov     ecx, dword ptr [ebp-4]
00417800  |.  E8 8B42FFFF   call    0040BA90
00417805  |.  3945 08       cmp     dword ptr [ebp+8], eax
00417808  |.  7E 0A         jle     short 00417814
0041780A  |>  68 57000780   push    80070057                    ; /Arg1 = 80070057
0041780F  |.  E8 5C36FFFF   call    0040AE70                    ; \CDDVDDR.0040AE70
00417814  |>  8B45 FC       mov     eax, dword ptr [ebp-4]
00417817  |.  8B08          mov     ecx, dword ptr [eax]
00417819  |.  8B55 08       mov     edx, dword ptr [ebp+8]
0041781C  |.  8A0411        mov     al, byte ptr [ecx+edx]

先是对用户名的前两位各取了两次:
0041A9D9  |> \6A 00         push    0                                ; /Arg1 = 00000000
0041A9DB  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041A9DE  |.  83C1 70       add     ecx, 70                          ; |
0041A9E1  |.  E8 0ACEFFFF   call    004177F0                         ; \CDDVDDR.004177F0
0041A9E6  |.  8845 EF       mov     byte ptr [ebp-11], al            ;  取用户名的第1个字符
0041A9E9  |.  6A 01         push    1                                ; /Arg1 = 00000001
0041A9EB  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041A9EE  |.  83C1 70       add     ecx, 70                          ; |
0041A9F1  |.  E8 FACDFFFF   call    004177F0                         ; \CDDVDDR.004177F0
0041A9F6  |.  8845 F8       mov     byte ptr [ebp-8], al             ;  取用户名第2位
0041A9F9  |.  6A 00         push    0                                ; /Arg1 = 00000000
0041A9FB  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041A9FE  |.  83C1 70       add     ecx, 70                          ; |
0041AA01  |.  E8 EACDFFFF   call    004177F0                         ; \CDDVDDR.004177F0
0041AA06  |.  8845 FF       mov     byte ptr [ebp-1], al
0041AA09  |.  6A 01         push    1                                ; /Arg1 = 00000001
0041AA0B  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041AA0E  |.  83C1 70       add     ecx, 70                          ; |
0041AA11  |.  E8 DACDFFFF   call    004177F0                         ; \CDDVDDR.004177F0

然后分别对取出的4位进行运算:
0041AA19  |.  0FB645 EF     movzx   eax, byte ptr [ebp-11]
0041AA1D  |.  83C8 43       or      eax, 43
0041AA20  |.  8845 EF       mov     byte ptr [ebp-11], al

只是其中的常量在改变,呵呵…………
换位表达如:
*******************************************************
第1位------->EAX------->EAX=EAX OR 43
AL------->[ebp-11]
第2位------->ECX------->ECX=ECX OR 44
CL------->[ebp-8]
第1位------->EDX------->EDX=EAX OR 52
DL------->[ebp-1]
第2位------->EAX------->ECX=ECX OR 44
CL------->[ebp-6]

继续对取出的4位计算,方式如:
0041AA41  |.  0FB645 EF     movzx   eax, byte ptr [ebp-11]
0041AA45  |.  99            cdq
0041AA46  |.  B9 0A000000   mov     ecx, 0A
0041AA4B  |.  F7F9          idiv    ecx
0041AA4D  |.  8855 EF       mov     byte ptr [ebp-11], dl

其实也就是一个求余的运算,换位表达如下:
[ebp-11]=[ebp-11] MOD A
[ebp-8]=[ebp-8] MOD A
[ebp-1]=[ebp-1] MOD A
[ebp-6]=[ebp-6] MOD A

又是一个大循环:
0041AA7D  |.  C745 F0 00000>mov     dword ptr [ebp-10], 0
0041AA84  |.  C745 E8 00000>mov     dword ptr [ebp-18], 0            ;  相当于计时器
0041AA8B  |.  EB 09         jmp     short 0041AA96
0041AA8D  |>  8B55 E8       /mov     edx, dword ptr [ebp-18]
0041AA90  |.  83C2 01       |add     edx, 1
0041AA93  |.  8955 E8       |mov     dword ptr [ebp-18], edx
0041AA96  |>  8B4D E0        mov     ecx, dword ptr [ebp-20]
0041AA99  |.  83C1 70       |add     ecx, 70
0041AA9C  |.  E8 EF0FFFFF   |call    0040BA90                        ;  子函数,取用户名LEN
0041AAA1  |.  3945 E8       |cmp     dword ptr [ebp-18], eax
0041AAA4  |.  7D 1E         |jge     short 0041AAC4
0041AAA6  |.  8B45 E8       |mov     eax, dword ptr [ebp-18]
0041AAA9  |.  50            |push    eax                             ; /Arg1
0041AAAA  |.  8B4D E0       |mov     ecx, dword ptr [ebp-20]         ; |
0041AAAD  |.  83C1 70       |add     ecx, 70                         ; |
0041AAB0  |.  E8 3BCDFFFF   |call    004177F0                        ; \CDDVDDR.004177F0
0041AAB5  |.  8845 E7       |mov     byte ptr [ebp-19], al
0041AAB8  |.  0FB64D E7     |movzx   ecx, byte ptr [ebp-19]
0041AABC  |.  034D F0       |add     ecx, dword ptr [ebp-10]
0041AABF  |.  894D F0       |mov     dword ptr [ebp-10], ecx
0041AAC2  |.^ EB C9         \jmp     short 0041AA8D                  ;  用户名各位字符的ASCII累加到EBP-10
0041AAC4  |>  8B45 F0       mov     eax, dword ptr [ebp-10]          ;  将累加值送入EAX

这个更清晰了,就是累加用户名各位的字符的ASCII
换位表达如下:
total=0;
for(i=0;i<len(name);i++)
        total+=name
然后将total MOD A求余,值送往[ebp-C]

接下来就是对注册码的判断了,看完了就会发现,其实上面做的一切就是“白搭”,呵呵
先假设一下,我们输入的注册码为code[n]
0041AAD2  |.  6A 00         push    0                                ; /Arg1 = 00000000
0041AAD4  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041AAD7  |.  83C1 74       add     ecx, 74                          ; |
0041AADA  |.  E8 11CDFFFF   call    004177F0                         ; \CDDVDDR.004177F0
0041AADF  |.  8845 FC       mov     byte ptr [ebp-4], al
……………………………………
0041AB42  |.  6A 07         push    7                                ; /Arg1 = 00000007
0041AB44  |.  8B4D E0       mov     ecx, dword ptr [ebp-20]          ; |
0041AB47  |.  83C1 74       add     ecx, 74                          ; |
0041AB4A  |.  E8 A1CCFFFF   call    004177F0                         ; \CDDVDDR.004177F0
0041AB4F  |.  8845 FB       mov     byte ptr [ebp-5], al

上面一段取码行为的结果就是:
[ebp-2]=code[6]
[ebp-3]=code[1]
[ebp-4]=code[0]
[ebp-5]=code[7]
[ebp-6]
[ebp-7]=code[4]
[ebp-8]
[ebp-9]=code[5]
[ebp-A]=code[2]
[ebp-B]=code[3]

看了一大堆,其实只需要这一段就OK了,
0041AB52  |.  0FB655 EF     movzx   edx, byte ptr [ebp-11]
0041AB56  |.  0FB645 FC     movzx   eax, byte ptr [ebp-4]
0041AB5A  |.  83E8 30       sub     eax, 30
0041AB5D  |.  3BD0          cmp     edx, eax
0041AB5F  |.  75 3C         jnz     short 0041AB9D

希望你没有那么不幸,刚好此处的跳转没跳,那样你可能要多走一段弯路,不过那样的机率很小,/:013 。
我很幸运,跳转实现了,直接来到了下面这段代码:
==========================================================
0041ABA1  |.  83F8 39       cmp     eax, 39
0041ABA4  |.  0F85 A7000000 jnz     0041AC51
0041ABAA  |.  0FB64D FD     movzx   ecx, byte ptr [ebp-3]
0041ABAE  |.  83F9 33       cmp     ecx, 33
0041ABB1  |.  0F85 9A000000 jnz     0041AC51
0041ABB7  |.  0FB655 F6     movzx   edx, byte ptr [ebp-A]
0041ABBB  |.  83FA 30       cmp     edx, 30
0041ABBE  |.  0F85 8D000000 jnz     0041AC51
0041ABC4  |.  0FB645 F5     movzx   eax, byte ptr [ebp-B]
0041ABC8  |.  83F8 31       cmp     eax, 31
0041ABCB  |.  0F85 80000000 jnz     0041AC51
0041ABD1  |.  0FB64D F9     movzx   ecx, byte ptr [ebp-7]
0041ABD5  |.  83F9 36       cmp     ecx, 36
0041ABD8  |.  75 77         jnz     short 0041AC51
0041ABDA  |.  0FB655 F7     movzx   edx, byte ptr [ebp-9]
0041ABDE  |.  83FA 36       cmp     edx, 36
0041ABE1  |.  75 6E         jnz     short 0041AC51
0041ABE3  |.  0FB645 FE     movzx   eax, byte ptr [ebp-2]
0041ABE7  |.  83F8 36       cmp     eax, 36
0041ABEA  |.  75 65         jnz     short 0041AC51
0041ABEC  |.  0FB64D FB     movzx   ecx, byte ptr [ebp-5]
0041ABF0  |.  83F9 36       cmp     ecx, 36
0041ABF3  |.  75 5C         jnz     short 0041AC51

========对照如下,只要符合下面的条件就OK了,花了半多个小时看前面,
========哎,……
========现在明白没有,
                code[0]==39
[ebp-3]                code[1]=33
[ebp-A]                code[2]=30
[ebp-B]                code[3]=31
[ebp-7]                code[4]=36
[ebp-9]                code[5]=36
[ebp-2]                code[6]=36
[ebp-5]                code[7]=36

只要注册码满足下面的条件,就OK了,就这么简单,都不知道作者绕那么多弯弯是为什么???       
即:93016666****
另,注册码必须大于等于8位
程序运行界面如下:
SpxImage07.gif

附件为目标程序和算法跟踪过程: cddvddr.rar (200.12 KB, 下载次数: 2)

[ 本帖最后由 iawen 于 2007-12-29 17:02 编辑 ]
PYG19周年生日快乐!

该用户从未签到

发表于 2007-12-29 19:56:54 | 显示全部楼层
学习学习!!!!!!!!!
PYG19周年生日快乐!

该用户从未签到

发表于 2007-12-31 00:13:25 | 显示全部楼层
先来研究一下软件 再来看楼主的破文 向楼主学习了
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表