acafeel 发表于 2007-11-10 16:13:28

风月宝鉴(修正版)的注册算法分析 + 注册机源代码

风月宝鉴(修正版)的注册算法分析 + 注册机源代码


一款比较独特的软件,想看看里面到底是些什么内容,便分析了下,简单写出来。

软件在未注册的状态下,每次进入具体页面时会弹出一个InPut输入对话框;随便的输入注册名:aCaFeeL,注册码:12345678,点击OK按钮,程序弹出Message对话框,提示密码不对。

程序加了压缩壳,不管它,拖入OD中,按F9键运行,然后按Ctrl+A键分析,下断点:bp MessageBoxA,重复上面的注册步骤,此时程序中断,返回几次后便来到了这里:

>>>>>>
0045C9EC   $55               push    ebp                        ;下断点:bp MessageBoxA,
0045C9ED   .8BEC               mov   ebp, esp                   ;程序中断,
0045C9EF   .81C4 BCFEFFFF      add   esp, -144                  ;返回几次后便来到了这里!
0045C9F5   .53               push    ebx
0045C9F6   .56               push    esi
0045C9F7   .57               push    edi
0045C9F8   .33DB               xor   ebx, ebx
0045C9FA   .899D BCFEFFFF      mov   dword ptr , ebx
0045CA00   .899D C8FEFFFF      mov   dword ptr , ebx
0045CA06   .894D F4            mov   dword ptr , ecx
0045CA09   .8955 F8            mov   dword ptr , edx
0045CA0C   .8945 FC            mov   dword ptr , eax
0045CA0F   .33C0               xor   eax, eax
0045CA11   .55               push    ebp
0045CA12   .68 D2CC4500      push    风月宝鉴.0045CCD2
0045CA17   .64:FF30            push    dword ptr fs:
0045CA1A   .64:8920            mov   dword ptr fs:, esp
0045CA1D   .8B45 F8            mov   eax, dword ptr
0045CA20   .8B00               mov   eax, dword ptr
0045CA22   .E8 754EFBFF      call    风月宝鉴.0041189C
0045CA27   .C645 F3 00         mov   byte ptr , 0
0045CA2B   .8D8D CCFEFFFF      lea   ecx, dword ptr
0045CA31   .8B55 F4            mov   edx, dword ptr
0045CA34   .8B45 FC            mov   eax, dword ptr
0045CA37   .E8 50FFFFFF      call    风月宝鉴.0045C98C
0045CA3C   .33D2               xor   edx, edx
0045CA3E   .55               push    ebp
0045CA3F   .68 A7CC4500      push    风月宝鉴.0045CCA7
0045CA44   .64:FF32            push    dword ptr fs:
0045CA47   .64:8922            mov   dword ptr fs:, esp
0045CA4A   .8A45 CC            mov   al, byte ptr
0045CA4D   .3A05 25E04800      cmp   al, byte ptr       ;关键跳转
0045CA53   .75 5A            jnz   short 风月宝鉴.0045CAAF    ;爆破,可从这里下手!
0045CA55   .8B45 FC            mov   eax, dword ptr
0045CA58   .66:8378 32 00      cmp   word ptr , 0
0045CA5D   .75 09            jnz   short 风月宝鉴.0045CA68
0045CA5F   .8B45 FC            mov   eax, dword ptr
0045CA62   .C640 29 00         mov   byte ptr , 0
0045CA66   .EB 1B            jmp   short 风月宝鉴.0045CA83
0045CA68   >8B45 FC            mov   eax, dword ptr
0045CA6B   .8078 29 00         cmp   byte ptr , 0       ; 与 0 比较
0045CA6F   .75 12            jnz   short 风月宝鉴.0045CA83    ;是否选择了[记住密码]选项
0045CA71   .8B75 FC            mov   esi, dword ptr
0045CA74   .8B55 FC            mov   edx, dword ptr
0045CA77   .8B46 34            mov   eax, dword ptr
0045CA7A   .FF56 30            call    dword ptr          ;【关键算法】决定AL的结果,F7进入:
0045CA7D   .8B55 FC            mov   edx, dword ptr
0045CA80   .8842 29            mov   byte ptr , al      ;al ->     ;?
0045CA83   >8B45 FC            mov   eax, dword ptr
0045CA86   .8078 29 00         cmp   byte ptr , 0       ;不能为0,由上面的al决定
0045CA8A      75 23            jnz   short 风月宝鉴.0045CAAF    ;关键跳转,一跳,便OK了!
0045CA8C   .8B45 FC            mov   eax, dword ptr
0045CA8F   .E8 D0020000      call    风月宝鉴.0045CD64          ;NAG错误对话窗口
0045CA94   .8B45 F8            mov   eax, dword ptr
0045CA97   .8B00               mov   eax, dword ptr
0045CA99   .E8 FE4DFBFF      call    风月宝鉴.0041189C
0045CA9E   .8B45 FC            mov   eax, dword ptr
0045CAA1   .C640 29 00         mov   byte ptr , 0
0045CAA5   .E8 DA6CFAFF      call    风月宝鉴.00403784
0045CAAA   .E9 FF010000      jmp   风月宝鉴.0045CCAE
0045CAAF   >8B45 FC            mov   eax, dword ptr
0045CAB2   .8B40 24            mov   eax, dword ptr
>>>>>>



