佳宜客户管理软件 v2.05 注册算法分析

这几天老想找个东西破破,无奈加密都太高明,我又太弱

下午逛 WZ,看到去年发的一个帖子(当时是发个破解混分数),后面有人求新版破解。
于是把新版下载下来研究

发现注册判断一点也没有变

给 MessageBoxA 设断点,随便输入注册码,断住后跳出 MessageBoxA 本身,然后再跳出一层函数,往上看,就找到了判断的地方:
005ED03D  0F85 FE000000 jnz   005ED141
上次是直接把这个 jnz 改成 jmp 的
现在仍然这么做,还是有效,任意注册码可注册成功
这个软件判断注册成功的时候会把正确的注册信息写入注册表,所以下次再开原版也没关系。



本来想就这么搞,继续混一分的。后来想想这太没追求了,于是开始一句一句看。

具体分析如下(里面好多都没用,只是我当时不知道哪些有用哪些没用,一句句看下来了):


005ECF4C  55            push  ebp
005ECF4D  68 B2D15E00   push  005ED1B2
005ECF52  64
:FF30       push  dword ptr fs:[eax]
005ECF55  64:8920       mov   dword ptr fs:[eax], esp
005ECF58  8D55 F0       lea   edx, dword ptr [ebp-10]     ; EDX="hNG"
005ECF5B  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
005ECF5E  8B80 04030000 mov   eax, dword ptr [eax+304]    ; EAX=[EAX+304]=[01660D74]=01656380
005ECF64  E8 3F1BE6FF   call  0044EAA8
005ECF69  8B45 
F0       mov   eax, dword ptr [ebp-10]     ; EAX=0163906C="abcd"
005ECF6C  8D55 F4       lea   edx, dword ptr [ebp-C]      ; [ebp-C]=00000000
005ECF6F  E8 18C8E1FF   call  0040978C                    ; 去除用户名首尾空格
005ECF74  837D F4 00    cmp   dword ptr [ebp-C], 0        ; [ebp-C]=0163B2D0="abcd"
005ECF78  75 22         jnz   short 005ECF9C
005ECF7A  6A 00         
push  0
005ECF7C  68 
C0D15E00   push  005ED1C0
005ECF81  
E8 2AFBFEFF   call  <jmp.&PunUnitLib.ShowMess>  ; 提示填写用户名称
005ECF86  8B45 FC       mov   eax, dword ptr [ebp-4]
005ECF89  8B80 04030000 mov   eax, dword ptr [eax+304]
005ECF8F  8B10          mov   edx, dword ptr [eax]
005ECF91  FF92 C0000000 call  dword ptr [edx+C0]
005ECF97  E9 B1010000   jmp   005ED14D
005ECF9C  8D55 
E8       lea   edx, dword ptr [ebp-18]     ; EDX=0012F39C, [EDX]=00000000
005ECF9F  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
005ECFA2  8B80 FC020000 mov   eax, dword ptr [eax+2FC]    ; EAX=[01660D6C]=01662F58, [EAX]=004331E8
005ECFA8  E8 FB1AE6FF   call  0044EAA8                    ; 不知道在干嘛
005ECFAD  8B45 E8       mov   eax, dword ptr [ebp-18]     ; EAX=0163B2D0="1234"
005ECFB0  8D55 EC       lea   edx, dword ptr [ebp-14]     ; [ebp-14]=00000000
005ECFB3  E8 D4C7E1FF   call  0040978C                    ; 去除注册码首尾空格
005ECFB8  837D EC 00    cmp   dword ptr [ebp-14], 0       ; [ebp-14]=01646B4C="1234"
005ECFBC  75 22         jnz   short 005ECFE0
005ECFBE  6A 00         
push  0
005ECFC0  68 
D4D15E00   push  005ED1D4
005ECFC5  
E8 E6FAFEFF   call  <jmp.&PunUnitLib.ShowMess>  ; 提示输入注册码
005ECFCA  8B45 FC       mov   eax, dword ptr [ebp-4]
005ECFCD  8B80 FC020000 mov   eax, dword ptr [eax+2FC]
005ECFD3  8B10          mov   edx, dword ptr [eax]
005ECFD5  FF92 C0000000 call  dword ptr [edx+C0]
005ECFDB  E9 6D010000   jmp   005ED14D
005ECFE0  
A1 94A96300   mov   eax, dword ptr [63A994]     ; EAX=[0063A994]=00639D44
005ECFE5  8B00          mov   eax, dword ptr [eax]        ; EAX=[00639D44]=005DCB44="6J9Y-K3H7"
005ECFE7  E8 0080E1FF   call  00404FEC                    ; 不知道在干嘛
005ECFEC  50            push  eax                         ; EAX=005DCB44="6J9Y-K3H7"
005ECFED  8D55 E4       lea   edx, dword ptr [ebp-1C]     ; [ebp-1C]=00000000
005ECFF0  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
005ECFF3  8B80 F4020000 mov   eax, dword ptr [eax+2F4]    ; EAX=[01660D64]=01662C98, [EAX]=004331E8
005ECFF9  E8 AA1AE6FF   call  0044EAA8                    ; 不知道在干嘛
005ECFFE  8B45 E4       mov   eax, dword ptr [ebp-1C]     ; EAX=[ebp-1C]=0165EC18="WD-WCARY0610755"
005ED001  E8 E67FE1FF   call  00404FEC                    ; 不知道在干嘛
005ED006  50            push  eax                         ; EAX=0165EC18="WD-WCARY0610755", 机器码
005ED007  E8 D4FAFEFF   call  <jmp.&PunUnitLib.GetRegPass>; 算注册码
005ED00C  8BD0          mov   edxeax                    ; EDX=EAX=01512524="6J9Y-5353-K3H7-7303"
005ED00E  8D45 F8       lea   eax, dword ptr [ebp-8]      ; [ebp-8]=[0012F3AC]=00000000
005ED011  E8 167DE1FF   call  00404D2C                    ; [ebp-8]=0165EC34=正确注册码
005ED016  8D55 DC       lea   edx, dword ptr [ebp-24]     ; [ebp-24]=00000000
005ED019  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=[0012F3B0]=01660A70
005ED01C  8B80 FC020000 mov   eax, dword ptr [eax+2FC]    ; EAX=[01660D6C]=01662F58, [EAX]=004331T8
005ED022  E8 811AE6FF   call  0044EAA8                    ; 不知道在干嘛
005ED027  8B45 DC       mov   eax, dword ptr [ebp-24]     ; EAX="1234", 错误注册码
005ED02A  8D55 E0       lea   edx, dword ptr [ebp-20]     ; [ebp-20]=[0012F394]=00000000
005ED02D  E8 5AC7E1FF   call  0040978C                    ; 复制字符串?
005ED032  8B45 E0       mov   eax, dword ptr [ebp-20]     ; EAX=[ebp-20]="1234", 错误注册码
005ED035  8B55 F8       mov   edx, dword ptr [ebp-8]      ; EDX=0165EC34=正确注册码
005ED038  E8 FB7EE1FF   call  00404F38                    ; 比较
005ED03D  0F85 FE000000 jnz   005ED141                    ; 不同则跳


