【破文标题】  GIF Creator软件注册算法分析[浮点指令应用](增加存盘验证部分)
【破文作者】  snake
【软件名称】  EximiousSoft GIF Creator V3.25
【下载地址】  http://www4.skycn.com/soft/25641.html
【软件简介】  一款GIF动画制作软件。提供很多强大的功能帮助你快速制作精彩的动画。
              支持从多种格式的图像中载入动画的一帧或多帧,支持载入的格式包括:
              GIF, AVI, BMP, PCX, JPG, TIFF, PNG, TGA, PSD, ICO, CUR, ANI等等。
【调试环境】  Windows XP + SP2
【作者声明】  只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

程序的注册验证算法部分用了很多的浮点指令,对学习这部分内容有很好的帮助
文中分析不对的地方还请各位大侠指正。

感谢寒秋提出的存盘验证问题,后面将补上这部分的分析过程。

程序验证注册码分两部分进行
第一部分是在输入注册码的时候,验证第3、6、7、9位,验证通过提示注册成功的信息
第二部分是在保存文件的时候,验证第3、4、5、8、9、10位,验证通过则保存的文件不带有公司的logo
注册码保存在注册表中的位置为:
[HKEY_CURRENT_USER\Software\EximiousSoft\EximiousSoft GIF Creator\Default]
"KeyCode"="7702180575"
删除后可重新注册。

【破解过程】

第一部分验证分析过程

用PEiD查壳为Microsoft Visual C++ 6.0,无壳。
OD载入程序,F9运行,点击Help-->Registration输入注册信息
License Key:1234567890
确定后提示"Invalid serial number!"
下断bp MessageBoxA,返回程序“确定”后,程序被断下,向上查找跳转处并下断点bp 0046B680
重新输入注册信息,Register后断下,开始分析

0046B680   .  8B5424 10     mov     edx, [esp+10]                       ;  注册码
0046B684   .  8B42 F8       mov     eax, [edx-8]                        ;  码长
0046B687   .  83F8 0A       cmp     eax, 0A                             ;  为10位串
0046B68A   .  0F85 8D000000 jnz     0046B71D
0046B690   .  8D4424 14     lea     eax, [esp+14]
0046B694   .  33C9          xor     ecxecx
0046B696   .  2BD0          sub     edxeax
0046B698   >  8D040A        lea     eax, [edx+ecx]
0046B69B   .  8A4404 14     mov     al, [esp+eax+14]                    ;  注册码"1234567890"转换
0046B69F   .  3C 30         cmp     al, 30
0046B6A1   .  7C 10         jl      short 0046B6B3
0046B6A3   .  3C 39         cmp     al, 39
0046B6A5   .  7F 0C         jg      short 0046B6B3
0046B6A7   .  2C 30         sub     al, 30                              ;  结果为
0046B6A9   .  88440C 14     mov     [esp+ecx+14], al                    ;  0012F2DC  01 02 03 04 05 06 07 08 09 00
0046B6AD   .  41            inc     ecx                                 ;  用于后面的验证
0046B6AE   .  83F9 0A       cmp     ecx, 0A
0046B6B1   .^ 7C E5         jl      short 0046B698
0046B6B3   >  83F9 0A       cmp     ecx, 0A
0046B6B6   .  75 65         jnz     short 0046B71D
0046B6B8   .  51            push    ecx                                 ; /Arg2
0046B6B9   .  8D4C24 18     lea     ecx, [esp+18]                       ; |
0046B6BD   .  51            push    ecx                                 ; |Arg1
0046B6BE   .  8B0D 082F4C00 mov     ecx, [4C2F08]                       ; |
0046B6C4   .  E8 1714FBFF   call    0041CAE0                            ; \***算法call,跟进***
0046B6C9   .  85C0          test    eaxeax
0046B6CB   .  74 50         je      short 0046B71D                      ;  关键跳转 nop
0046B6CD   .  8B4424 0C     mov     eax, [esp+C]
0046B6D1   .  6A 01         push    1
0046B6D3   .  8D5424 28     lea     edx, [esp+28]
0046B6D7   .  8B48 F8       mov     ecx, [eax-8]
0046B6DA   .  51            push    ecx
0046B6DB   .  50            push    eax
0046B6DC   .  6A 20         push    20
0046B6DE   .  68 68044C00   push    004C0468
0046B6E3   .  52            push    edx
0046B6E4   .  E8 27DA0100   call    00489110
0046B6E9   .  83C4 18       add     esp, 18
0046B6EC   .  8D4424 24     lea     eax, [esp+24]
0046B6F0   .  53            push    ebx
0046B6F1   .  6A 40         push    40
0046B6F3   .  50            push    eax
0046B6F4   .  E8 B7A00200   call    <jmp.&MFC42.#1200_AfxMessageBox>    ;  提示注册成功
0046B6F9   .  8D4C24 10     lea     ecx, [esp+10]