毫无疑问,注册成功与否,便是看0045CA80 这里的al是否为0了,不为0才注册成功,要分析算法,自然要进入 0045CA7A 地址的:

0045CA7A   .FF56 30            call    dword ptr

在这里F2键下断,用OD重新载入程序后,F9键运行,重复上面的步骤,便断在了这里,按F7建进入该子程序后:

>>>>>>
0048BDDC/.55               push    ebp
0048BDDD|.8BEC               mov   ebp, esp
0048BDDF|.B9 06000000      mov   ecx, 6
0048BDE4|>6A 00            /push    0
0048BDE6|.6A 00            |push    0
0048BDE8|.49               |dec   ecx
0048BDE9|.^ 75 F9            \jnz   short 风月宝鉴.0048BDE4
0048BDEB|.53               push    ebx
0048BDEC|.56               push    esi
0048BDED|.8BF0               mov   esi, eax
0048BDEF|.33C0               xor   eax, eax
0048BDF1|.55               push    ebp
0048BDF2|.68 1BC04800      push    风月宝鉴.0048C01B
0048BDF7|.64:FF30            push    dword ptr fs:
0048BDFA|.64:8920            mov   dword ptr fs:, esp
0048BDFD|.33DB               xor   ebx, ebx
0048BDFF|.8D4D F8            lea   ecx, dword ptr
0048BE02|.8D55 FC            lea   edx, dword ptr
0048BE05|.8BC6               mov   eax, esi
0048BE07|.E8 A8030000      call    风月宝鉴.0048C1B4
0048BE0C|.A1 E8E44800      mov   eax, dword ptr
0048BE11|.8B00               mov   eax, dword ptr
0048BE13|.8B80 18030000      mov   eax, dword ptr
0048BE19|.8B55 FC            mov   edx, dword ptr    ;注册名 -> eax
0048BE1C|.E8 A7E0F9FF      call    风月宝鉴.00429EC8
0048BE21|.A1 E8E44800      mov   eax, dword ptr
0048BE26|.8B00               mov   eax, dword ptr
0048BE28|.8B80 1C030000      mov   eax, dword ptr
0048BE2E|.8B55 F8            mov   edx, dword ptr    ;注册码 -> edx
0048BE31|.E8 92E0F9FF      call    风月宝鉴.00429EC8
0048BE36|.A1 84E94800      mov   eax, dword ptr
0048BE3B|.8B00               mov   eax, dword ptr
0048BE3D|.83E8 01            sub   eax, 1                     ;Switch (cases 1..3)
0048BE40|.72 0A            jb      short 风月宝鉴.0048BE4C
0048BE42|.74 0C            je      short 风月宝鉴.0048BE50
0048BE44|.48               dec   eax
0048BE45|.83E8 02            sub   eax, 2
0048BE48|.72 30            jb      short 风月宝鉴.0048BE7A
0048BE4A|.EB 7C            jmp   short 风月宝鉴.0048BEC8
0048BE4C|>B3 01            mov   bl, 1
0048BE4E|.EB 78            jmp   short 风月宝鉴.0048BEC8
0048BE50|>8D55 F4            lea   edx, dword ptr    ;Case 1 of switch 0048BE3D
0048BE53|.A1 E8E44800      mov   eax, dword ptr
0048BE58|.8B00               mov   eax, dword ptr
0048BE5A|.8B80 1C030000      mov   eax, dword ptr
0048BE60|.E8 33E0F9FF      call    风月宝鉴.00429E98
0048BE65|.8B55 F4            mov   edx, dword ptr
0048BE68|.A1 54E54800      mov   eax, dword ptr
0048BE6D|.8B00               mov   eax, dword ptr
0048BE6F|.E8 B481F7FF      call    风月宝鉴.00404028
0048BE74|.75 52            jnz   short 风月宝鉴.0048BEC8
0048BE76|.B3 01            mov   bl, 1
0048BE78|.EB 4E            jmp   short 风月宝鉴.0048BEC8
0048BE7A|>8D55 EC            lea   edx, dword ptr     ;Cases 2,3 of switch 0048BE3D
0048BE7D|.A1 E8E44800      mov   eax, dword ptr
0048BE82|.8B00               mov   eax, dword ptr
0048BE84|.8B80 18030000      mov   eax, dword ptr
0048BE8A|.E8 09E0F9FF      call    风月宝鉴.00429E98
0048BE8F|.8B45 EC            mov   eax, dword ptr     ;注册名
0048BE92|.8D4D F0            lea   ecx, dword ptr
0048BE95|.8B15 54E54800      mov   edx, dword ptr
0048BE9B|.8B12               mov   edx, dword ptr        ; -> edx
0048BE9D|.E8 DE9EFFFF      call    风月宝鉴.00485D80
0048BEA2|.8B45 F0            mov   eax, dword ptr     ; -> eax
0048BEA5|.50               push    eax
0048BEA6|.8D55 E8            lea   edx, dword ptr
0048BEA9|.A1 E8E44800      mov   eax, dword ptr
0048BEAE|.8B00               mov   eax, dword ptr
0048BEB0|.8B80 1C030000      mov   eax, dword ptr
0048BEB6|.E8 DDDFF9FF      call    风月宝鉴.00429E98
0048BEBB|.8B55 E8            mov   edx, dword ptr
0048BEBE|.58               pop   eax
0048BEBF|.E8 6481F7FF      call    风月宝鉴.00404028
0048BEC4|.75 02            jnz   short 风月宝鉴.0048BEC8
0048BEC6|.B3 01            mov   bl, 1
0048BEC8|>84DB               test    bl, bl                     ;bl and bl = 0 ?
0048BECA|.0F85 FE000000      jnz   风月宝鉴.0048BFCE          ;不等,则跳
0048BED0|.A1 E8E44800      mov   eax, dword ptr
0048BED5|.8B00               mov   eax, dword ptr
0048BED7|.8B10               mov   edx, dword ptr
0048BED9|.FF92 D8000000      call    dword ptr          ;调用输入框
0048BEDF|.48               dec   eax
0048BEE0|.0F85 E8000000      jnz   风月宝鉴.0048BFCE
0048BEE6|.A1 84E94800      mov   eax, dword ptr
0048BEEB|.8B00               mov   eax, dword ptr
0048BEED|.83E8 01            sub   eax, 1                     ;Switch (cases 1..3)
0048BEF0|.72 0A            jb      short 风月宝鉴.0048BEFC
0048BEF2|.74 0C            je      short 风月宝鉴.0048BF00
0048BEF4|.48               dec   eax
0048BEF5|.83E8 02            sub   eax, 2
0048BEF8|.72 30            jb      short 风月宝鉴.0048BF2A
0048BEFA|.EB 7C            jmp   short 风月宝鉴.0048BF78
0048BEFC|>B3 01            mov   bl, 1
0048BEFE|.EB 78            jmp   short 风月宝鉴.0048BF78
0048BF00|>8D55 E4            lea   edx, dword ptr     ;Case 1 of switch 0048BEED
0048BF03|.A1 E8E44800      mov   eax, dword ptr
0048BF08|.8B00               mov   eax, dword ptr
0048BF0A|.8B80 1C030000      mov   eax, dword ptr
0048BF10|.E8 83DFF9FF      call    风月宝鉴.00429E98
0048BF15|.8B55 E4            mov   edx, dword ptr
0048BF18|.A1 54E54800      mov   eax, dword ptr
0048BF1D|.8B00               mov   eax, dword ptr
0048BF1F|.E8 0481F7FF      call    风月宝鉴.00404028
0048BF24|.75 52            jnz   short 风月宝鉴.0048BF78
0048BF26|.B3 01            mov   bl, 1
0048BF28|.EB 4E            jmp   short 风月宝鉴.0048BF78
0048BF2A|>8D55 DC            lea   edx, dword ptr     ;Cases 2,3 of switch 0048BEED
0048BF2D|.A1 E8E44800      mov   eax, dword ptr
0048BF32|.8B00               mov   eax, dword ptr
0048BF34|.8B80 18030000      mov   eax, dword ptr
0048BF3A|.E8 59DFF9FF      call    风月宝鉴.00429E98
0048BF3F|.8B45 DC            mov   eax, dword ptr     ;注册名 -> eax
0048BF42|.8D4D E0            lea   ecx, dword ptr
0048BF45|.8B15 54E54800      mov   edx, dword ptr
0048BF4B|.8B12               mov   edx, dword ptr        ;"fengyuebaojian520++" -> edx
0048BF4D|.E8 2E9EFFFF      call    风月宝鉴.00485D80          ;【注册算法】,F7进入:
0048BF52|.8B45 E0            mov   eax, dword ptr     ;真正的注册码 -> eax
>>>>>>