上面是一段,大体情况已经清楚,注册码中的第一段和第三段是常量,第二段和第四段则是算出来的

下面看算注册码的函数
PunUnitLib.GetRegPass


007D9024  55            push  ebp
007D9025  8BEC          mov   ebpesp
007D9027  B9 06000000   mov   ecx6                    ; 循环 6 次
007D902C  6A 00         push  0
007D902E  6A 00         
push  0
007D9030  49            
dec   ecx
007D9031  75 F9         jnz   short 007D902C            ; 循环尾,一共 PUSH 了 12 个 0
007D9033  53            push  ebx                       ; EBX=01628E04="hNG"
007D9034  56            push  esi                       ; ESI=004773E0
007D9035  33C0          xor   eaxeax
007D9037  55            push  ebp
007D9038  68 F2917D00   push  007D91F2
007D903D  64
:FF30       push  dword ptr fs:[eax]
007D9040  64:8920       mov   dword ptr fs:[eax], esp
007D9043  8D45 EC       lea   eax, dword ptr [ebp-14]
007D9046  E8 65B5F8FF   call  007645B0
007D904B  8D45 
F0       lea   eax, dword ptr [ebp-10]   ; [ebp-10]=[0012F360]=00000000
007D904E  8B55 08       mov   edx, dword ptr [ebp+8]    ; EDX=[0012F348]=01512400="WD-WCARY0610755"
007D9051  E8 4AB7F8FF   call  007647A0
007D9056  8B45 
F0       mov   eax, dword ptr [ebp-10]   ; [ebp-10]=[0012F348]=01512400="WD-WCARY0610755"
007D9059  E8 0AB8F8FF   call  00764868                  ; 求机器码长度
007D905E  8BF0          mov   esieax                  ; ESI=EAX=0000000F
007D9060  85F6          test  esiesi
007D9062  7E 26         jle   short 007D908A            ; 机器码为空?
007D9064  BB 01000000   mov   ebx1                    ; 记录循环次数(N),下行开始循环
007D9069  8D4D E8       lea   ecx, dword ptr [ebp-18]   ; [ebp-18]=[0012F340]=00000000
007D906C  8B45 F0       mov   eax, dword ptr [ebp-10]   ; EAX="WD-WCARY0610755"
007D906F  0FB64418 FF   movzx eax, byte ptr [eax+ebx-1; EAX=第N个字符='W'=57h
007D9074  33D2          xor   edxedx
007D9076  E8 F905F9FF   call  00769674                  ; 数值转字符(十六进制)
007D907B  8B55 E8       mov   edx, dword ptr [ebp-18]   ; EDX=[ebp-18]=[0012F340]=0051241C="57"
007D907E  8D45 FC       lea   eax, dword ptr [ebp-4]    ; [ebp-4]=[0012F354]=00000000
007D9081  E8 EAB7F8FF   call  00764870                  ; [ebp-4]=0041241C="57"
007D9086  43            inc   ebx
007D9087  4E            dec   esi
007D9088  75 DF         jnz   short 007D9069            ; 循环尾
007D908A  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
                                                        ; 原来刚才的循环是把每一个字符的 ASCII 码拼起来
007D908D  E8 D6B7F8FF   call  00764868                  ; 求字符串长度
007D9092  8BF0          mov   esieax                  ; ESI=EAX=0000001E
007D9094  85F6          test  esiesi
007D9096  7E 2C         jle   short 007D90C4            ; 又来判断字符串为空?刚才不是判断过了。。
007D9098  BB 01000000   mov   ebx1                    ; 记录循环次数(N),下行开始循环
007D909D  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
007D90A0  E8 C3B7F8FF   call  00764868                  ; 求字符串长度, EAX=0000001E
007D90A5  2BC3          sub   eaxebx                  ; EAX=EAX-N=1D(N=1)
007D90A7  8B55 FC       mov   edx, dword ptr [ebp-4]    ; EDX=[ebp-4]=0151243C="57442D574341525930363130373535"
007D90AA  8A1402        mov   dl, byte ptr [edx+eax]    ; DL=倒数第N个字符 1st:DL='5'=35h, 2nd:DL='3'=33h
007D90AD  8D45 E4       lea   eax, dword ptr [ebp-1C]   ; [ebp-1C]=[0012F33C]=00000000
007D90B0  E8 DBB6F8FF   call  00764790
007D90B5  8B55 
E4       mov   edx, dword ptr [ebp-1C]   ; 1st: EDX=[ebp-1C]=[0012F33C]=0151242C, [EDX]=00000035
                                                        ; 2nd: EDX=[ebp-1C]=[0012F33C]=01512468, [EDX]=00000033
007D90B8  8D45 F8       lea   eax, dword ptr [ebp-8]    ; 1st: [ebp-8]=[0012F350]=00000000
                                                        ; 2nd: [ebp-8]=[0012F350]=0151242C="5"
007D90BB  E8 B0B7F8FF   call  00764870                  ; 1st: [ebp-8]=[0012F350]=0151242C="5"
                                                        ; 2nd: [ebp-8]=[0012F350]=0151242C="53"
                                                        ; 3st: [ebp-8]=[0012F350]=0151242C="535"
                                                        ; 4th: [ebp-8]=[0012F350]=01512478="5353"
                                                        ; 5th: [ebp-8]=[0012F350]=01512478="53537"
                                                        ; ……
007D90C0  43            inc   ebx
007D90C1  4E            dec   esi
007D90C2  75 D9         jnz   short 007D909D            ; 循环尾
                                                        ; [ebp-8]=01512478="535373031363039525143475D24475"
                                                        ; 刚才那个循环把这字符串倒了一下
007D90C4  8D45 FC       lea   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
007D90C7  50            push  eax                       ; 00764AC0 的参数四,buffer
007D90C8  B9 04000000   mov   ecx4                    ; 参数三,要取的字符数
007D90CD  BA 01000000   mov   edx1                    ; 参数二,从第几位开始取
007D90D2  8B45 F8       mov   eax, dword ptr [ebp-8]    ; 参数一,要取子串的字符串
                                                        ; EAX=[ebp-8]=01512478="535373031363039525143475D24475"
007D90D5  E8 E6B9F8FF   call  00764AC0                  ; 取子串。EAX=0012F354, [EAX]=015124A4="5353"
007D90DA  8D45 F8       lea   eax, dword ptr [ebp-8]
007D90DD  50            push  eax
007D90DE  B9 04000000   mov   ecx4                    ; 取 4 位
007D90E3  BA 05000000   mov   edx5                    ; 从第 5 位开始取
007D90E8  8B45 F8       mov   eax, dword ptr [ebp-8]    ; 还是那串字符串
007D90EB  E8 D0B9F8FF   call  00764AC0                  ; 取子串。EAX=0012F350, [EAX]=015124B8="7303"
007D90F0  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX="5353"
007D90F3  E8 70B7F8FF   call  00764868                  ; 求字符串长度
007D90F8  83F8 04       cmp   eax4
007D90FB  7D 2F         
jge   short 007D912C            ; 长度为 4, 跳到 007D912C。下面是长度小于 4 的处理
007D90FD  8B45 FC       mov   eax, dword ptr [ebp-4]    ; 假设机器码只有一个"W",EAX="75"
007D9100  E8 63B7F8FF   call  00764868                  ; 求长
007D9105  8BD8          mov   ebxeax                  ; EBX=EAX=2
007D9107  83FB 03       cmp   ebx3
007D910A  7F 20         
jg    short 007D912C            ; 大于 3,仍然跳到 007D912C。这个判断似乎又是多此一举?
007D910C  8D4D E0       lea   ecx, dword ptr [ebp-20]   ; [ebp-20]=[0012F338]=00000000
007D910F  8BC3          mov   eaxebx                  ; 1st: EAX=EBX=00000002
                                                        ; 2nd: EAX=3
007D9111  C1E0 02       shl   eax2                    ; 1st: EAX=EAX*4=00000008
                                                        ; 2nd: EAX=EAX*4=C
007D9114  33D2          xor   edxedx
007D9116  E8 5905F9FF   call  00769674                  ; 1st: EAX="8"
                                                        ; 2nd: EAX="C"
007D911B  8B55 E0       mov   edx, dword ptr [ebp-20]   ; EDX=[ebp-20]=[0012F338]=015124CC, EDX=59390043
007D911E  8D45 FC       lea   eax, dword ptr [ebp-4]    ; 1st: [ebp-4]=015124A4="758"
                                                        ; 2nd: [ebp-4]=015124A4="758C"
007D9121  E8 4AB7F8FF   call  00764870
007D9126  43            
inc   ebx
007D9127  83FB 04       cmp   ebx4                    ; 没有补到 4 个则继续
007D912A  75 E0         jnz   short 007D910C
007D912C  8B45 
F8       mov   eax, dword ptr [ebp-8]
007D912F  E8 34B7F8FF   call  00764868
007D9134  83F8 04       
cmp   eax4
007D9137  7D 2F         
jge   short 007D9168
007D9139  8B45 
F8       mov   eax, dword ptr [ebp-8]
007D913C  E8 27B7F8FF   call  00764868
007D9141  8BD8          
mov   ebxeax
007D9143  83FB 03       cmp   ebx3
007D9146  7F 20         
jg    short 007D9168
007D9148  8D4D 
DC       lea   ecx, dword ptr [ebp-24]
007D914B  8BC3          mov   eaxebx
007D914D  C1E0 02       shl   eax2
007D9150  33D2          
xor   edxedx
007D9152  E8 1D05F9FF   call  00769674
007D9157  8B55 
DC       mov   edx, dword ptr [ebp-24]
007D915A  8D45 F8       lea   eax, dword ptr [ebp-8]    ; 这里缺位也跟上面一样补,补为 048C
                                                        ; 不管原来几位最后都是 048C, *48C, **8C, ***C, ****
007D915D  E8 0EB7F8FF   call  00764870
007D9162  43            
inc   ebx
007D9163  83FB 04       cmp   ebx4
007D9166  75 
E0         jnz   short 007D9148
007D9168  8D45 
D8       lea   eax, dword ptr [ebp-28]   ; [ebp-28]=[0012F330]=00000000
007D916B  8B55 0C       mov   edx, dword ptr [ebp+C]    ; EDX=[0012F364]=005DCB44="6J9Y-K3H7"
007D916E  E8 2DB6F8FF   call  007647A0
007D9173  8B45 
D8       mov   eax, dword ptr [ebp-28]   ; EAX=[ebp-28]=[0012F330]=01512488="6J9Y-K3H7"
007D9176  8D55 F4       lea   edx, dword ptr [ebp-C]    ; [ebp-C]=[0012F34C]=00000000
007D9179  E8 DE03F9FF   call  0076955C                  ; [ebp-C]=[0012F34C]=015124A0="6J9Y-K3H7"
007D917E  8D45 D4       lea   eax, dword ptr [ebp-2C]   ; [ebp-2C]=[0012F32C]=00000000
007D9181  50            push  eax
007D9182  B9 04000000   mov   ecx4
007D9187  
BA 01000000   mov   edx1
007D918C  8B45 
F4       mov   eax, dword ptr [ebp-C]
007D918F  E8 2CB9F8FF   call  00764AC0                  ; [ebp-2C]=[0012F32C]=015124B8="6J9Y"
007D9194  FF75 D4       push  dword ptr [ebp-2C]
007D9197  68 0C927D00   push  007D920C
007D919C  
FF75 FC       push  dword ptr [ebp-4]
007D919F  8D45 D0       lea   eax, dword ptr [ebp-30]
007D91A2  50            push  eax
007D91A3  B9 05000000   mov   ecx5
007D91A8  
BA 05000000   mov   edx5
007D91AD  8B45 
F4       mov   eax, dword ptr [ebp-C]
007D91B0  E8 0BB9F8FF   call  00764AC0
007D91B5  
FF75 D0       push  dword ptr [ebp-30]        ; [ebp-30]=[0012F328]=015124CC="-K3H7"
007D91B8  68 0C927D00   push  007D920C
007D91BD  
FF75 F8       push  dword ptr [ebp-8]
007D91C0  8D45 EC       lea   eax, dword ptr [ebp-14]
007D91C3  BA 06000000   mov   edx6
007D91C8  
E8 5BB7F8FF   call  00764928                  ; 这里就是拼接起来,懒得仔细看了
                                                        ; 最后是 6J9Y-5353-K3H7-7303
007D91CD  8B45 EC       mov   eax, dword ptr [ebp-14]
007D91D0  E8 8BB8F8FF   call  00764A60
007D91D5  8BD8          
mov   ebxeax
007D91D7  33C0          xor   eaxeax
007D91D9  5A            pop   edx
007D91DA  59            pop   ecx
007D91DB  59            pop   ecx
007D91DC  64:8910       mov   dword ptr fs:[eax], edx
007D91DF  68 F9917D00   push  007D91F9
007D91E4  8D45 
D0       lea   eax, dword ptr [ebp-30]
007D91E7  BA 0C000000   mov   edx0C
007D91EC  
E8 E3B3F8FF   call  007645D4
007D91F1  
C3            retn
007D91F2  E9 1DADF8FF   jmp   00763F14
007D91F7  
EB EB         jmp   short 007D91E4
007D91F9  8BC3          
mov   eaxebx
007D91FB  5E            pop   esi
007D91FC  5B            pop   ebx
007D91FD  8BE5          mov   espebp
007D91FF  5D            pop   ebp
007D9200  C2 0800       retn  8


哈哈,终于熬出头了,再写个 注册机(仅供学习研究,请下载后24小时内删除)



第一次完整地把算法分析出来,真兴奋~

(原发表于 CSDN:https://blog.csdn.net/cnStreamlet/article/details/2505288)

posted on 2008-06-03 00:40  溪流  阅读(59)  评论(0编辑  收藏  举报