吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 17591|回复: 40
收起左侧

[原创] 某物流通软件 算法分析 + 注册机源码(庆祝自己生日)

  [复制链接]
网络断魂 发表于 2008-11-10 19:28
【文章作者】: 网络断魂
【软件名称】: 某物流软件
【下载地址】: 国产的,不说了,不然有人找麻烦,
【加壳方式】: 无壳
【保护方式】: 机器码序列号
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: PEID,OD,
【操作平台】: XP SP3,
【作者声明】: 菜鸟学习算法,失误之处敬请诸位大侠赐教!

软件无壳,找关键点比较简单,可以通过中文提示找到,直奔主题部份
1、机器码逆推硬盘号:

006D1940  /$  55            push    ebp
006D1941  |.  8BEC          mov     ebp, esp
006D1943  |.  83C4 E8       add     esp, -18
006D1946  |.  53            push    ebx
006D1947  |.  56            push    esi
006D1948  |.  57            push    edi
006D1949  |.  33C9          xor     ecx, ecx
006D194B  |.  894D E8       mov     dword ptr [ebp-18], ecx
006D194E  |.  894D EC       mov     dword ptr [ebp-14], ecx
006D1951  |.  894D F0       mov     dword ptr [ebp-10], ecx
006D1954  |.  8955 F8       mov     dword ptr [ebp-8], edx
006D1957  |.  8945 FC       mov     dword ptr [ebp-4], eax
006D195A  |.  8B45 FC       mov     eax, dword ptr [ebp-4]           ;  //注册码(或机器码)送给EAX
006D195D  |.  E8 563AD3FF   call    004053B8
006D1962  |.  33C0          xor     eax, eax
006D1964  |.  55            push    ebp
006D1965  |.  68 2C1A6D00   push    006D1A2C
006D196A  |.  64:FF30       push    dword ptr fs:[eax]
006D196D  |.  64:8920       mov     dword ptr fs:[eax], esp
006D1970  |.  8B45 F8       mov     eax, dword ptr [ebp-8]           ;  //堆栈地址送给EAX
006D1973  |.  E8 A035D3FF   call    00404F18
006D1978  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
006D197B  |.  E8 5038D3FF   call    004051D0                         ;  //记算注册码(或机器码)长度
006D1980      B9 03000000   mov     ecx, 3                           ;  //ECX=3,作除数
006D1985  |.  99            cdq
006D1986  |.  F7F9          idiv    ecx                              ;  //注册码(或机器码)长度除以3
006D1988  |.  8BF8          mov     edi, eax                         ;  //商送给EDI
006D198A  |.  85FF          test    edi, edi
006D198C  |.  7E 7B         jle     short 006D1A09                   ;  //商小于零则跳
006D198E  |.  BE 01000000   mov     esi, 1                           ;  //ESI=1,循环记算标志位
006D1993  |>  8BC6          /mov     eax, esi
006D1995  |.  B9 03000000   |mov     ecx, 3                          ;  //ECX=3,作除数
006D199A  |.  99            |cdq
006D199B  |.  F7F9          |idiv    ecx                             ;  //记算标志除以3,得出的余数用于指向 hjy 的位置
006D199D  |.  8BCA          |mov     ecx, edx                        ;  //余数送给ECX
006D199F  |.  85C9          |test    ecx, ecx                        ;  //余数是否为零
006D19A1  |.  75 09         |jnz     short 006D19AC                  ;  //不为零则跳,
006D19A3  |.  C745 F4 03000>|mov     dword ptr [ebp-C], 3            ;  //余数若为零(即3的倍数位),直接赋值3
006D19AA  |.  EB 03         |jmp     short 006D19AF
006D19AC  |>  894D F4       |mov     dword ptr [ebp-C], ecx          ;  //余数存入堆栈
006D19AF  |>  8D45 F0       |lea     eax, dword ptr [ebp-10]         ;  //堆栈地址送给EAX
006D19B2  |.  50            |push    eax
006D19B3  |.  8BC6          |mov     eax, esi                        ;  //标志位送给EAX
006D19B5  |.  48            |dec     eax                             ;  //EAX-1
006D19B6  |.  8D1440        |lea     edx, dword ptr [eax+eax*2]      ;  //EDX=3*EAX
006D19B9  |.  42            |inc     edx                             ;  //EDX+1,从第  3*EAX+1 位开始取
006D19BA  |.  B9 03000000   |mov     ecx, 3                          ;  //ECX=3,取3位,
006D19BF  |.  8B45 FC       |mov     eax, dword ptr [ebp-4]          ;  //注册码(或机器码)送给EAX
006D19C2  |.  E8 613AD3FF   |call    00405428                        ;  //取3位,从第 3*EAX+1 位开始取,
006D19C7  |.  8D45 EC       |lea     eax, dword ptr [ebp-14]         ;  //堆栈地址送给EAX
006D19CA  |.  8B4D F0       |mov     ecx, dword ptr [ebp-10]         ;  //上面取到的三位字符串送给ECX
006D19CD  |.  BA 441A6D00   |mov     edx, 006D1A44                   ;  // $ 字符送给EDX,
006D19D2  |.  E8 4538D3FF   |call    0040521C                        ;  //连接字符串, $ 字符放前面
006D19D7  |.  8B45 EC       |mov     eax, dword ptr [ebp-14]         ;  //连接后的字符串送给EAX
006D19DA  |.  E8 B18ED3FF   |call    0040A890                        ;  //转换为数值
006D19DF  |.  8BD8          |mov     ebx, eax                        ;  //数值送给EBX
006D19E1  |.  B8 501A6D00   |mov     eax, 006D1A50                   ;  //固定字符串  hjy  送给EAX
006D19E6  |.  8B55 F4       |mov     edx, dword ptr [ebp-C]          ;  //余数送给EDX,取 hjy 中的第几位,
006D19E9  |.  325C10 FF     |xor     bl, byte ptr [eax+edx-1]        ;  //转换后数值的低位跟 hjy 中第N位的ASCII值异或
006D19ED  |.  8D45 E8       |lea     eax, dword ptr [ebp-18]         ;  //堆栈地址送给EAX,
006D19F0  |.  8BD3          |mov     edx, ebx                        ;  //异或后的值送给EDX
006D19F2  |.  E8 0137D3FF   |call    004050F8                        ;  //异或值的低位转换成字符
006D19F7  |.  8B55 E8       |mov     edx, dword ptr [ebp-18]         ;  //转换后字符的地址送给EDX
006D19FA  |.  8B45 F8       |mov     eax, dword ptr [ebp-8]          ;  //堆栈地址送给EAX
006D19FD  |.  E8 D637D3FF   |call    004051D8                        ;  //转存
006D1A02  |.  8B45 F8       |mov     eax, dword ptr [ebp-8]          ;  //地址送给EAX
006D1A05  |.  46            |inc     esi                             ;  //标志位+1,计算下一位,
006D1A06  |.  4F            |dec     edi                             ;  //长度除以3的值循环减1,是否计算完,
006D1A07  |.^ 75 8A         \jnz     short 006D1993                  ;  //未完继续
006D1A09  |>  33C0          xor     eax, eax                         ;  //EAX清零
006D1A0B  |.  5A            pop     edx
006D1A0C  |.  59            pop     ecx
006D1A0D  |.  59            pop     ecx
006D1A0E  |.  64:8910       mov     dword ptr fs:[eax], edx
006D1A11  |.  68 331A6D00   push    006D1A33
006D1A16  |>  8D45 E8       lea     eax, dword ptr [ebp-18]          ;  //堆栈地址送给EAX
006D1A19  |.  BA 03000000   mov     edx, 3                           ;  //EDX=3
006D1A1E  |.  E8 1935D3FF   call    00404F3C
006D1A23  |.  8D45 FC       lea     eax, dword ptr [ebp-4]
006D1A26  |.  E8 ED34D3FF   call    00404F18
006D1A2B  \.  C3            retn
006D1A2C   .^ E9 0F2ED3FF   jmp     00404840
006D1A31   .^ EB E3         jmp     short 006D1A16
006D1A33   .  5F            pop     edi
006D1A34   .  5E            pop     esi
006D1A35   .  5B            pop     ebx
006D1A36   .  8BE5          mov     esp, ebp
006D1A38   .  5D            pop     ebp
006D1A39   .  C3            retn