从上面可知道,要分析算法,需要进入 0048BF4D 地址的:

0048BF4D|.E8 2E9EFFFF      call    风月宝鉴.00485D80

在这里再用F2键下断,用OD重新载入程序后,F9键运行,再次重复上面的步骤,便断在了这里,按F7建进入该子程序后:

>>>>>>
00485D80/$55               push    ebp                        ;算法分析开始
00485D81|.8BEC               mov   ebp, esp
00485D83|.83C4 D0            add   esp, -30
00485D86|.53               push    ebx
00485D87|.56               push    esi
00485D88|.57               push    edi
00485D89|.33DB               xor   ebx, ebx
00485D8B|.895D D0            mov   dword ptr , ebx
00485D8E|.895D D4            mov   dword ptr , ebx
00485D91|.895D E0            mov   dword ptr , ebx
00485D94|.895D EC            mov   dword ptr , ebx
00485D97|.895D E8            mov   dword ptr , ebx
00485D9A|.895D E4            mov   dword ptr , ebx
00485D9D|.894D F4            mov   dword ptr , ecx
00485DA0|.8955 F8            mov   dword ptr , edx
00485DA3|.8945 FC            mov   dword ptr , eax
00485DA6|.8B45 FC            mov   eax, dword ptr
00485DA9|.E8 1EE3F7FF      call    风月宝鉴.004040CC
00485DAE|.8B45 F8            mov   eax, dword ptr
00485DB1|.E8 16E3F7FF      call    风月宝鉴.004040CC
00485DB6|.33C0               xor   eax, eax
00485DB8|.55               push    ebp
00485DB9|.68 745F4800      push    风月宝鉴.00485F74
00485DBE|.64:FF30            push    dword ptr fs:
00485DC1|.64:8920            mov   dword ptr fs:, esp
00485DC4|.8D45 E8            lea   eax, dword ptr
00485DC7|.8B55 FC            mov   edx, dword ptr
00485DCA|.E8 61DFF7FF      call    风月宝鉴.00403D30
00485DCF|.8D45 E4            lea   eax, dword ptr
00485DD2|.8B55 F8            mov   edx, dword ptr
00485DD5|.E8 56DFF7FF      call    风月宝鉴.00403D30
00485DDA|.8B45 F4            mov   eax, dword ptr
00485DDD|.BA 8C5F4800      mov   edx, 风月宝鉴.00485F8C         ;i love ada
00485DE2|.E8 05DFF7FF      call    风月宝鉴.00403CEC
00485DE7|.837D E8 00         cmp   dword ptr , 0
00485DEB|.0F84 4E010000      je      风月宝鉴.00485F3F
00485DF1|.837D E4 00         cmp   dword ptr , 0
00485DF5|.0F84 44010000      je      风月宝鉴.00485F3F
00485DFB|.8B45 E4            mov   eax, dword ptr
00485DFE|.E8 15E1F7FF      call    风月宝鉴.00403F18
00485E03|.8945 F0            mov   dword ptr , eax
00485E06|.33FF               xor   edi, edi
00485E08|.BB 80000000      mov   ebx, 80
00485E0D|.8B45 E8            mov   eax, dword ptr
00485E10|.E8 03E1F7FF      call    风月宝鉴.00403F18
00485E15|.8BF0               mov   esi, eax
00485E17|.83FE 01            cmp   esi, 1
00485E1A|.7C 7E            jl      short 风月宝鉴.00485E9A
00485E1C|>8B45 E8            /mov   eax, dword ptr    ;注册名 -> eax
00485E1F|.0FB64430 FF      |movzx   eax, byte ptr ;从尾部依次取注册名的各字符码
00485E24|.03C3               |add   eax, ebx                  ;eax := eax + ebx;
00485E26|.B9 FF000000      |mov   ecx, 0FF                  ;ecx := $FF;
00485E2B|.99               |cdq
00485E2C|.F7F9               |idiv    ecx                     ;edx := eax mon ecx的余数;
00485E2E|.8BDA               |mov   ebx, edx                  ;ebx := edx;
00485E30|.3B7D F0            |cmp   edi, dword ptr
00485E33|.7D 03            |jge   short 风月宝鉴.00485E38
00485E35|.47               |inc   edi
00485E36|.EB 05            |jmp   short 风月宝鉴.00485E3D
00485E38|>BF 01000000      |mov   edi, 1
00485E3D|>8B45 E4            |mov   eax, dword ptr    ;"fengyuebaojian520++" -> eax
00485E40|.0FB64438 FF      |movzx   eax, byte ptr ;依次取该字符串的字符码
00485E45|.33D8               |xor   ebx, eax                  ;ebx := ebx xor eax;//
00485E47|.8BC6               |mov   eax, esi
00485E49|.25 01000080      |and   eax, 80000001             ;eax := eax and $80000001;
00485E4E|.79 05            |jns   short 风月宝鉴.00485E55
00485E50|.48               |dec   eax
00485E51|.83C8 FE            |or      eax, FFFFFFFE
00485E54|.40               |inc   eax
00485E55|>85C0               |test    eax, eax
00485E57|.75 27            |jnz   short 风月宝鉴.00485E80
00485E59|.8D45 E0            |lea   eax, dword ptr
00485E5C|.50               |push    eax                     ; /Arg1
00485E5D|.895D D8            |mov   dword ptr , ebx   ; |
00485E60|.C645 DC 00         |mov   byte ptr , 0      ; |
00485E64|.8D55 D8            |lea   edx, dword ptr    ; |
00485E67|.33C9               |xor   ecx, ecx                  ; |
00485E69|.B8 A05F4800      |mov   eax, 风月宝鉴.00485FA0      ; |%1.2x
00485E6E|.E8 1136F8FF      |call    风月宝鉴.00409484             ; \风月宝鉴.00409484
00485E73|.8B55 E0            |mov   edx, dword ptr
00485E76|.8D45 EC            |lea   eax, dword ptr
00485E79|.E8 A2E0F7FF      |call    风月宝鉴.00403F20
00485E7E|.EB 15            |jmp   short 风月宝鉴.00485E95
00485E80|>8D45 D4            |lea   eax, dword ptr
00485E83|.8BD3               |mov   edx, ebx
00485E85|.E8 B6DFF7FF      |call    风月宝鉴.00403E40
00485E8A|.8B55 D4            |mov   edx, dword ptr
00485E8D|.8D45 EC            |lea   eax, dword ptr
00485E90|.E8 8BE0F7FF      |call    风月宝鉴.00403F20
00485E95|>4E               |dec   esi
00485E96|.85F6               |test    esi, esi
00485E98|.^ 75 82            \jnz   short 风月宝鉴.00485E1C
00485E9A|>8D45 EC            lea   eax, dword ptr
00485E9D|.BA B05F4800      mov   edx, 风月宝鉴.00485FB0         ;"12345678" -> edx
00485EA2|.E8 79E0F7FF      call    风月宝鉴.00403F20
00485EA7|.8B45 EC            mov   eax, dword ptr     ;连接后的新字符串->eax
00485EAA|.E8 69E0F7FF      call    风月宝鉴.00403F18            ;获取其长度->eax
00485EAF|.83F8 07            cmp   eax, 7                     ;与7比较
00485EB2|.7E 16            jle   short 风月宝鉴.00485ECA      ;小于或等于,则跳
00485EB4|.8D45 EC            lea   eax, dword ptr
00485EB7|.50               push    eax
00485EB8|.B9 07000000      mov   ecx, 7                     ;ecx := 7;
00485EBD|.BA 01000000      mov   edx, 1                     ;edx := 1;
00485EC2|.8B45 EC            mov   eax, dword ptr
00485EC5|.E8 56E2F7FF      call    风月宝鉴.00404120
00485ECA|>8D45 E8            lea   eax, dword ptr
00485ECD|.E8 C6DDF7FF      call    风月宝鉴.00403C98
00485ED2|.8B45 EC            mov   eax, dword ptr
00485ED5|.E8 3EE0F7FF      call    风月宝鉴.00403F18          ;取新生成字符串的前7位字符
00485EDA|.8BF0               mov   esi, eax                   ;esi := 7;
00485EDC|.83FE 01            cmp   esi, 1
00485EDF|.7C 53            jl      short 风月宝鉴.00485F34
00485EE1|>8B45 EC            /mov   eax, dword ptr    ;新生成字符串的前7位字符->eax
00485EE4|.0FB64430 FF      |movzx   eax, byte ptr ;从该字符串的尾部依次反序取字符码
00485EE9|.03C3               |add   eax, ebx                  ;eax := eax + ebx;
00485EEB|.B9 FF000000      |mov   ecx, 0FF                  ;ecx := $FF;
00485EF0|.99               |cdq
00485EF1|.F7F9               |idiv    ecx                     ;edx := eax mod ecx 的余数;
00485EF3|.8BDA               |mov   ebx, edx                  ;ebx := edx;
00485EF5|.83FF 01            |cmp   edi, 1
00485EF8|.7D 03            |jge   short 风月宝鉴.00485EFD       ;大于或等于,跳
00485EFA|.4F               |dec   edi
00485EFB|.EB 03            |jmp   short 风月宝鉴.00485F00
00485EFD|>8B7D F0            |mov   edi, dword ptr
00485F00|>8B45 E4            |mov   eax, dword ptr    ;"fengyuebaojian520++" -> eax
00485F03|.0FB64438 FF      |movzx   eax, byte ptr ;eax := $2B;
00485F08|.33D8               |xor   ebx, eax                  ;ebx := ebx xor eax;
00485F0A|.8D45 D0            |lea   eax, dword ptr
00485F0D|.50               |push    eax                     ; /Arg1
00485F0E|.895D D8            |mov   dword ptr , ebx   ; |
00485F11|.C645 DC 00         |mov   byte ptr , 0      ; |
00485F15|.8D55 D8            |lea   edx, dword ptr    ; |
00485F18|.33C9               |xor   ecx, ecx                  ; |
00485F1A|.B8 A05F4800      |mov   eax, 风月宝鉴.00485FA0      ; |%1.2x
00485F1F|.E8 6035F8FF      |call    风月宝鉴.00409484             ; \风月宝鉴.00409484
00485F24|.8B55 D0            |mov   edx, dword ptr    ;ASCII "结果" -> edx
00485F27|.8D45 E8            |lea   eax, dword ptr
00485F2A|.E8 F1DFF7FF      |call    风月宝鉴.00403F20
00485F2F|.4E               |dec   esi                     ;esi := esi - 1;
00485F30|.85F6               |test    esi, esi                  ;esi and esi = 0 ?
00485F32|.^ 75 AD            \jnz   short 风月宝鉴.00485EE1       ;不为0,继续循环
00485F34|>8B45 F4            mov   eax, dword ptr
00485F37|.8B55 E8            mov   edx, dword ptr     ;真正的注册码->edx
00485F3A|.E8 ADDDF7FF      call    风月宝鉴.00403CEC
00485F3F|>33C0               xor   eax, eax
00485F41|.5A               pop   edx
00485F42|.59               pop   ecx
00485F43|.59               pop   ecx
00485F44|.64:8910            mov   dword ptr fs:, edx
00485F47|.68 7B5F4800      push    风月宝鉴.00485F7B
00485F4C|>8D45 D0            lea   eax, dword ptr
00485F4F|.BA 02000000      mov   edx, 2
00485F54|.E8 63DDF7FF      call    风月宝鉴.00403CBC
00485F59|.8D45 E0            lea   eax, dword ptr
00485F5C|.BA 04000000      mov   edx, 4
00485F61|.E8 56DDF7FF      call    风月宝鉴.00403CBC
00485F66|.8D45 F8            lea   eax, dword ptr
00485F69|.BA 02000000      mov   edx, 2
00485F6E|.E8 49DDF7FF      call    风月宝鉴.00403CBC
00485F73\.C3               retn
>>>>>>