==================    0046B6C4   .  E8 1714FBFF   call    0041CAE0    =======================

0041CAE0  /$  83EC 0C       sub     esp, 0C
0041CAE3  |.  33C0          xor     eaxeax
0041CAE5  |.  8D5424 00     lea     edx, [esp]
0041CAE9  |.  894424 01     mov     [esp+1], eax
0041CAED  |.  6A 0A         push    0A                                  ; /Arg2 = 0000000A
0041CAEF  |.  894424 09     mov     [esp+9], eax                        ; |
0041CAF3  |.  52            push    edx                                 ; |Arg1
0041CAF4  |.  C64424 08 00  mov     byte ptr [esp+8], 0                 ; |
0041CAF9  |.  884424 11     mov     [esp+11], al                        ; |
0041CAFD  |.  E8 CEFDFFFF   call    0041C8D0                            ; \***算法call*** 此处设置一断点后面分析用到
0041CB02  |.  85C0          test    eaxeax
0041CB04  |.  74 3B         je      short 0041CB41                      ;  计算结果0012F2B0  00 00 00 00 00 08 00 00 07 00
0041CB06  |.  8B4424 10     mov     eax, [esp+10]                       ;  假码转换结果0012F2DC  01 02 03 04 05 06 07 08 09 00
0041CB0A  |.  8A5424 02     mov     dl, [esp+2]
0041CB0E  |.  8A48 02       mov     cl, [eax+2]
0041CB11  |.  3ACA          cmp     cldl                              ;  验证第三位是否为0
0041CB13  |.  75 2C         jnz     short 0041CB41                      ;  nop
0041CB15  |.  8A50 05       mov     dl, [eax+5]
0041CB18  |.  8A4C24 05     mov     cl, [esp+5]
0041CB1C  |.  3AD1          cmp     dlcl                              ;  验证第六位是否为8
0041CB1E  |.  75 21         jnz     short 0041CB41                      ;  nop
0041CB20  |.  8A48 06       mov     cl, [eax+6]
0041CB23  |.  8A5424 06     mov     dl, [esp+6]
0041CB27  |.  3ACA          cmp     cldl                              ;  验证第七位是否为0
0041CB29  |.  75 16         jnz     short 0041CB41                      ;  nop
0041CB2B  |.  8A50 08       mov     dl, [eax+8]
0041CB2E  |.  8A4424 08     mov     al, [esp+8]
0041CB32  |.  3AD0          cmp     dlal                              ;  验证第九位是否为7
0041CB34  |.  75 0B         jnz     short 0041CB41                      ;  nop
0041CB36  |.  B8 01000000   mov     eax, 1                              ;  验证通过返回值eax=1
0041CB3B  |.  83C4 0C       add     esp, 0C
0041CB3E  |.  C2 0800       retn    8
0041CB41  |>  33C0          xor     eaxeax
0041CB43  |.  83C4 0C       add     esp, 0C
0041CB46  \.  C2 0800       retn    8

==================    0041CAFD  |.  E8 CEFDFFFF   call    0041C8D0    ====================