2、硬盘号变换出一串八位字符串:(日期变换采用相同算法)

007252B8  |.  8B85 BCFDFFFF mov     eax, dword ptr [ebp-244]         ;  //硬盘号送给EAX,
007252BE  |.  E8 0DFFCDFF   call    004051D0                         ;  //计算长度
007252C3  |.  83F8 08       cmp     eax, 8                           ;  //与此8比较
007252C6  |.  7D 2F         jge     short 007252F7                   ;  //大于等于8则跳
007252C8  |.  8D85 B4FDFFFF lea     eax, dword ptr [ebp-24C]
007252CE  |.  E8 E5C4FAFF   call    006D17B8
007252D3  |.  8B85 B4FDFFFF mov     eax, dword ptr [ebp-24C]
007252D9  |.  8D95 B8FDFFFF lea     edx, dword ptr [ebp-248]
007252DF  |.  E8 0450CEFF   call    0040A2E8
007252E4  |.  8B85 B8FDFFFF mov     eax, dword ptr [ebp-248]
007252EA  |.  8D4D B0       lea     ecx, dword ptr [ebp-50]
007252ED  |.  BA 08000000   mov     edx, 8
007252F2  |.  E8 3183D2FF   call    0044D628
007252F7  |>  8D85 70FFFFFF lea     eax, dword ptr [ebp-90]
007252FD  |.  E8 16FCCDFF   call    00404F18
00725302  |.  8D85 68FFFFFF lea     eax, dword ptr [ebp-98]
00725308  |.  E8 0BFCCDFF   call    00404F18
0072530D  |.  8D55 90       lea     edx, dword ptr [ebp-70]
00725310  |.  8B45 B0       mov     eax, dword ptr [ebp-50]
00725313  |.  E8 D04FCEFF   call    0040A2E8
00725318  |.  8B45 90       mov     eax, dword ptr [ebp-70]
0072531B  |.  E8 B0FECDFF   call    004051D0                         ;  //计算长度
00725320  |.  8945 88       mov     dword ptr [ebp-78], eax          ;  //存入,
00725323  |.  B8 08000000   mov     eax, 8                           ;  //EAX=8
00725328  |.  85C0          test    eax, eax
0072532A  |.  0F8E 1B010000 jle     0072544B                         ;  //小于等于0则跳
00725330  |.  8985 3CFFFFFF mov     dword ptr [ebp-C4], eax
00725336  |.  BF 01000000   mov     edi, 1                           ;  //循环开始标志位 EDI=1
0072533B  |>  8D85 B0FDFFFF /lea     eax, dword ptr [ebp-250]
00725341  |.  50            |push    eax
00725342  |.  B9 01000000   |mov     ecx, 1                          ;  //ECX=1,取一位
00725347  |.  8BD7          |mov     edx, edi                        ;  //EDX=EDI,标志位(从第N位开始取)
00725349  |.  8B45 90       |mov     eax, dword ptr [ebp-70]         ;  //硬盘号送给EAX
0072534C  |.  E8 D700CEFF   |call    00405428                        ;  //取字符串,
00725351  |.  8B95 B0FDFFFF |mov     edx, dword ptr [ebp-250]        ;  //取到的字符串的地址送给EDX
00725357  |.  8D45 98       |lea     eax, dword ptr [ebp-68]         ;  //也是存储地址,
0072535A  |.  E8 7904CEFF   |call    004057D8                        ;  //取地址,
0072535F  |.  8B45 98       |mov     eax, dword ptr [ebp-68]         ;  //字符串地址送给EAX
00725362  |.  66:8B00       |mov     ax, word ptr [eax]              ;  //取到的硬盘号字符ASCII值送给AX
00725365  |.  0FB7D8        |movzx   ebx, ax                         ;  //AX送给EBX
00725368  |.  83FB 30       |cmp     ebx, 30                         ;  //与30(0)比较,
0072536B  |.  7C 13         |jl      short 00725380                  ;  //小于则跳
0072536D  |.  83FB 39       |cmp     ebx, 39                         ;  //与39(9)比较,
00725370  |.  7F 0E         |jg      short 00725380                  ;  //大于则跳,(这两个比较用来较验字符是否为数字)
00725372  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725378  |.  8D53 31       |lea     edx, dword ptr [ebx+31]         ;  //EDX=EBX+31,若为数字则ASCII值+31
0072537B  |.  E8 78FDCDFF   |call    004050F8                        ;  //相加后的值存储,
00725380  |>  83FB 41       |cmp     ebx, 41                         ;  //与41(A)比较,
00725383  |.  7C 15         |jl      short 0072539A                  ;  //小于则跳
00725385  |.  83FB 4A       |cmp     ebx, 4A                         ;  //与4A(J)比较,
00725388  |.  7F 10         |jg      short 0072539A                  ;  //大于则跳,这两个比较用于较验字符是否在A-J之间
0072538A  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725390  |.  8BD3          |mov     edx, ebx
00725392  |.  83EA 11       |sub     edx, 11                         ;  //若在A-J之间,则ASCII值-11后再存储(即转换为数字)
00725395  |.  E8 5EFDCDFF   |call    004050F8                        ;  //存储
0072539A  |>  83FB 4B       |cmp     ebx, 4B                         ;  //与4B(K 大写)比较,
0072539D  |.  7C 13         |jl      short 007253B2                  ;  //小于则跳
0072539F  |.  83FB 52       |cmp     ebx, 52                         ;  //与52(R)比较,
007253A2  |.  7F 0E         |jg      short 007253B2                  ;  //大于则跳这两个比较用于较验字符是否在K-R之间
007253A4  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007253AA  |.  8D53 28       |lea     edx, dword ptr [ebx+28]         ;  //EDX=EBX+28,若字符在K-R之间,则ASCII值+28后再存储
007253AD  |.  E8 46FDCDFF   |call    004050F8
007253B2  |>  83FB 53       |cmp     ebx, 53                         ;  //与53(S 大写)比较,
007253B5  |.  7C 13         |jl      short 007253CA                  ;  //小于则跳
007253B7  |.  83FB 5A       |cmp     ebx, 5A                         ;  //与5A(Z大写)比较,
007253BA  |.  7F 0E         |jg      short 007253CA             ;  //大于则跳这两个比较用于较验字符是否在S-Z(大写)之间
007253BC  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007253C2  |.  8D53 18       |lea     edx, dword ptr [ebx+18]         ;  //EDX=EBX+18,若字符在S-Z之间,则ASCII值+18后再存储
007253C5  |.  E8 2EFDCDFF   |call    004050F8
007253CA  |>  83FB 61       |cmp     ebx, 61                         ;  //与61(a)比较,
007253CD  |.  7C 15         |jl      short 007253E4                  ;  //小于则跳,
007253CF  |.  83FB 68       |cmp     ebx, 68                         ;  //与68(h)比较
007253D2  |.  7F 10         |jg      short 007253E4                  ;  //大于则跳
007253D4  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007253DA  |.  8BD3          |mov     edx, ebx
007253DC  |.  83EA 16       |sub     edx, 16                         ;  //EDX-16,若字符在a-h之间,则ASCII值-16再存储
007253DF  |.  E8 14FDCDFF   |call    004050F8
007253E4  |>  83FB 69       |cmp     ebx, 69                         ;  //与69(i)比较
007253E7  |.  7C 15         |jl      short 007253FE                  ;  //小于则跳
007253E9  |.  83FB 70       |cmp     ebx, 70                         ;  //与70(p)比较
007253EC  |.  7F 10         |jg      short 007253FE                  ;  //大于则跳
007253EE  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007253F4  |.  8BD3          |mov     edx, ebx
007253F6  |.  83EA 16       |sub     edx, 16                         ;  //EDX-16,若字符在i-p之间,则ASCII值-16再存储
007253F9  |.  E8 FAFCCDFF   |call    004050F8
007253FE  |>  83FB 71       |cmp     ebx, 71                         ;  //与71(q)比较
00725401  |.  7C 15         |jl      short 00725418                  ;  //小于则跳
00725403  |.  83FB 7A       |cmp     ebx, 7A                         ;  //与7A(z)比较,
00725406  |.  7F 10         |jg      short 00725418                  ;  //大于则跳,
00725408  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
0072540E  |.  8BD3          |mov     edx, ebx
00725410  |.  83EA 30       |sub     edx, 30                         ;  //EDX-30,若字符在q-z之间,则ASCII值-30再存储
00725413  |.  E8 E0FCCDFF   |call    004050F8
00725418  |>  83FB 2D       |cmp     ebx, 2D                         ;  //与2D(-)比较,
0072541B  |.  75 10         |jnz     short 0072542D                  ;  //不等则跳,
0072541D  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725423  |.  BA 0C637200   |mov     edx, 0072630C                   ;  //若字符为 - ,则用 x 代替后存储,
00725428  |.  E8 83FBCDFF   |call    00404FB0
0072542D  |>  8D85 68FFFFFF |lea     eax, dword ptr [ebp-98]
00725433  |.  8B95 70FFFFFF |mov     edx, dword ptr [ebp-90]
00725439  |.  E8 9AFDCDFF   |call    004051D8                        ;  //转存
0072543E  |.  47            |inc     edi                             ;  //标志位+1,计算下一位,
0072543F  |.  FF8D 3CFFFFFF |dec     dword ptr [ebp-C4]              ;  //长度-1,较验是否计算完
00725445  |.^ 0F85 F0FEFFFF \jnz     0072533B                        ;  //未完继续
0072544B  |>  68 18637200   push    00726318                         ;  select * from khzc where xlh='
00725450  |.  8D95 ACFDFFFF lea     edx, dword ptr [ebp-254]
00725456  |.  8B45 90       mov     eax, dword ptr [ebp-70]          ;  //硬盘号送给EAX
00725459  |.  E8 1AC4FAFF   call    006D1878                         ;  //生成机器码,跟进,这是注册码逆推的反运算
0072545E  |.  FFB5 ACFDFFFF push    dword ptr [ebp-254]              ;  //生成的机器码入栈