通过上面的分析,我们知道了其注册算法的方式为:

当注册名的长度为‘奇数’时,反顺序依次取注册名中各个字符的ASCII码,经过循环运算后,得到一个新的字符串,取该新字符串的‘奇数’位不变,‘偶数’位再次取码拆解,成为一个长度增加1.5倍的新字符串;再连接字符串12345678后,取这个新字符串的前7位,再经过一个循环运算后,得到真正的结果;
比如:
注册名为:               aBc
反序后为:               cBa
取码为:            63    42   61
循序运算后为:      85    A2   6A
偶数’位取码拆解后为:854132 6A   (41 32 即是偶数位的 A2 拆解为 A 和 2 的ASCII码值)
连接‘12345678’后为:854132 6A3132333435363738
取前7位后,得到:   854132 6A313233
再循序运算后为:      B6C3DF 61B8D273
将其转换为字符串‘B6C3DF61B8D273’后,即为真正的注册码了;


当注册名的长度为‘偶数’时,则‘奇数’位拆分,‘偶数’位不变,其余照样。
比如:
注册名为:               aB
反序后为:               Ba
取码为:                42    61
循序运算后为:          A4    63
奇数’位取码拆解后为:413463   (41 34 即是奇数位的 A4 拆解为 A 和 4 的ASCII码值)
连接‘12345678’后为:4134633132333435363738
取前7位后,得到:   41346331323334
再循序运算后为:      BCC4DD24ACCB26
将其转换为字符串‘BCC4DD24ACCB26’后,即为真正的注册码了!