0041C8D0  /$  83EC 28       sub     esp, 28
0041C8D3  |.  33C0          xor     eaxeax
0041C8D5  |.  56            push    esi
0041C8D6  |.  8BF1          mov     esiecx
0041C8D8  |.  894424 1D     mov     [esp+1D], eax                       ;  清零
0041C8DC  |.  894424 21     mov     [esp+21], eax
0041C8E0  |.  8D4C24 1C     lea     ecx, [esp+1C]
0041C8E4  |.  6A 0C         push    0C                                  ; /Arg2 = 0000000C
0041C8E6  |.  66:894424 29  mov     [esp+29], ax                        ; |
0041C8EB  |.  51            push    ecx                                 ; |Arg1
0041C8EC  |.  8BCE          mov     ecxesi                            ; |
0041C8EE  |.  C64424 24 00  mov     byte ptr [esp+24], 0                ; |
0041C8F3  |.  884424 2F     mov     [esp+2F], al                        ; |
0041C8F7  |.  E8 14FFFFFF   call    0041C810                            ; \***算法call***
{{{
0041C810  /$  83EC 30       sub     esp, 30
0041C813  |.  53            push    ebx
0041C814  |.  8B5C24 38     mov     ebx, [esp+38]
0041C818  |.  55            push    ebp
0041C819  |.  56            push    esi
0041C81A  |.  57            push    edi
0041C81B  |.  8BE9          mov     ebpecx
0041C81D  |.  C74424 10 000>mov     dword ptr [esp+10], 40A00000        ;  初始化常数值
0041C825  |.  C74424 14 000>mov     dword ptr [esp+14], 42A00000
0041C82D  |.  C74424 18 000>mov     dword ptr [esp+18], 41100000
0041C835  |.  C74424 1C 000>mov     dword ptr [esp+1C], 42880000
0041C83D  |.  C74424 20 000>mov     dword ptr [esp+20], 41A00000
0041C845  |.  C74424 24 000>mov     dword ptr [esp+24], 42480000
0041C84D  |.  C74424 28 000>mov     dword ptr [esp+28], 41C80000
0041C855  |.  C74424 2C 000>mov     dword ptr [esp+2C], 42600000
0041C85D  |.  C74424 30 000>mov     dword ptr [esp+30], 41F00000
0041C865  |.  C74424 34 000>mov     dword ptr [esp+34], 42100000
0041C86D  |.  C74424 38 000>mov     dword ptr [esp+38], 42280000
0041C875  |.  C74424 3C 000>mov     dword ptr [esp+3C], 423C0000
0041C87D  |.  33F6          xor     esiesi
0041C87F  |.  8D7C24 10     lea     edi, [esp+10]
0041C883  |>  D907          /fld     dword ptr [edi]                    ;  装入实数到st(0)
0041C885  |.  DC0D B0274A00 |fmul    qword ptr [4A27B0]                 ;  乘上一个实数
0041C88B  |.  83FE 0B       |cmp     esi, 0B
0041C88E  |.  D9FE          |fsin                                       ;  正弦函数sin
0041C890  |.  DFAD 16060000 |fild    qword ptr [ebp+616]                ;  装入整数到st(0)
0041C896  |.  DEC9          |fmulp   st(1), st                          ;  乘上一个实数
0041C898  |.  7D 0D         |jge     short 0041C8A7
0041C89A  |.  E8 31950700   |call    <jmp.&MSVCRT._ftol>                ;  浮点数转换成长整型数
0041C89F  |.  99            |cdq                                        ;  eax为返回值
0041C8A0  |.  B9 0A000000   |mov     ecx, 0A
0041C8A5  |.  EB 0B         |jmp     short 0041C8B2
0041C8A7  |>  E8 24950700   |call    <jmp.&MSVCRT._ftol>
0041C8AC  |.  99            |cdq
0041C8AD  |.  B9 1A000000   |mov     ecx, 1A
0041C8B2  |>  F7F9          |idiv    ecx
0041C8B4  |.  46            |inc     esi
0041C8B5  |.  83C7 04       |add     edi, 4
0041C8B8  |.  83FE 0C       |cmp     esi, 0C
0041C8BB  |.  88541E FF     |mov     [esi+ebx-1], dl                    ;  保存余数
0041C8BF  |.^ 7C C2         \jl      short 0041C883
0041C8C1  |.  5F            pop     edi
0041C8C2  |.  5E            pop     esi
0041C8C3  |.  5D            pop     ebp
0041C8C4  |.  B8 01000000   mov     eax, 1
0041C8C9  |.  5B            pop     ebx
0041C8CA  |.  83C4 30       add     esp, 30
0041C8CD  \.  C2 0800       retn    8
}}}
0041C8FC  |.  85C0          test    eaxeax                            ;  循环结束后的计算结果为
0041C8FE  |.  75 07         jnz     short 0041C907                      ;  0012F294  04 02 08 07 07 08 06 01 01 08 05 00
0041C900  |.  5E            pop     esi
0041C901  |.  83C4 28       add     esp, 28
0041C904  |.  C2 0800       retn    8
0041C907  |> \DD05 50294A00 fld     qword ptr [4A2950]                  ;  装入实数到st(0)
0041C90D  |.  D9FE          fsin                                        ;  正弦函数sin
0041C90F  |.  8B5424 25     mov     edx, [esp+25]
0041C913  |.  8B4424 26     mov     eax, [esp+26]
0041C917  |.  81E2 FF000000 and     edx, 0FF                            ;  edx=8
0041C91D  |.  25 FF000000   and     eax, 0FF                            ;  eax=5
0041C922  |.  895424 04     mov     [esp+4], edx
0041C926  |.  8B4C24 21     mov     ecx, [esp+21]
0041C92A  |.  81E1 FF000000 and     ecx, 0FF                            ;  ecx=8
0041C930  |.  57            push    edi
0041C931  |.  DD5C24 18     fstp    qword ptr [esp+18]                  ;  保存实数st(0)到[esp+18],然后出栈
0041C935  |.  DD05 48294A00 fld     qword ptr [4A2948]                  ;  装入实数到st(0)
0041C93B  |.  D9FE          fsin                                        ;  正弦函数sin
0041C93D  |.  DD5C24 10     fstp    qword ptr [esp+10]                  ;  保存实数st(0)到[esp+10],然后出栈
0041C941  |.  DD05 40294A00 fld     qword ptr [4A2940]                  ;  装入实数到st(0)
0041C947  |.  D9FE          fsin                                        ;  正弦函数sin
0041C949  |.  DB4424 08     fild    dword ptr [esp+8]                   ;  装入整数到st(0)
0041C94D  |.  894424 08     mov     [esp+8], eax                        ;  eax=5
0041C951  |.  DEC9          fmulp   st(1), st                           ;  st(1) <- st(0) * st(1),然后出栈
0041C953  |.  DB4424 08     fild    dword ptr [esp+8]                   ;  装入整数到st(0)
0041C957  |.  894C24 08     mov     [esp+8], ecx                        ;  ecx=8
0041C95B  |.  DC4C24 10     fmul    qword ptr [esp+10]                  ;  乘上实数[esp+10]
0041C95F  |.  DEC1          faddp   st(1), st                           ;  st(1) <- st(1) + st(0),然后出栈
0041C961  |.  DB4424 08     fild    dword ptr [esp+8]                   ;  装入整数到st(0)
0041C965  |.  DC4C24 18     fmul    qword ptr [esp+18]                  ;  乘上实数[esp+18]
0041C969  |.  DEC1          faddp   st(1), st                           ;  st(1) <- st(1) + st(0),然后出栈
0041C96B  |.  E8 60940700   call    <jmp.&MSVCRT._ftol>                 ;  浮点数转换成长整型数
0041C970  |.  99            cdq                                         ;  eax为返回值
0041C971  |.  B9 0A000000   mov     ecx, 0A
0041C976  |.  F7F9          idiv    ecx
0041C978  |.  8BCE          mov     ecxesi
0041C97A  |.  52            push    edx
0041C97B  |.  E8 D0010000   call    0041CB50                            ;  根据余数查表得计算结果
0041C980  |.  DD05 38294A00 fld     qword ptr [4A2938]                  ;  下面运算部分跟上面的类似,不再做详细分析了
0041C986  |.  D9FE          fsin                                        ;  注意eax,ecx,edx的取值就可以了
0041C988  |.  8B5424 25     mov     edx, [esp+25]
0041C98C  |.  8B7C24 34     mov     edi, [esp+34]
0041C990  |.  81E2 FF000000 and     edx, 0FF                            ;  edx=8
0041C996  |.  8B4C24 22     mov     ecx, [esp+22]
0041C99A  |.  895424 34     mov     [esp+34], edx
0041C99E  |.  8847 02       mov     [edi+2], al                         ;  保存计算结果[12F2B0]
0041C9A1  |.  8B4424 26     mov     eax, [esp+26]
0041C9A5  |.  81E1 FF000000 and     ecx, 0FF                            ;  ecx=8
0041C9AB  |.  25 FF000000   and     eax, 0FF                            ;  eax=6
0041C9B0  |.  DD5C24 08     fstp    qword ptr [esp+8]
0041C9B4  |.  DD05 30294A00 fld     qword ptr [4A2930]
0041C9BA  |.  D9FE          fsin
0041C9BC  |.  DB4424 34     fild    dword ptr [esp+34]
0041C9C0  |.  894424 34     mov     [esp+34], eax
0041C9C4  |.  DEC9          fmulp   st(1), st
0041C9C6  |.  DD05 28294A00 fld     qword ptr [4A2928]
0041C9CC  |.  D9FE          fsin
0041C9CE  |.  DB4424 34     fild    dword ptr [esp+34]
0041C9D2  |.  894C24 34     mov     [esp+34], ecx
0041C9D6  |.  DEC9          fmulp   st(1), st
0041C9D8  |.  DEC1          faddp   st(1), st
0041C9DA  |.  DB4424 34     fild    dword ptr [esp+34]
0041C9DE  |.  DC4C24 08     fmul    qword ptr [esp+8]
0041C9E2  |.  DEC1          faddp   st(1), st
0041C9E4  |.  E8 E7930700   call    <jmp.&MSVCRT._ftol>
0041C9E9  |.  99            cdq
0041C9EA  |.  B9 0A000000   mov     ecx, 0A
0041C9EF  |.  F7F9          idiv    ecx
0041C9F1  |.  8BCE          mov     ecxesi
0041C9F3  |.  52            push    edx
0041C9F4  |.  E8 57010000   call    0041CB50
......(略)