3、变换出的字符串作为偶数位,奇数位上填充日期变换出来的字符:


007255EC  |> \8D85 68FFFFFF lea     eax, dword ptr [ebp-98]          ;  //硬盘号变换出来字符串的地址送给EAX
007255F2  |.  E8 21F9CDFF   call    00404F18
007255F7  |.  8D85 64FFFFFF lea     eax, dword ptr [ebp-9C]
007255FD  |.  E8 16F9CDFF   call    00404F18
00725602  |.  BF 01000000   mov     edi, 1
00725607  |>  8BC7          /mov     eax, edi                        ;  //循环标志位送给EAX
00725609  |.  25 01000080   |and     eax, 80000001                   ;  //奇偶较验
0072560E  |.  79 05         |jns     short 00725615
00725610  |.  48            |dec     eax
00725611  |.  83C8 FE       |or      eax, FFFFFFFE
00725614  |.  40            |inc     eax
00725615  |>  85C0          |test    eax, eax
00725617  |.  0F85 09010000 |jnz     00725726                        ;  //奇数位则跳,偶数位不跳
0072561D  |.  8D85 88FDFFFF |lea     eax, dword ptr [ebp-278]
00725623  |.  50            |push    eax
00725624  |.  B9 01000000   |mov     ecx, 1                          ;  //ECX=1,取1位,
00725629  |.  8BD7          |mov     edx, edi                        ;  //EDX=EDI,取第N位,N为循环标志位
0072562B  |.  8B85 60FFFFFF |mov     eax, dword ptr [ebp-A0]         ;  //注册码逆推字符串送给EAX
00725631  |.  E8 F2FDCDFF   |call    00405428                        ;  //取字符串
00725636  |.  8B95 88FDFFFF |mov     edx, dword ptr [ebp-278]        ;  //地址送给EDX
0072563C  |.  8D45 98       |lea     eax, dword ptr [ebp-68]
0072563F  |.  E8 9401CEFF   |call    004057D8
00725644  |.  8B45 98       |mov     eax, dword ptr [ebp-68]
00725647  |.  66:8B00       |mov     ax, word ptr [eax]              ;  //字符ASCII值送给AX,
0072564A  |.  0FB7D8        |movzx   ebx, ax                         ;  //AX送给EBX
0072564D  |.  83FB 61       |cmp     ebx, 61                         ;  //与61(a)比较,
00725650  |.  7C 15         |jl      short 00725667                  ;  //小于则跳
00725652  |.  83FB 6A       |cmp     ebx, 6A                         ;  //与6A(j)比较,
00725655  |.  7F 10         |jg      short 00725667                  ;  //大于则跳
00725657  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
0072565D  |.  8BD3          |mov     edx, ebx
0072565F  |.  83EA 31       |sub     edx, 31                         ;  //EDX-31,若字符在a-j之间,则ASCII值-31后存储
00725662  |.  E8 91FACDFF   |call    004050F8
00725667  |>  83FB 30       |cmp     ebx, 30                         ;  //与30(0)比较,
0072566A  |.  7C 13         |jl      short 0072567F                  ;  //小于则跳
0072566C  |.  83FB 39       |cmp     ebx, 39                         ;  //与39(9)比较,
0072566F  |.  7F 0E         |jg      short 0072567F                  ;  //大于则跳
00725671  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725677  |.  8D53 11       |lea     edx, dword ptr [ebx+11]         ;  //EDX=EBX+11,若字符在0-9之间,则ASCII值+11后存储
0072567A  |.  E8 79FACDFF   |call    004050F8
0072567F  |>  83FB 6B       |cmp     ebx, 6B                         ;  //与6B(k)比较,
00725682  |.  7C 15         |jl      short 00725699                  ;  //小于则跳,
00725684  |.  83FB 72       |cmp     ebx, 72                         ;  //与72(r)比较,
00725687  |.  7F 10         |jg      short 00725699                  ;  //大于则跳,
00725689  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
0072568F  |.  8BD3          |mov     edx, ebx
00725691  |.  83EA 18       |sub     edx, 18                         ;  //EDX-18,若字符在k-r之间,则ASCII值-18后存储
00725694  |.  E8 5FFACDFF   |call    004050F8
00725699  |>  83FB 73       |cmp     ebx, 73                         ;  //与73(s)比较,
0072569C  |.  7C 15         |jl      short 007256B3                  ;  //小与则跳
0072569E  |.  83FB 7A       |cmp     ebx, 7A                         ;  //与7A(z)比较,
007256A1  |.  7F 10         |jg      short 007256B3                  ;  //大于则跳
007256A3  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007256A9  |.  8BD3          |mov     edx, ebx
007256AB  |.  83EA 28       |sub     edx, 28                         ;  //EDX-28,若字符在s-z之间,则ASCII值-28后存储
007256AE  |.  E8 45FACDFF   |call    004050F8
007256B3  |>  83FB 44       |cmp     ebx, 44                         ;  //与44(D)比较,
007256B6  |.  7C 13         |jl      short 007256CB                  ;  //小于则跳
007256B8  |.  83FB 54       |cmp     ebx, 54                         ;  //与54(T)比较,
007256BB  |.  7F 0E         |jg      short 007256CB                  ;  //大于则跳
007256BD  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007256C3  |.  8D53 16       |lea     edx, dword ptr [ebx+16]
007256C6  |.  E8 2DFACDFF   |call    004050F8
007256CB  |>  83FB 53       |cmp     ebx, 53                         ;  //S(大写)
007256CE  |.  7C 13         |jl      short 007256E3
007256D0  |.  83FB 5A       |cmp     ebx, 5A                         ;  //Z(大写)
007256D3  |.  7F 0E         |jg      short 007256E3
007256D5  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007256DB  |.  8D53 16       |lea     edx, dword ptr [ebx+16]         ;  //EDX=EBX+16,若字符在S-Z之间,则ASCII值+16后存储
007256DE  |.  E8 15FACDFF   |call    004050F8
007256E3  |>  83FB 41       |cmp     ebx, 41                         ;  //A
007256E6  |.  7C 13         |jl      short 007256FB
007256E8  |.  83FB 4A       |cmp     ebx, 4A                         ;  //J
007256EB  |.  7F 0E         |jg      short 007256FB
007256ED  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
007256F3  |.  8D53 30       |lea     edx, dword ptr [ebx+30]         ;  //EDX=EBX+30,若字符在A-J之间,则ASCII值+30后存储
007256F6  |.  E8 FDF9CDFF   |call    004050F8
007256FB  |>  83FB 58       |cmp     ebx, 58                         ;  //X(大写)
007256FE  |.  75 10         |jnz     short 00725710                  ;  //不等则跳
00725700  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725706  |.  BA A4637200   |mov     edx, 007263A4                   ;  //若字符为 - ,则用X代替,
0072570B  |.  E8 A0F8CDFF   |call    00404FB0
00725710  |>  8D85 68FFFFFF |lea     eax, dword ptr [ebp-98]
00725716  |.  8B95 70FFFFFF |mov     edx, dword ptr [ebp-90]
0072571C  |.  E8 B7FACDFF   |call    004051D8
00725721  |.  E9 9F000000   |jmp     007257C5
00725726  |>  8D85 84FDFFFF |lea     eax, dword ptr [ebp-27C]
0072572C  |.  50            |push    eax
0072572D  |.  B9 01000000   |mov     ecx, 1                          ;  //ECX=1,取1位,
00725732  |.  8BD7          |mov     edx, edi                        ;  //EDX=EDI,EDI为标志位,
00725734  |.  8B85 60FFFFFF |mov     eax, dword ptr [ebp-A0]         ;  //注册码逆推后的值送给EAX
0072573A  |.  E8 E9FCCDFF   |call    00405428                        ;  //取字符串,
0072573F  |.  8B95 84FDFFFF |mov     edx, dword ptr [ebp-27C]        ;  (initial cpu selection)
00725745  |.  8D45 94       |lea     eax, dword ptr [ebp-6C]
00725748  |.  E8 8B00CEFF   |call    004057D8                        ;  //取ASCII值
0072574D  |.  8B45 94       |mov     eax, dword ptr [ebp-6C]
00725750  |.  66:8B00       |mov     ax, word ptr [eax]              ;  //ASCII值送给AX
00725753  |.  0FB7D8        |movzx   ebx, ax                         ;  //AX送给EBX
00725756  |.  83FB 58       |cmp     ebx, 58                         ;  //与X(58)比较,
00725759  |.  75 10         |jnz     short 0072576B                  ;  //不等则跳
0072575B  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]
00725761  |.  BA A4637200   |mov     edx, 007263A4                   ;  //第一位若是 - 号,刚用x替换
00725766  |.  E8 45F8CDFF   |call    00404FB0
0072576B  |>  83FB 58       |cmp     ebx, 58                         ;  //与X(58)比较,
0072576E  |.  74 44         |je      short 007257B4                  ;  //是则跳
00725770  |.  8BC3          |mov     eax, ebx
00725772  |.  83E8 31       |sub     eax, 31                         ;  //ASCII值减31(1)
00725775  |.  83F8 30       |cmp     eax, 30                         ;  //与30(0)比较
00725778  |.  7C 1C         |jl      short 00725796                  ;  //小于则跳,跳往注册码不正确
0072577A  |.  8BC3          |mov     eax, ebx
0072577C  |.  83E8 31       |sub     eax, 31
0072577F  |.  83F8 39       |cmp     eax, 39                         ;  //与39(9)比较,
00725782      7F 12         jg      short 00725796                   ;  //大于则跳,跳往注册码不正确
00725784  |.  8D85 70FFFFFF |lea     eax, dword ptr [ebp-90]       ; 
               //这两个比较,说明注册码逆推后字符串的奇数位必须为a-j之间(这里是日期)