其注册算法转换成用 Delphi + KOL/MCK 写的代码即是如下形式:(已写成为string函数格式,方便你的调用和修改,嘿嘿 :)


//字符串反顺序函数
function stringFX(czSTR: string): string;
var
posSTR : integer;
begin
for posSTR := length(czSTR) downto 1 do
   czSTR := czSTR+czSTR;
posSTR := length(czSTR) div 2;
Result := copy(czSTR, posSTR+1, posSTR);
end;

//风月宝鉴注册算法
function SEX_SN(Name: string): string;
var
i, ii, eax, ebx : integer;
newSTR, tmpSTR, str, newSTR2, czSTR : string;
begin
if (length(Name) mod 2 = 0)
//注册名长度为'偶数'时的算法//
then begin
         Name := stringFX(Name);//注册名先反转顺序

         ebx := $80;//初始化相关变量
         str := 'fengyuebaojian520++';
         for i := 1 to length(Name) do
         begin
             eax := ord(Name) + ebx;
             ebx := eax mod $0FF;
             eax := ord(str);
             ebx := ebx xor eax;
             //newSTR := newSTR + int2hex(ebx,18);
             if (i mod 2 = 0) //当为字符串的‘偶数’位字符时
             then //为偶数
               newSTR := newSTR + int2hex(ebx,2)
             else //为奇数
               begin
               tmpSTR := int2hex(ebx,2);
               for ii := 1 to length(tmpSTR) do
                   newSTR := newSTR + int2hex(ord(tmpSTR),2);
               end;
         end;

         newSTR := copy(newSTR + '3132333435363738',1,14); //取前14位字符
         
         for i := 1 to length(newSTR) do
         if (i mod 2 <> 0) //当为字符串的‘奇数’位字符时
         then newSTR2 := newSTR2 + chr(hex2int(copy(newSTR,i,2)));

         newSTR2 := stringFX(newSTR2);//反转字符串

         for i := 1 to length(newSTR2) do
         begin
             eax := ord(newSTR2) + ebx;
             ebx := eax mod $0FF;
             eax := $2B; //'+'
             ebx := ebx xor eax;
             czSTR := czSTR + int2hex(ebx,18);
         end;
       end