第二部分验证分析过程

运行程序输入注册码"8301480573",提示注册成功后退出程序,把注册码写入注册表中
Ctrl+F2重新载入程序,F9运行,程序被断下

0041CAED  |.  6A 0A         push    0A                                ; /Arg2 = 0000000A
0041CAEF  |.  894424 09     mov     [esp+9], eax                      ; |
0041CAF3  |.  52            push    edx                               ; |Arg1
0041CAF4  |.  C64424 08 00  mov     byte ptr [esp+8], 0               ; |
0041CAF9  |.  884424 11     mov     [esp+11], al                      ; |
0041CAFD  |.  E8 CEFDFFFF   call    0041C8D0                          ; \***算法call*** 断在此处
0041CB02  |.  85C0          test    eaxeax

这里是第一部分的验证过程,Ctrl+F9返回上一级调用到0043DB66处,下断bp 0043DB21,Ctrl+F2重新载入程序
F9运行,程序断在0043DB21处,F8到0043DB27,此时edx为假码存放地址003F4FC8,在此地址下硬件访问断点,
F9运行程序

0043DB10  /$  83EC 0C       sub     esp, 0C
0043DB13  |.  53            push    ebx
0043DB14  |.  56            push    esi
0043DB15  |.  8BF1          mov     esiecx
0043DB17  |.  33C0          xor     eaxeax
0043DB19  |.  8B4C24 18     mov     ecx, [esp+18]
0043DB1D  |.  894424 09     mov     [esp+9], eax
0043DB21  |.  32DB          xor     blbl                            ;  F2在这里下断点
0043DB23  |.  894424 0D     mov     [esp+D], eax
0043DB27  |.  8B11          mov     edx, [ecx]                        ;  edx为假码存放地址003F4FC8
0043DB29  |.  885C24 08     mov     [esp+8], bl
0043DB2D  |.  884424 11     mov     [esp+11], al
0043DB31  |.  837A F8 0A    cmp     dword ptr [edx-8], 0A
0043DB35  |.  75 35         jnz     short 0043DB6C
0043DB37  |.  33C9          xor     ecxecx
0043DB39  |>  8A040A        /mov     al, [edx+ecx]                    ;  假码转换过程
0043DB3C  |.  3C 30         |cmp     al, 30
0043DB3E  |.  7C 10         |jl      short 0043DB50
0043DB40  |.  3C 39         |cmp     al, 39
0043DB42  |.  7F 0C         |jg      short 0043DB50
0043DB44  |.  2C 30         |sub     al, 30
0043DB46  |.  88440C 08     |mov     [esp+ecx+8], al
0043DB4A  |.  41            |inc     ecx
0043DB4B  |.  83F9 0A       |cmp     ecx, 0A
0043DB4E  |.^ 7C E9         \jl      short 0043DB39
0043DB50  |>  83F9 0A       cmp     ecx, 0A
0043DB53  |.  75 17         jnz     short 0043DB6C
0043DB55  |.  8D5424 08     lea     edx, [esp+8]
0043DB59  |.  51            push    ecx                               ; /Arg2
0043DB5A  |.  8B8E 70010000 mov     ecx, [esi+170]                    ; |
0043DB60  |.  52            push    edx                               ; |Arg1
0043DB61  |.  E8 7AEFFDFF   call    0041CAE0                          ; \GifCreat.0041CAE0
0043DB66  |.  85C0          test    eaxeax                          ;  返回到此处
0043DB68  |.  74 02         je      short 0043DB6C
0043DB6A  |.  B3 01         mov     bl, 1