0072578A  |.  8BD3          |mov     edx, ebx
0072578C  |.  83EA 31       |sub     edx, 31
0072578F  |.  E8 64F9CDFF   |call    004050F8                        ;  //转存
00725794  |.  EB 1E         |jmp     short 007257B4
00725796  |>  B8 B0637200   |mov     eax, 007263B0                   ;  注册码不正确!!
0072579B  |.  E8 686FD2FF   |call    0044C708
007257A0  |.  A1 2CA07600   |mov     eax, dword ptr [76A02C]
007257A5  |.  8B00          |mov     eax, dword ptr [eax]
007257A7  |.  8B10          |mov     edx, dword ptr [eax]
007257A9  |.  FF92 E8000000 |call    dword ptr [edx+E8]
007257AF  |.  E9 F9000000   |jmp     007258AD
007257B4  |>  8D85 64FFFFFF |lea     eax, dword ptr [ebp-9C]
007257BA  |.  8B95 70FFFFFF |mov     edx, dword ptr [ebp-90]
007257C0  |.  E8 13FACDFF   |call    004051D8
007257C5  |>  47            |inc     edi                             ;  //标志位+1
007257C6  |.  83FF 11       |cmp     edi, 11                         ;  //与17比较,较验是否计算完成
007257C9  |.^ 0F85 38FEFFFF \jnz     00725607
007257CF  |.  8D85 64FFFFFF lea     eax, dword ptr [ebp-9C]
007257D5  |.  8B8D 64FFFFFF mov     ecx, dword ptr [ebp-9C]
007257DB  |.  BA CC637200   mov     edx, 007263CC                    ;  //20
007257E0  |.  E8 37FACDFF   call    0040521C                            //连接字符串
007257E5  |.  8B85 68FFFFFF mov     eax, dword ptr [ebp-98]
007257EB  |.  8B55 B0       mov     edx, dword ptr [ebp-50]
007257EE  |.  E8 21FBCDFF   call    00405314                            //转换为日期,若连接后的字符串不是有效的日期则报错!
007257F3  |.  74 0F         je      short 00725804
007257F5  |.  B8 D8637200   mov     eax, 007263D8                    ;  注册码不正确,无法使用!
007257FA  |.  E8 096FD2FF   call    0044C708
007257FF  |.  E9 A9000000   jmp     007258AD
00725804  |>  8B85 64FFFFFF mov     eax, dword ptr [ebp-9C]
0072580A  |.  E8 5997CEFF   call    0040EF68
0072580F  |.  DD9D 7CFDFFFF fstp    qword ptr [ebp-284]
00725815  |.  9B            wait
00725816  |.  E8 2181CEFF   call    0040D93C
0072581B  |.  DC9D 7CFDFFFF fcomp   qword ptr [ebp-284]
00725821  |.  DFE0          fstsw   ax
00725823  |.  9E            sahf
00725824  |.  76 78         jbe     short 0072589E
00725826  |.  B8 68637200   mov     eax, 00726368                    ;  试用期限已过,软件无法正常使用,请申请正版注册码!