//注册名长度为'奇数'时的算法//      
else begin
         Name := stringFX(Name);//注册名先反转顺序

         ebx := $80;//初始化相关变量
         str := 'fengyuebaojian520++';
         for i := 1 to length(Name) do
         begin
             eax := ord(Name) + ebx;
             ebx := eax mod $0FF;
             eax := ord(str);
             ebx := ebx xor eax;
             //newSTR := newSTR + int2hex(ebx,18);
             if (i mod 2 <> 0) //当为字符串的‘奇数’位字符时
             then //为奇数
               newSTR := newSTR + int2hex(ebx,2)
             else //为偶数
               begin
               tmpSTR := int2hex(ebx,2);
               for ii := 1 to length(tmpSTR) do
                   newSTR := newSTR + int2hex(ord(tmpSTR),2);
               end;
         end;

         newSTR := copy(newSTR + '3132333435363738',1,14); //取前7位字符

         for i := 1 to length(newSTR) do
         if (i mod 2 <> 0) //当为字符串的‘奇数’位字符时
         then newSTR2 := newSTR2 + chr(hex2int(copy(newSTR,i,2)));

         newSTR2 := stringFX(newSTR2);//反转字符串

         for i := 1 to length(newSTR2) do
         begin
             eax := ord(newSTR2) + ebx;
             ebx := eax mod $0FF;
             eax := $2B; //'+'
             ebx := ebx xor eax;
             czSTR := czSTR + int2hex(ebx,18);
         end;
       end;