编辑一个文件,然后点击"File-->Save As-->GIF File",保存,程序断下,取消断点

00455521  |.  33C9          xor     ecxecx
00455523  |.  894C24 20     mov     [esp+20], ecx
00455527  |.  8B42 F8       mov     eax, [edx-8]
0045552A  |.  83F8 0A       cmp     eax, 0A
0045552D  |.  75 3D         jnz     short 0045556C
0045552F  |.  8D4424 0C     lea     eax, [esp+C]
00455533  |.  2BD0          sub     edxeax
00455535  |>  8D040A        /lea     eax, [edx+ecx]                   ;  假码"8301480573"转换
00455538  |.  8A4404 0C     |mov     al, [esp+eax+C]
0045553C  |.  3C 30         |cmp     al, 30                           ;  ***断在此处***
0045553E  |.  7C 10         |jl      short 00455550
00455540  |.  3C 39         |cmp     al, 39
00455542  |.  7F 0C         |jg      short 00455550
00455544  |.  2C 30         |sub     al, 30                           ;  结果为
00455546  |.  88440C 0C     |mov     [esp+ecx+C], al                  ;  0012F69C  08 03 00 01 04 08 00 05 07 03
0045554A  |.  41            |inc     ecx
0045554B  |.  83F9 0A       |cmp     ecx, 0A
0045554E  |.^ 7C E5         \jl      short 00455535
00455550  |>  83F9 0A       cmp     ecx, 0A
00455553  |.  75 17         jnz     short 0045556C
00455555  |.  51            push    ecx                               ; /Arg2
00455556  |.  8D4C24 10     lea     ecx, [esp+10]                     ; |
0045555A  |.  51            push    ecx                               ; |Arg1
0045555B  |.  8B0D 082F4C00 mov     ecx, [4C2F08]                     ; |
00455561  |.  E8 BA7CFCFF   call    0041D220                          ; \***算法call***
{{{
0041D220  /$  83EC 0C       sub     esp, 0C
0041D223  |.  33C0          xor     eaxeax
0041D225  |.  8D5424 00     lea     edx, [esp]
0041D229  |.  894424 01     mov     [esp+1], eax
0041D22D  |.  6A 0C         push    0C                                ; /Arg2 = 0000000C
0041D22F  |.  894424 09     mov     [esp+9], eax                      ; |
0041D233  |.  52            push    edx                               ; |Arg1
0041D234  |.  66:894424 11  mov     [esp+11], ax                      ; |
0041D239  |.  C64424 08 00  mov     byte ptr [esp+8], 0               ; |
0041D23E  |.  884424 13     mov     [esp+13], al                      ; |
0041D242  |.  E8 69FCFFFF   call    0041CEB0                          ; \此call与0041CAFD处的call 0041C8D0
0041D247  |.  85C0          test    eaxeax                          ;  计算过程相似,只是取值有些变化
0041D249  |.  74 51         je      short 0041D29C                    ;  计算结果0012F678  00 00 00 02 01 00 00 05 07 05
0041D24B  |.  8B4424 10     mov     eax, [esp+10]
0041D24F  |.  8A5424 02     mov     dl, [esp+2]
0041D253  |.  8A48 02       mov     cl, [eax+2]
0041D256  |.  3ACA          cmp     cldl                            ;  验证第三位是否为0
0041D258  |.  75 42         jnz     short 0041D29C                    ;  nop
0041D25A  |.  8A50 03       mov     dl, [eax+3]
0041D25D  |.  8A4C24 03     mov     cl, [esp+3]
0041D261  |.  3AD1          cmp     dlcl                            ;  验证第四位是否为2
0041D263  |.  75 37         jnz     short 0041D29C                    ;  nop
0041D265  |.  8A48 04       mov     cl, [eax+4]
0041D268  |.  8A5424 04     mov     dl, [esp+4]
0041D26C  |.  3ACA          cmp     cldl                            ;  验证第五位是否为1
0041D26E  |.  75 2C         jnz     short 0041D29C                    ;  nop
0041D270  |.  8A50 07       mov     dl, [eax+7]
0041D273  |.  8A4C24 07     mov     cl, [esp+7]
0041D277  |.  3AD1          cmp     dlcl                            ;  验证第八位是否为5
0041D279  |.  75 21         jnz     short 0041D29C                    ;  nop
0041D27B  |.  8A48 09       mov     cl, [eax+9]
0041D27E  |.  8A5424 09     mov     dl, [esp+9]
0041D282  |.  3ACA          cmp     cldl                            ;  验证第十位是否为5
0041D284  |.  75 16         jnz     short 0041D29C                    ;  nop
0041D286  |.  8A50 08       mov     dl, [eax+8]
0041D289  |.  8A4424 08     mov     al, [esp+8]
0041D28D  |.  3AD0          cmp     dlal                            ;  验证第九位是否为7
0041D28F  |.  75 0B         jnz     short 0041D29C                    ;  nop
0041D291  |.  B8 01000000   mov     eax, 1
0041D296  |.  83C4 0C       add     esp, 0C
0041D299  |.  C2 0800       retn    8
0041D29C  |>  33C0          xor     eaxeax
0041D29E  |.  83C4 0C       add     esp, 0C
0041D2A1  \.  C2 0800       retn    8
}}}
00455566  |.  85C0          test    eaxeax
00455568  |. /74 02         je      short 0045556C                    ;  nop
0045556A  |.  B3 01         mov     bl, 1
0045556C  |>  33D2          xor     edxedx
0045556E  |.  8D4C24 08     lea     ecx, [esp+8]
00455572  |.  84DB          test    blbl
00455574  |.  0F95C2        setne   dl
......