4、填充奇数位后的字符串计算出注册码:


006D1878  /$  55            push    ebp                              ;  //硬盘号生成机器码的关键算法
006D1879  |.  8BEC          mov     ebp, esp
006D187B  |.  83C4 F4       add     esp, -0C
006D187E  |.  53            push    ebx
006D187F  |.  56            push    esi
006D1880  |.  57            push    edi
006D1881  |.  33C9          xor     ecx, ecx                         ;  //ECX清零
006D1883  |.  894D F4       mov     dword ptr [ebp-C], ecx
006D1886  |.  8BFA          mov     edi, edx
006D1888  |.  8945 FC       mov     dword ptr [ebp-4], eax           ;  //硬盘号送入堆栈中
006D188B  |.  8B45 FC       mov     eax, dword ptr [ebp-4]           ;  //反送给EAX
006D188E  |.  E8 253BD3FF   call    004053B8
006D1893  |.  33C0          xor     eax, eax                         ;  //EAX清零
006D1895  |.  55            push    ebp
006D1896  |.  68 25196D00   push    006D1925
006D189B  |.  64:FF30       push    dword ptr fs:[eax]
006D189E  |.  64:8920       mov     dword ptr fs:[eax], esp
006D18A1  |.  8BC7          mov     eax, edi
006D18A3  |.  E8 7036D3FF   call    00404F18
006D18A8  |.  8B45 FC       mov     eax, dword ptr [ebp-4]           ;  //硬盘号送给EAX
006D18AB  |.  E8 2039D3FF   call    004051D0                         ;  //取长度
006D18B0  |.  8BF0          mov     esi, eax                         ;  //送给ESI
006D18B2  |.  85F6          test    esi, esi                         ;  //长度是否为零
006D18B4  |.  7E 51         jle     short 006D1907                   ;  //小于零则跳
006D18B6  |.  BB 01000000   mov     ebx, 1                           ;  //EBX=1,循环计算开始的标志位
006D18BB  |>  8BC3          /mov     eax, ebx                        ;  //EAX=EBX,(第N位)
006D18BD  |.  B9 03000000   |mov     ecx, 3                          ;  //ECX=3,作除数
006D18C2  |.  99            |cdq
006D18C3  |.  F7F9          |idiv    ecx                             ;  //除以3
006D18C5  |.  8BCA          |mov     ecx, edx                        ;  //余数送给ECX
006D18C7  |.  85C9          |test    ecx, ecx                        ;  //余数是否为零,
006D18C9  |.  75 07         |jnz     short 006D18D2                  ;  //不为零则跳
006D18CB  |.  B8 03000000   |mov     eax, 3                          ;  //为零(3的倍数位),则直接赋值3
006D18D0  |.  EB 02         |jmp     short 006D18D4
006D18D2  |>  8BC1          |mov     eax, ecx                        ;  //余数送给EAX
006D18D4  |>  BA 3C196D00   |mov     edx, 006D193C                   ;  //固定字符串 hjy 送给EDX
006D18D9  |.  8A4402 FF     |mov     al, byte ptr [edx+eax-1];//hjy字符串中第余数位(若余数为零则指向第3位)的ASCII值送给AL
006D18DD  |.  8B55 FC       |mov     edx, dword ptr [ebp-4]          ;  //硬盘号送给EDX
006D18E0  |.  32441A FF     |xor     al, byte ptr [edx+ebx-1]        ;  //硬盘号的第N位与hjy中的第余数位ASCII值异或
006D18E4  |.  8845 FB       |mov     byte ptr [ebp-5], al            ;  //异或值存入堆栈
006D18E7  |.  8D4D F4       |lea     ecx, dword ptr [ebp-C]
006D18EA  |.  33C0          |xor     eax, eax                        ;  //EAX清零
006D18EC  |.  8A45 FB       |mov     al, byte ptr [ebp-5]            ;  //异或值送给AL
006D18EF  |.  BA 03000000   |mov     edx, 3                          ;  //EDX=3
006D18F4  |.  E8 5B8FD3FF   |call    0040A854                        ;  //数值转换为字符串,不足3位则前而添0,
006D18F9  |.  8B55 F4       |mov     edx, dword ptr [ebp-C]          ;  //转换后的字符串送给EDX
006D18FC  |.  8BC7          |mov     eax, edi                        ;  //送堆栈地址
006D18FE  |.  E8 D538D3FF   |call    004051D8                        ;  //转存
006D1903  |.  43            |inc     ebx                             ;  //计算下一位
006D1904  |.  4E            |dec     esi                             ;  //长度-1,用于较验是否计算完成
006D1905  |.^ 75 B4         \jnz     short 006D18BB                  ;  //未完继续
006D1907  |>  33C0          xor     eax, eax
006D1909  |.  5A            pop     edx
006D190A  |.  59            pop     ecx
006D190B  |.  59            pop     ecx
006D190C  |.  64:8910       mov     dword ptr fs:[eax], edx
006D190F  |.  68 2C196D00   push    006D192C
006D1914  |>  8D45 F4       lea     eax, dword ptr [ebp-C]
006D1917  |.  E8 FC35D3FF   call    00404F18
006D191C  |.  8D45 FC       lea     eax, dword ptr [ebp-4]
006D191F  |.  E8 F435D3FF   call    00404F18
006D1924  \.  C3            retn
006D1925   .^ E9 162FD3FF   jmp     00404840
006D192A   .^ EB E8         jmp     short 006D1914
006D192C   .  5F            pop     edi
006D192D   .  5E            pop     esi
006D192E   .  5B            pop     ebx
006D192F   .  8BE5          mov     esp, ebp
006D1931   .  5D            pop     ebp
006D1932   .  C3            retn