Result := czSTR;
end;



上面的注册机算法在多台机器上使用不同注册名通过验证,但没有时间再优化它了,应该不存在bug的问题;

注册成功,则注册名和注册码便保存在了: 内。



放上两组可用的Key:

注册名:aCaFeeL
注册码:E00E6C0A146020

或者

注册名:看看
注册码:B8304EA90B1561



好的,就到这里结束吧!分析难免有不当之处,还望大家给我指出来!

wan 发表于 2007-11-10 18:33:46

学习一下楼主的耐心啊/:good
当时我见论坛出了个DLL内存补丁的东东,试用了把它暴的,方便点

Nisy 发表于 2007-11-12 17:43:35

禁用 Discuz!代码在这里打沟 算法部分的代码显示就OK了

感谢兄弟分享/:09

fwtfd 发表于 2007-11-14 16:02:00

分析的很详细 ,学习了

acafeel 发表于 2007-11-16 14:12:17

原帖由 Nisy 于 2007-11-12 17:43 发表 https://www.chinapyg.com/images/common/back.gif
禁用 Discuz!代码在这里打沟 算法部分的代码显示就OK了...

好的,又学习了:loveliness:

秋之夜 发表于 2007-11-18 00:39:27

谢谢楼主的耐心说明,受教了。。

fengasdf 发表于 2007-11-19 17:09:39

学习逆向工程ing...

sdprtf 发表于 2007-11-21 17:10:59

好东西,谢谢楼主

sdprtf 发表于 2007-11-22 09:38:22

好的,又学习了:lol:

clh1979cmh 发表于 2007-11-22 10:58:02

继续!!!!好好学习吧
页: [1] 2
查看完整版本: 风月宝鉴(修正版)的注册算法分析 + 注册机源代码