至此验证过程全部结束。

【汇编注册机算法部分源码】

.data
szData1    dd  40A00000h, 42A00000h, 41100000h, 42880000h, 41A00000h, 42480000h
    dd  41C80000h, 42600000h, 41F00000h, 42100000h, 42280000h, 423C0000h
szData2    dd  9D353918h, 3F91DF46h
szData3    dd  0ACAD4B6h, 00000000h
szData4    dd  33834055h, 3FDCB91Fh
szData5    dd  0EBCFD5A4h, 3FCACEE9h
szData6    dd  33834055h, 3FCCB91Fh
szData7    dd  4482875Eh, 3FD65718h
szData8    dd  3361E587h, 3FF0C152h
szData9    dd  70DBE03Bh, 3FE41B2Fh
szData10  dd  3361E587h, 3FD0C152h
szData11  dd  4D12D84Ah, 3FE921FBh
szData12  dd  3361E587h, 3FE0C152h
szData13  dd  23C86CAAh, 3FCEEEBFh
szData14  dd  6699577Ch, 3FD24742h
szData15  dd  359DCE1Dh, 3FC17BD0h

.data?
szName    db  16 dup (?)
szSerial  db  16 dup (?)
szRlt    db  16 dup (?)

.code
return  proc  rlt
  mov  eax,rlt
  and  eax,0FFh
  .if  eax == 0
    mov  al,7
  .elseif  eax == 1
    mov  al,2
  .elseif  eax == 2
    mov  al,4
  .elseif  eax == 3
    mov  al,8
  .elseif  eax == 4
    mov  al,5
  .elseif  eax == 5
    mov  al,1
  .elseif  eax == 6
    xor  al,al
  .elseif  eax == 7
    mov  al,9
  .elseif  eax == 8
    mov  al,3
  .elseif  eax == 9
    mov  al,6
  .endif
  ret