6、以本机为例手工推算:


机器码05D03A03205805D02D025022  逆推出硬盘号  5PK07TMH,硬盘号转换后得到字符串fxsahlu7,日期10-09-09转换后得到字符串baXajXaj

填充奇偶字符后 bfaxXsaajhXlauj7,跟hjy异或者运算后计算出注册码:00A00C01801003200A00900B01300003201500901F01305F

  1   5   0   P   -   K   0   0   9   7   -   T   0   M   9   H           (20)10-09-09   5PK07TMH  
  31  35  30  50  2D  4B  30  30  39  37  2D  54  30  4D  39  48

+31 +31 +31 +28 =58 +28 +31 +31 +31 +31 =58 +18 +31 +28 +31 -11  

  62  66  61  78  58  73  61  61  6A  68  58  6C  61  75  6A  37
  b   f   a   x   X   s   a   a   j   h   X   l   a   u   j   7


(20)10-09-09 == (20)baXajXaj         5PK07TMH ==fxsahlu7
  b   f   a   x   X   s   a   a   j   h   X   l   a   u   j   7          
  62  66  61  78  58  73  61  61  6A  68  58  6c  61  75  6A  37

XOR

  h   j   y   h   j   y   h   j   y   h   j   y   h   j   y   h
  68  6A  79  68  6A  79  68  6A  79  68  6A  79  68  6A  79  68

  00A 00C 018 010 032 00A 009 00B 013 000 032 015 009 01F 013 05F

  00A00C01801003200A00900B01300003201500901F01305F

