【文章标题】: MagicDVD 4.4.0算法分析
【文章作者】: the0crat
【作者邮箱】: the0crat.cn_at_gmail.com
【作者主页】: http://the0crat.blogcn.com
【生产日期】: 20070126
【软件名称】: MagicDVD v4.4.0
【保护方式】: 注册码
【编写语言】: VC++ 6.0
【使用工具】: OD
【作者声明】: 本文仅供研究学习,本人对因这篇文章而导致的一切后果,不承担任何法律责任。本文中的不足之处请各位多多指教
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
--------------------------------------------------------------------------------
【详细过程】
无壳

00428810  /$  6A FF         push    -1
00428812  |.  68 F8704C00   push    004C70F8                         ;  SE handler installation
00428817  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
0042881D  |.  50            push    eax
0042881E  |.  64:8925 00000>mov     dword ptr fs:[0], esp
00428825  |.  83EC 24       sub     esp, 24
00428828  |.  8B4424 3C     mov     eax, dword ptr [esp+3C]
0042882C  |.  53            push    ebx
0042882D  |.  55            push    ebp
0042882E  |.  8B6C24 3C     mov     ebp, dword ptr [esp+3C]
00428832  |.  56            push    esi
00428833  |.  57            push    edi
00428834  |.  55            push    ebp
00428835  |.  8D4C24 48     lea     ecx, dword ptr [esp+48]
00428839  |.  C600 00       mov     byte ptr [eax], 0
0042883C  |.  E8 FDF2FFFF   call    <jmp.&MFC42.#537>
00428841  |.  8B3D 2C264D00 mov     edi, dword ptr [<&MSVCRT._mbscmp>;  msvcrt._mbscmp
00428847  |.  C74424 3C 000>mov     dword ptr [esp+3C], 0
0042884F  |.  BE 04355000   mov     esi, 00503504                    ;  ASCII "Christopher Bettison"
00428854  |>  8B4C24 44     /mov     ecx, dword ptr [esp+44]
00428858  |.  56            |push    esi
00428859  |.  51            |push    ecx
0042885A  |.  FFD7          |call    edi
0042885C  |.  83C4 08       |add     esp, 8
0042885F  |.  85C0          |test    eax, eax
00428861  |.  74 69         |je      short 004288CC                  ;  这里有一堆id,如果与这些id相同则失败
00428863  |.  83C6 6B       |add     esi, 6B
00428866  |.  81FE BD615000 |cmp     esi, 005061BD
0042886C  |.^ 7C E6         \jl      short 00428854
0042886E  |.  8B5C24 48     mov     ebx, dword ptr [esp+48]
00428872  |.  83C9 FF       or      ecx, FFFFFFFF
00428875  |.  8BFB          mov     edi, ebx
00428877  |.  33C0          xor     eax, eax
00428879  |.  F2:AE         repne   scas byte ptr es:[edi]
0042887B  |.  F7D1          not     ecx
0042887D  |.  49            dec     ecx
0042887E  |.  83F9 14       cmp     ecx, 14
00428881  |.  75 6F         jnz     short 004288F2                   ;  注册码长度不为20则失败
00428883  |.  50            push    eax                              ; /timer => NULL
00428884  |.  FF15 44264D00 call    dword ptr [<&MSVCRT.time>]       ; \time
0042888A  |.  8D5424 50     lea     edx, dword ptr [esp+50]
0042888E  |.  894424 50     mov     dword ptr [esp+50], eax
00428892  |.  52            push    edx                              ; /timet
00428893  |.  FF15 7C264D00 call    dword ptr [<&MSVCRT.localtime>]  ; \localtime
00428899  |.  B9 09000000   mov     ecx, 9
0042889E  |.  8BF0          mov     esi, eax
004288A0  |.  8D7C24 18     lea     edi, dword ptr [esp+18]
004288A4  |.  53            push    ebx
004288A5  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>
004288A7  |.  8B4424 30     mov     eax, dword ptr [esp+30]
004288AB  |.  8B4C24 5C     mov     ecx, dword ptr [esp+5C]
004288AF  |.  8B5424 2C     mov     edx, dword ptr [esp+2C]
004288B3  |.  05 6D070000   add     eax, 76D
004288B8  |.  8901          mov     dword ptr [ecx], eax
004288BA  |.  8B4424 60     mov     eax, dword ptr [esp+60]
004288BE  |.  42            inc     edx
004288BF  |.  55            push    ebp
004288C0  |.  8910          mov     dword ptr [eax], edx
004288C2  |.  E8 59FBFFFF   call    00428420

关键call,跟进

00428420  /$  6A FF         push    -1
00428422  |.  68 A8704C00   push    004C70A8                                      ;  SE handler installation
00428427  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
0042842D  |.  50            push    eax
0042842E  |.  64:8925 00000>mov     dword ptr fs:[0], esp
00428435  |.  83EC 0C       sub     esp, 0C
00428438  |.  53            push    ebx
00428439  |.  55            push    ebp
0042843A  |.  56            push    esi
0042843B  |.  57            push    edi
0042843C  |.  8D4C24 14     lea     ecx, dword ptr [esp+14]
00428440  |.  E8 5FF4FFFF   call    <jmp.&MFC42.#540>
00428445  |.  8B7C24 30     mov     edi, dword ptr [esp+30]
00428449  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
0042844D  |.  57            push    edi
0042844E  |.  C74424 28 000>mov     dword ptr [esp+28], 0
00428456  |.  E8 E3F6FFFF   call    <jmp.&MFC42.#537>
0042845B  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
0042845F  |.  C64424 24 01  mov     byte ptr [esp+24], 1
00428464  |.  E8 C1F5FFFF   call    <jmp.&MFC42.#6282>                            ;  trimleft(void)
00428469  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
0042846D  |.  E8 B2F5FFFF   call    <jmp.&MFC42.#6283>                            ;  trimright(void)
00428472  |.  8D4C24 10     lea     ecx, dword ptr [esp+10]
00428476  |.  E8 A3F5FFFF   call    <jmp.&MFC42.#4204>                            ;  注册码转换成大写
0042847B  |.  6A 30         push    30
0042847D  |.  6A 4F         push    4F
0042847F  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
00428483  |.  E8 12F5FFFF   call    <jmp.&MFC42.#6876>
00428488  |.  83CE FF       or      esi, FFFFFFFF
0042848B  |.  33C0          xor     eax, eax
0042848D  |.  8BCE          mov     ecx, esi
0042848F  |.  F2:AE         repne   scas byte ptr es:[edi]
00428491  |.  F7D1          not     ecx
00428493  |.  49            dec     ecx
00428494  |.  83F9 14       cmp     ecx, 14
00428497  |.  75 3E         jnz     short 004284D7
00428499  |.  8B4424 2C     mov     eax, dword ptr [esp+2C]
0042849D  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
004284A1  |.  50            push    eax
004284A2  |.  E8 97F6FFFF   call    <jmp.&MFC42.#537>
004284A7  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
004284AB  |.  C64424 24 02  mov     byte ptr [esp+24], 2
004284B0  |.  E8 75F5FFFF   call    <jmp.&MFC42.#6282>                            ;  trimleft(void)
004284B5  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
004284B9  |.  E8 66F5FFFF   call    <jmp.&MFC42.#6283>                            ;  trimright(void)
004284BE  |.  8B4424 18     mov     eax, dword ptr [esp+18]
004284C2  |.  8B48 F8       mov     ecx, dword ptr [eax-8]
004284C5  |.  85C9          test    ecx, ecx
004284C7  |.  75 25         jnz     short 004284EE
004284C9  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
004284CD  |.  C64424 24 01  mov     byte ptr [esp+24], 1
004284D2  |.  E8 BBF3FFFF   call    <jmp.&MFC42.#800>
004284D7  |>  8D4C24 10     lea     ecx, dword ptr [esp+10]
004284DB  |.  C64424 24 00  mov     byte ptr [esp+24], 0
004284E0  |.  E8 ADF3FFFF   call    <jmp.&MFC42.#800>
004284E5  |.  897424 24     mov     dword ptr [esp+24], esi
004284E9  |.  E9 F2000000   jmp     004285E0
004284EE  |>  50            push    eax
004284EF  |.  E8 0C010000   call    00428600                                      ;  将用户名每个字符的ascii累计相加
004284F4  |.  8BC8          mov     ecx, eax
004284F6  |.  BE 14000000   mov     esi, 14
004284FB  |.  81E1 FFFF0000 and     ecx, 0FFFF
00428501  |.  83C4 04       add     esp, 4
00428504  |.  8BC1          mov     eax, ecx
00428506  |.  99            cdq
00428507  |.  F7FE          idiv    esi                                           ;  然后除以注册码长度,也就是20
00428509  |.  51            push    ecx                                           ;  取余数n
0042850A  |.  8D4C24 18     lea     ecx, dword ptr [esp+18]
0042850E  |.  68 C0615000   push    005061C0                                      ;  ASCII "%04x"
00428513  |.  51            push    ecx
00428514  |.  8BFA          mov     edi, edx
00428516  |.  E8 97F4FFFF   call    <jmp.&MFC42.#2818>                            ;  将上面的十六进制值format成4个字节的字符串m
0042851B  |.  83C4 0C       add     esp, 0C
0042851E  |.  8D4C24 14     lea     ecx, dword ptr [esp+14]
00428522  |.  E8 F7F4FFFF   call    <jmp.&MFC42.#4204>                            ;  转换成大写
00428527  |.  8BCF          mov     ecx, edi
00428529  |.  BF 14000000   mov     edi, 14
0042852E  |.  81E1 FFFF0000 and     ecx, 0FFFF
00428534  |.  8B7424 14     mov     esi, dword ptr [esp+14]
00428538  |.  8D41 05       lea     eax, dword ptr [ecx+5]
0042853B  |.  8A1E          mov     bl, byte ptr [esi]
0042853D  |.  99            cdq
0042853E  |.  F7FF          idiv    edi                                           ;  用户名的长度/注册码的长度
00428540  |.  8B7C24 10     mov     edi, dword ptr [esp+10]
00428544  |.  3A1C3A        cmp     bl, byte ptr [edx+edi]                        ;  余数为k。对比[大写(注册码)]的第k+1个字符,与m的第一个字符
00428547  |.  75 73         jnz     short 004285BC                                ;  不相等则失败
00428549  |.  8D41 09       lea     eax, dword ptr [ecx+9]                        ;  n+=9
0042854C  |.  BD 14000000   mov     ebp, 14
00428551  |.  99            cdq
00428552  |.  F7FD          idiv    ebp                                           ;  n/20
00428554  |.  8A5E 01       mov     bl, byte ptr [esi+1]
00428557  |.  3A1C3A        cmp     bl, byte ptr [edx+edi]                        ;  余数为k。对比[大写(注册码)]的第k+1个字符,与m的第二个字符
0042855A  |.  75 60         jnz     short 004285BC
0042855C  |.  8D41 12       lea     eax, dword ptr [ecx+12]                       ;  n+=18
0042855F  |.  8A5E 02       mov     bl, byte ptr [esi+2]
00428562  |.  99            cdq
00428563  |.  F7FD          idiv    ebp                                           ;  n/20
00428565  |.  3A1C3A        cmp     bl, byte ptr [edx+edi]                        ;  余数为k。对比[大写(注册码)]的第k+1个字符,与m的第三个字符
00428568  |.  75 52         jnz     short 004285BC
0042856A  |.  8D41 0B       lea     eax, dword ptr [ecx+B]                        ;  n+=11
0042856D  |.  8BCD          mov     ecx, ebp
0042856F  |.  99            cdq
00428570  |.  F7F9          idiv    ecx                                           ;  n/20
00428572  |.  8A5E 03       mov     bl, byte ptr [esi+3]
00428575  |.  3A1C3A        cmp     bl, byte ptr [edx+edi]                        ;  余数为k。对比[大写(注册码)]的第k+1个字符,与m的第四个字符
00428578  |.  75 42         jnz     short 004285BC

每次启动都效验注册码

【算法总结】
.注册码大写
.注册名的十六进制的ascii累加值->转换成4个字节的字符串m
.注册名的十六进制的ascii累加值->除以注册码长度,取余数n
然后开始对比注册码中相应偏移上的字符
.m的第一个字符  <=>  [注册码偏移:](用户名长度/注册码长度)的余数+1
.m的第二个字符  <=>  [注册码偏移:](n+9)/20的余数+1
.m的第三个字符  <=>  [注册码偏移:](n+18)/20的余数+1
.m的第四个字符  <=>  [注册码偏移:](n+11)/20的余数+1
这四个字符相同即可

\\注册机略

用户名:the0crat
注册码:2334567800ab3d7fghij