return  endp

GetRegKey  proc  hDlg
  local  flag1:WORD,flag2:WORD,szTmp[64]:BYTE
  pushad
  lea  edi,szData1
  lea  ebx,szName
  xor  esi,esi
@@:
  fld  DWORD ptr [edi]
  fmul  QWORD ptr [szData2]
  fsin
  fild  QWORD ptr [szData3]
  fmulp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  cmp  esi,0Bh
  jge  @N
  xor  edx,edx
  mov  ecx,0Ah
  jmp  @C
@N:
  xor  edx,edx
  mov  ecx,1Ah
@C:
  idiv  ecx
  mov  [ebx],dl
  inc  ebx
  inc  esi
  add  edi,4
  cmp  esi,0Ch
  jl  @b
  lea  ebx,szName
  lea  esi,szTmp
  lea  edi,szSerial
  fld  QWORD ptr [szData4]
  fsin
  movzx  edx,BYTE ptr [ebx+9]
  mov  [esi+10h],edx
  movzx  eax,BYTE ptr [ebx+0Ah]
  movzx  ecx,BYTE ptr [ebx+5]
  fstp  QWORD ptr [esi]
  fld  QWORD ptr [szData5]
  fsin
  fstp  QWORD ptr [esi+8]
  fld  QWORD ptr [szData6]
  fsin
  fild  DWORD ptr [esi+10h]
  mov  [esi+10h],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi+10h]
  mov  [esi+10h],ecx
  fmul  QWORD ptr [esi+8]
  faddp  st(1),st
  fild  DWORD ptr [esi+10h]
  fmul  QWORD ptr [esi]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+2],al
  fld  QWORD ptr [szData7]
  fsin
  movzx  edx,BYTE ptr [ebx+5]
  movzx  ecx,BYTE ptr [ebx+2]
  movzx  eax,BYTE ptr [ebx+6]
  mov  [esi+18h],edx
  fstp  QWORD ptr [esi+10h]
  fld  QWORD ptr [szData8]
  fsin
  fild  DWORD ptr [esi+18h]
  mov  [esi+18h],eax
  fmulp  st(1),st
  fld  QWORD ptr [szData9]
  fsin
  fild  DWORD ptr [esi+18h]
  mov  [esi+18h],ecx
  fmulp  st(1),st
  faddp  st(1),st
  fild  DWORD ptr [esi+18h]
  fmul  QWORD ptr [esi+10h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+5],al
  fld  QWORD ptr [szData10]
  fsin
  movzx  edx,BYTE ptr [ebx+6]
  movzx  ecx,BYTE ptr [ebx+4]
  movzx  eax,BYTE ptr [ebx+3]
  mov  [esi+18h],edx
  fild  DWORD ptr [esi+18h]
  mov  [esi+18h],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi+18h]
  fmul  QWORD ptr [esi+8]
  faddp  st(1),st
  mov  [esi+18h],ecx
  fild  DWORD ptr [esi+18h]
  fmul  QWORD ptr [esi]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+6],al
  fld  QWORD ptr [szData11]
  fsin
  movzx  edx,BYTE ptr [ebx+5]
  movzx  ecx,BYTE ptr [ebx+1]
  movzx  eax,BYTE ptr [ebx+9]
  mov  [esi+18h],edx
  fild  DWORD ptr [esi+18h]
  fmulp  st(1),st
  fld  QWORD ptr [szData12]
  fsin
  fild  DWORD ptr [esi+18h]
  mov  [esi+18h],ecx
  fmulp  st(1),st
  faddp  st(1),st
  fild  DWORD ptr [esi+18h]
  fmul  QWORD ptr [esi+10h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+8],al
  fld  QWORD ptr [szData6]
  fsin
  movzx  eax,BYTE ptr [ebx+5]
  movzx  ecx,BYTE ptr [ebx+9]
  movzx  edx,BYTE ptr [ebx+0Ah]
  mov  [esi],edx
  fstp  QWORD ptr [esi+30h]
  fld  QWORD ptr [szData4]
  fsin
  fstp  QWORD ptr [esi+8]
  fld  QWORD ptr [szData5]
  fsin
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi]
  mov  [esi],ecx
  fmul  QWORD ptr [esi+8]
  faddp  st(1),st
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+30h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+2],al
  fld  QWORD ptr [szData12]
  fsin
  movzx  eax,BYTE ptr [ebx]
  movzx  ecx,BYTE ptr [ebx+0Bh]
  movzx  edx,BYTE ptr [ebx+8]
  mov  [esi],edx
  fstp  QWORD ptr [esi+20h]
  fld  QWORD ptr [szData13]
  fsin
  fstp  QWORD ptr [esi+10h]
  fld  QWORD ptr [szData9]
  fsin
  fstp  QWORD ptr [esi+18h]
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmul  QWORD ptr [esi+18h]
  fild  DWORD ptr [esi]
  mov  [esi],ecx
  fmul  QWORD ptr [esi+10h]
  faddp  st(1),st
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+20h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+3],al
  fld  QWORD ptr [szData7]
  fsin
  movzx  eax,BYTE ptr [ebx+8]
  movzx  ecx,BYTE ptr [ebx+3]
  movzx  edx,BYTE ptr [ebx+6]
  mov  [esi],edx
  fstp  QWORD ptr [esi+28h]
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmul  QWORD ptr [esi+28h]
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+10h]
  faddp  st(1),st
  mov  [esi],ecx
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+8]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+4],al
  fld  QWORD ptr [szData14]
  fsin
  movzx  eax,BYTE ptr [ebx]
  movzx  ecx,BYTE ptr [ebx+0Ah]
  movzx  edx,BYTE ptr [ebx+8]
  mov  [esi],edx
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi]
  mov  [esi],ecx
  fmul  QWORD ptr [esi+28h]
  faddp  st(1),st
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+18h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+7],al
  fld  QWORD ptr [szData11]
  fsin
  movzx  eax,BYTE ptr [ebx+1]
  movzx  ecx,BYTE ptr [ebx+9]
  movzx  edx,BYTE ptr [ebx+5]
  mov  [esi],edx
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi]
  mov  [esi],ecx
  fmul  QWORD ptr [esi+28h]
  faddp  st(1),st
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+20h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+8],al
  fld  QWORD ptr [szData15]
  fsin
  movzx  eax,BYTE ptr [ebx+9]
  movzx  ecx,BYTE ptr [ebx+0Bh]
  movzx  edx,BYTE ptr [ebx+3]
  mov  [esi],edx
  fild  DWORD ptr [esi]
  mov  [esi],eax
  fmulp  st(1),st
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+8]
  faddp  st(1),st
  mov  [esi],ecx
  fild  DWORD ptr [esi]
  fmul  QWORD ptr [esi+30h]
  faddp  st(1),st
  fstcw  flag1
  mov  ax,flag1
  or  ah,0Ch
  mov  flag2,ax
  fldcw  flag2
  fistp  QWORD ptr [szRlt]
  fldcw  flag1
  mov  eax,DWORD ptr [szRlt]
  xor  edx,edx
  mov  ecx,0Ah
  idiv  ecx
  invoke  return,edx
  mov  [edi+9],al
  mov  ecx,0Ah
  mov  WORD ptr [edi],0707h
@@:
  mov  dl,[edi]
  add  dl,30h
  mov  [edi],dl
  inc  edi
  dec  ecx
  jnz  @b
  invoke  SetDlgItemText,hDlg,IDC_REG,addr szSerial
  popad
  ret
GetRegKey  endp

【版权声明】  本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!