7、注册机源码(写代码确实很菜,不要见笑):


//机器码转换成硬盘号
CString JqmToYph(CString jqm)
{
        CString yph;
        CString str_tmp;
        CString str_hjy = "hjy";
        int jqmlen;
        int str_num;
        jqmlen = jqm.GetLength();

        for (int i = 0;i < jqmlen/3;i++)
        {
                str_tmp = jqm.Mid(3*i,3);
                str_num = strtol(str_tmp,NULL,16);
                str_num = str_num ^ (int)str_hjy[i%3];
                yph += (char)str_num;
        }
        return yph;
}

//硬盘号或日期字符串生成注册码

CString YphRqToZcm(CString YphRq)
{
        int str_len = 0;
        CString hjy = "hjy";
        CString zcm,zcm_tmp;
        str_len = YphRq.GetLength();
        for (int i = 0;i<str_len;i++)
        {
                int str_int = (int)YphRq;
                if ( 0x30 <= str_int && str_int <= 0x39 )
                {
                        str_int = str_int + 0x31;
                }
                else if ( 0x41 <= str_int && str_int <= 0x4A )
                {
                        str_int = str_int - 0x11;
                }
                else if ( 0x4B <= str_int && str_int <= 0x52 )
                {
                        str_int = str_int + 0x28;
                }
                else if ( 0x53 <= str_int && str_int <= 0x5A )
                {
                        str_int = str_int + 0x18;
                }
                else if ( 0x61 <= str_int && str_int <= 0x70 )
                {
                        str_int = str_int - 0x16;
                }
                else if ( 0x71 <= str_int && str_int <= 0x7A )
                {
                        str_int = str_int - 0x30;
                }
                else if ( str_int == 0x2D )
                {
                        str_int = 0x58;
                }
                zcm_tmp += (char)str_int;
                str_int = str_int ^ (int)hjy[i%3];
                zcm_tmp.Format("%2x",str_int);
                zcm_tmp.Remove(' ');
                if (zcm_tmp.GetLength() == 1)
                {
                        zcm_tmp = "00" + zcm_tmp;
                }
                else if (zcm_tmp.GetLength() == 2)
                {
                        zcm_tmp = "0" + zcm_tmp;
                }
                zcm += zcm_tmp;
                zcm.MakeUpper();
        }
        return zcm;
}



void C物流通注册机Dlg::OnBnClickedOk()
{
        CString jqm,rq,rqy,rqm,rqd,zcm;//机器码,日期,年,月,日,注册码
        CString yph;//硬盘号
        CString YphRq;//硬盘号日期混合字符串
        int jqm_len = 0,rq_len = 0,rqy_len = 0,rqm_len = 0,rqd_len = 0;//机器码、日期、年、月、日的长度
        GetDlgItemText(IDC_EDIT1,jqm);//取机器码
        GetDlgItemText(IDC_EDIT2,rqy);//取年份
        GetDlgItemText(IDC_EDIT3,rqm);//取月份
        GetDlgItemText(IDC_EDIT4,rqd);//取日
        jqm_len = jqm.GetLength();//取机器码长度
        rqy_len = rqy.GetLength();//取年份长度
        rqm_len = rqm.GetLength();//取月份长度
        rqd_len = rqd.GetLength();//取日期长度


        if (jqm_len <= 0)
        {
                MessageBox("请输入机器码!");
                return;
        }
        for (int i = 0;i < jqm_len;i++)
        {
                if ( !(('0'<= jqm && jqm <= '9') || ('A' <= jqm && jqm <= 'F') || ('a' <= jqm && jqm <= 'f')) )
                {
                        MessageBox("机器码应该为十六进制字符,‘0-9’,‘a-f’,‘A-F’!");
                        return;
                }
        }



        if (rqy_len > 2 || rqy_len <= 0)
        {
                MessageBox("请输入00-99之间的两位数年份!");
                return;
        }
        if (rqy_len == 1)
        {
                rqy = "0" + rqy;
        }




        if (rqm_len > 2 || rqm_len <= 0)
        {
                MessageBox("请输入00-12之间的两位数月份!");
                return;
        }
        if (rqm_len == 1)
        {
                rqm = "0"+rqm;
        }
        int rqm_int = atoi(rqm);
        if (rqm_int > 12)
        {
                MessageBox("月份数没有大于12的!");
                return;
        }
        




        if (rqd_len > 2 || rqd_len<= 0)
        {
                MessageBox("请输入00-31之间的两位数日期!");
                return;
        }
        if (rqd_len == 1)
        {
                rqd = "0"+rqd;
        }
        int rqd_int = atoi(rqd);
        if (rqm_int == 2 && rqd_int > 28)
        {
                MessageBox("本月份最大日期为28!");
                return;
        }
        if (((rqm_int == 4) || (rqm_int == 6) || (rqm_int == 9) || (rqm_int == 11)) && rqd_int > 30)
        {
                MessageBox("本月份最大日期为30!");
                return;
        }
        



        rq = rqy + "-" + rqm + "-" + rqd;
        yph = JqmToYph(jqm);
        for (int i = 0;i < 8;i++)
        {
                YphRq += rq;
                YphRq += yph;
        }
        zcm = YphRqToZcm(YphRq);

        SetDlgItemText(IDC_EDIT5,zcm);

}


[ 本帖最后由 lqiulu 于 2008-11-10 20:52 编辑 ]

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ghostsyx 发表于 2008-11-10 20:28
生日HAPPY!
szboy 发表于 2008-11-10 19:52
生日丫,那祝你生日快乐!!

我给你送花!!!
 楼主| 网络断魂 发表于 2008-11-10 19:35
XuZhenG 发表于 2008-11-10 19:32
竟然是 C/C++

牛就一个字...
Hmily 发表于 2008-11-10 19:32
断魂兄生日快乐哦,好久没来论坛了~还在打游戏吧
lqiulu 发表于 2008-11-10 20:55
祝生日快乐!学习一下。
ximo 发表于 2008-11-10 21:08
这算法分析太强大了,学习.
生日快乐哈
小生我怕怕 发表于 2008-11-10 21:10
断魂大哥生日快乐!
qifeon 发表于 2008-11-10 22:01
生日快乐,学习了,好算法。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-18 05:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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