飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 15283|回复: 42

[原创] 先知起名大师 2009 超强版破解及算法分析

[复制链接]
  • TA的每日心情
    开心
    2016-12-24 08:16
  • 签到天数: 464 天

    [LV.9]以坛为家II

    发表于 2009-4-7 19:27:37 | 显示全部楼层 |阅读模式
    【破文标题】先知起名大师 2009 超强版破解及算法分析
    【破文作者】萧萧黄叶
    【作者邮箱】
    【作者主页】
    【破解工具】OllyICE,PEiD v0.94,C32Asm
    【破解平台】WinXP
    【软件名称】先知起名大师 2009 超强版
    【软件大小】2703KB
    【原版下载】http://www.newhua.com/soft/79200.htm
    【保护方式】
    【软件简介】名字影响性格,能力,人缘,最终影响命运。
    好的合适的名字给孩子一个自信,光明的未来。
    给孩子起个好名字是父母最基本最重要的责任。
    《先知起名大师 2009》是目前市场上最简单易用,最快速,而又免费试用的起名软件。
    软件运行后,用户输入父母的姓名,出生年份,小孩的性别,出生日期后几分钟即可得到小孩的最佳中

    文名和最佳英文名。
    起名是免费的!
    用户如果注册成为正式版,就可以知道为什么要起这个名,起这个名有什么好处,这个名字为什么最适

    合。

    本软件是先知计算机智能工作室的年度巨献,各方专家倾力合作,集成了中国古代名著的智慧,包括《

    易经》,《论语》,《尔雅》,《说文解字》等著作,必将给您惊喜!

    【破解声明】高手请飘过~~~
    ------------------------------------------------------------------------
    【破解过程】安装好了程序运行看看,使用说明中说“注册的好处是能看到名字背后蕴含的意义”,寻

    就注册一下了。
    任意码注册,确定:“注册码长度不对,请仔细核对!”
    先用PEiD v0.94探壳:什么都没找到  *
    好像没有加壳。
    再用C32Asm分析汇编了,查看字符串,没有相关的内容,再使用Unicode分析字符串,找到了几个:
    004054F5  PUSH 41142C                                 \->: 注册成功!谢谢!祝你好运!

    004054EA  PUSH 411448                                 \->: 注册码长度不对,请仔细核对

    0040550B  PUSH 411414                                 \->: 注册失败!请仔细核对

    这些正是我们需要的,用OllyICE载入吧,在上面地址的附近下断。
    这里是程序入口处:
    0040CEAA > $  6A 74         PUSH 74
    0040CEAC   .  68 F8304100   PUSH SuperNam.004130F8
    0040CEB1   .  E8 CE040000   CALL SuperNam.0040D384

    F9运行程序,用123456789注册看看,断在这里了:
    00405460   .  6A FF         PUSH -1
    00405462   .  68 82DF4000   PUSH SuperNam.0040DF82                   ;  SE 处理程序安装
    00405467   .  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]

    F8单步向下走:
    004054A2   .  E8 F1790000   CALL <JMP.&MFC71U.#3756>
    004054A7   .  8B4C24 08     MOV ECX,DWORD PTR SS:[ESP+8]             ;  经过上面的CALL之后

    ,我们的假码出现在堆栈中,将被移送到ECX上。
    004054AB   .  51            PUSH ECX
    004054AC   .  8D4C24 10     LEA ECX,DWORD PTR SS:[ESP+10]
    004054B0   .  FF15 34004100 CALL DWORD PTR DS:[<&ApolloPlan.HString:>;  

    ApolloPl.HString::HString
    004054B6   .  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]
    004054BA   .  C64424 38 01  MOV BYTE PTR SS:[ESP+38],1
    004054BF   .  FF15 CC004100 CALL DWORD PTR DS:[<&ApolloPlan.HString:>;  

    ApolloPl.HString::empty
    004054C5   .  84C0          TEST AL,AL
    004054C7   .  74 09         JE SHORT SuperNam.004054D2               ;  这里是判断有没有填

    写注册码,如果没有就不跳,然后下面就JMP了。
    004054C9   .  53            PUSH EBX
    004054CA   .  53            PUSH EBX
    004054CB   .  68 64144100   PUSH SuperNam.00411464
    004054D0   .  EB 3E         JMP SHORT SuperNam.00405510
    004054D2   >  8D5424 0C     LEA EDX,DWORD PTR SS:[ESP+C]
    004054D6   .  52            PUSH EDX
    004054D7   .  E8 84360000   CALL SuperNam.00408B60
    004054DC   .  8BC8          MOV ECX,EAX                              ; |
    004054DE   .  E8 5D3A0000   CALL SuperNam.00408F40                   ; \SuperNam.00408F40
    004054E3   .  83F8 FF       CMP EAX,-1
    004054E6   .  53            PUSH EBX
    004054E7   .  53            PUSH EBX
    004054E8   .  75 07         JNZ SHORT SuperNam.004054F1              ;  很明显要注册成功就

    必须要跳,不跳就是注册码长度不对!所以上面的CALL是关键了
    004054EA   .  68 48144100   PUSH SuperNam.00411448                   ;  注册码长度不对,请

    仔细核对

    004054EF   .  EB 1F         JMP SHORT SuperNam.00405510
    004054F1   >  3BC3          CMP EAX,EBX
    004054F3      75 16         JNZ SHORT SuperNam.0040550B              ;  很明显要注册成功就

    不能跳,一跳就死!所以上面的CALL是关键了
    004054F5   .  68 2C144100   PUSH SuperNam.0041142C                   ;  注册成功!谢谢!祝

    你好运!

    004054FA   .  E8 9F790000   CALL <JMP.&MFC71U.#1118>
    004054FF   .  8B06          MOV EAX,DWORD PTR DS:[ESI]
    00405501   .  8BCE          MOV ECX,ESI
    00405503   .  FF90 54010000 CALL DWORD PTR DS:[EAX+154]
    00405509   .  EB 0A         JMP SHORT SuperNam.00405515
    0040550B   >  68 14144100   PUSH SuperNam.00411414                   ;   注册失败!请仔细核



    00405510   >  E8 89790000   CALL <JMP.&MFC71U.#1118>
    00405515   >  8D4C24 0C     LEA ECX,DWORD PTR SS:[ESP+C]

    重新来一次,要着重分析004054DE   .  E8 5D3A0000   CALL SuperNam.00408F40                  

    ; \SuperNam.00408F40
    先看看到底要多少位的注册码才行,
    004054E3   .  83F8 FF       CMP EAX,-1这一句提示要使下面的JNZ跳转成功,EAX就不能等于-1,也

    就是FFFFFFFF。
    跟进关键CALL:
    00408F40  /$  6A FF         PUSH -1
    00408F42  |.  68 91E54000   PUSH SuperNam.0040E591                   ;  SE 处理程序安装
    00408F47  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]

    向下单步到:
    00408FB7  |.  57            PUSH EDI                                 ; /Arg1
    00408FB8  |.  8D4C24 28     LEA ECX,DWORD PTR SS:[ESP+28]            ; |
    00408FBC  |.  E8 8F040000   CALL SuperNam.00409450                   ; \SuperNam.00409450
    00408FC1  |.  8BD8          MOV EBX,EAX
    00408FC3  |.  85DB          TEST EBX,EBX
    00408FC5      0F85 C6000000 JNZ SuperNam.00409091                    ;  走到这里时跳转了,

    中间忽略了一大片,很是可疑,是EBX决定的,EBX的值是上面的CALL计算出来的,想不让它跳就跟进上

    面的CALL看看。
    00408FCB  |.  8D4C24 48     LEA ECX,DWORD PTR SS:[ESP+48]

    再来一次跟进00408FBC的CALL SuperNam.00409450
    00409450  /$  6A FF         PUSH -1
    00409452  |.  68 3BE64000   PUSH SuperNam.0040E63B                   ;  SE 处理程序安装
    00409457  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]

    继续单步:
    00409507  |.  894424 10     MOV DWORD PTR SS:[ESP+10],EAX
    0040950B  |.  FFD3          CALL EBX                                 ;  这个CALL计算出了假

    码的位数。现在为9。
    0040950D  |.  8B4C24 10     MOV ECX,DWORD PTR SS:[ESP+10]            ;  将一个为24的数移到

    了ECX
    00409511  |.  3BC1          CMP EAX,ECX
    00409513      0F85 22010000 JNZ SuperNam.0040963B                    ;  两者相比,不相等就

    跳走。所以24就是注册码的长度,要注册成功首先得注册码的位数为&H24。继续重新来过。
    00409519  |.  6A 00         PUSH 0

    再来一次,用24(十六进制)位字符注册,还到上面的地儿,这一次不跳转了,继续单步:
    00409519  |.  6A 00         PUSH 0
    0040951B  |.  8BCF          MOV ECX,EDI
    0040951D  |.  FFD3          CALL EBX
    0040951F  |.  50            PUSH EAX
    00409520  |.  57            PUSH EDI
    00409521  |.  8D8C24 A00000>LEA ECX,DWORD PTR SS:[ESP+A0]
    00409528  |.  FF15 4C014100 CALL DWORD PTR DS:[<&ApolloPlan.HString:>;  

    ApolloPl.HString::compare_first_n
    0040952E  |.  85C0          TEST EAX,EAX
    00409530      0F85 EA000000 JNZ SuperNam.00409620                    ;  这里又跳走了,结合

    上面的经验分析,应该是上面某个CALL又进行了一次注册码真假的判断,使EAX没有等于00000000,所以

    就跳走了。
    00409536  |.  8B55 00       MOV EDX,DWORD PTR SS:[EBP]

    继续再来,这一次要跟进00409528的CALL DWORD PTR DS:[<&ApolloPlan.HString:>:
    10022C00 >  8A4424 0C       MOV AL,BYTE PTR SS:[ESP+C]
    10022C04    84C0            TEST AL,AL
    10022C06    8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]

    继续单步:
    10022C54    3BF2            CMP ESI,EDX
    10022C56    72 05           JB SHORT ApolloPl.10022C5D
    10022C58    8B40 08         MOV EAX,DWORD PTR DS:[EAX+8]
    10022C5B    EB 03           JMP SHORT ApolloPl.10022C60
    10022C5D    83C0 08         ADD EAX,8
    10022C60    3951 1C         CMP DWORD PTR DS:[ECX+1C],EDX            ; 在这里注意一下EAX出

    现了字符“QM”
    10022C63    72 17           JB SHORT ApolloPl.10022C7C
    10022C65    8B5424 0C       MOV EDX,DWORD PTR SS:[ESP+C]
    10022C69    8B49 08         MOV ECX,DWORD PTR DS:[ECX+8]             ; 将假码也请出来了,放

    在ECX上。
    10022C6C    52              PUSH EDX
    10022C6D    50              PUSH EAX
    10022C6E    51              PUSH ECX                                 ; EAX和ECX的东东都将进

    入下面的CALL进行某一种动作。当然要跟进了。
    10022C6F    FF15 EC340510   CALL DWORD PTR DS:[<&MSVCR71._wcsnicmp>] ; MSVCR71._wcsnicmp
    10022C75    83C4 0C         ADD ESP,0C

    跟进10022C6F的CALL DWORD PTR DS:[<&MSVCR71._wcsnicmp>]:
    7C36FCBB >  55              PUSH EBP
    7C36FCBC    8BEC            MOV EBP,ESP
    7C36FCBE    51              PUSH ECX

    继续单步:
    7C36FCE6   /75 48           JNZ SHORT MSVCR71.7C36FD30
    7C36FCE8   |8B55 0C         MOV EDX,DWORD PTR SS:[EBP+C]             ; 将“QM”移到EDX。
    7C36FCEB   |8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]             ; 将假码移到ECX
    7C36FCEE   |33C0            XOR EAX,EAX                              ; EAX清零。
    7C36FCF0   |66:8B01         MOV AX,WORD PTR DS:[ECX]                 ; 取假码第一位,现在为

    1,ASCII码为31。
    7C36FCF3   |66:3D 4100      CMP AX,41
    7C36FCF7   |72 09           JB SHORT MSVCR71.7C36FD02
    7C36FCF9   |66:3D 5A00      CMP AX,5A
    7C36FCFD   |77 03           JA SHORT MSVCR71.7C36FD02
    7C36FCFF   |83C0 20         ADD EAX,20
    7C36FD02   |8945 FC         MOV DWORD PTR SS:[EBP-4],EAX             ; 由于31没有41大,故而

    跳转到这里。并将31存放到堆栈 SS:[0012DFF4]=00B699D8中。
    7C36FD05   |33C0            XOR EAX,EAX                              ; 再次将EAX清零。
    7C36FD07   |66:8B02         MOV AX,WORD PTR DS:[EDX]                 ; 取“QM”的第一位Q的

    ASCII码,51,放到AX上。
    7C36FD0A   |66:3D 4100      CMP AX,41
    7C36FD0E   |72 09           JB SHORT MSVCR71.7C36FD19
    7C36FD10   |66:3D 5A00      CMP AX,5A
    7C36FD14   |77 03           JA SHORT MSVCR71.7C36FD19
    7C36FD16   |83C0 20         ADD EAX,20                               ; EAX=EAX+20=51+20=71


    7C36FD19   |41              INC ECX
    7C36FD1A   |41              INC ECX
    7C36FD1B   |42              INC EDX
    7C36FD1C   |42              INC EDX
    7C36FD1D   |FF4D 10         DEC DWORD PTR SS:[EBP+10]
    7C36FD20   |74 4A           JE SHORT MSVCR71.7C36FD6C
    7C36FD22   |66:397D FC      CMP WORD PTR SS:[EBP-4],DI
    7C36FD26   |74 44           JE SHORT MSVCR71.7C36FD6C
    7C36FD28   |66:3945 FC      CMP WORD PTR SS:[EBP-4],AX               ; 刚才的两个ASCII码进

    行比较,相等则返回继续比较,不相等则下面的JE不跳,不规则下面就JMP了。
    7C36FD2C  ^|74 C0           JE SHORT MSVCR71.7C36FCEE                ; 所以这里一定要跳。所

    以注册码的前两位一定要为“QM”。QM正是“起名”两个字的第一个汉语拼音字母。应该是了!
    7C36FD2E   |EB 3C           JMP SHORT MSVCR71.7C36FD6C

    下面再来一次,假码的第一、二位为“QM”,还走到上面,这一次由7C36FD20   /74 4A           JE

    SHORT MSVCR71.7C36FD6C

    跳到了这里7C36FD6C    0FB77D FC       MOVZX EDI,WORD PTR SS:[EBP-4]

    走到返回处时EAX=00000000
    这一次
    00409530     /0F85 EA000000 JNZ SuperNam.00409620                    ;  

    没有跳转,继续单步,下面很多的CALL,而且我们已经知道这里很可能就是算法的中心,所以只好先一

    个个的跟进看看了。
    下面这个CALL跟进后发现很可疑:
    0040954E  |.  FF15 48014100 CALL DWORD PTR DS:[<&ApolloPlan.HString:>;  

    ApolloPl.HString::substr

    跟进:
    10022B20 >  6A FF           PUSH -1
    10022B22    68 C2E40410     PUSH ApolloPl.1004E4C2
    10022B27    64:A1 00000000  MOV EAX,DWORD PTR FS:[0]

    10022B59    8B7424 34       MOV ESI,DWORD PTR SS:[ESP+34]            ; 取出了假码的第三位到

    第十位,看看用来干嘛!
    10022B5D    50              PUSH EAX
    10022B5E    8BCE            MOV ECX,ESI

    继续下一个CALL
    跟进0040956C CALL SuperNam.00409290

    00409290  /$  6A FF         PUSH -1
    00409292  |.  68 E4E54000   PUSH SuperNam.0040E5E4                   ;  SE 处理程序安装
    00409297  |.  64:A1 0000000>MOV EAX,DWORD PTR FS:[0]

    走到下面这个CALL时问题已经明了,可能是用来进行了MD5的加密算法
    004092F2  |.  FF15 18014100 CALL DWORD PTR DS:[<&ApolloPlan.HIEUtil:>;  

    ApolloPl.HIEUtil::MD5::MD5

    跟进:
    100477A0 >  56              PUSH ESI
    100477A1    6A 58           PUSH 58
    100477A3    8BF1            MOV ESI,ECX
    100477A5    E8 292E0000     CALL ApolloPl.1004A5D3
    100477AA    50              PUSH EAX
    100477AB    8906            MOV DWORD PTR DS:[ESI],EAX
    100477AD    E8 1E0A0000     CALL ApolloPl.100481D0
    100477B2    83C4 08         ADD ESP,8
    100477B5    8BC6            MOV EAX,ESI
    100477B7    5E              POP ESI
    100477B8    C3              RETN

    再跟进100477AD的CALL ApolloPl.100481D0:

    100481D0    8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]
    100481D4    C740 04 0000000>MOV DWORD PTR DS:[EAX+4],0
    100481DB    C700 00000000   MOV DWORD PTR DS:[EAX],0
    100481E1    C740 08 0123456>MOV DWORD PTR DS:[EAX+8],67452301
    100481E8    C740 0C 89ABCDE>MOV DWORD PTR DS:[EAX+C],EFCDAB89
    100481EF    C740 10 FEDCBA9>MOV DWORD PTR DS:[EAX+10],98BADCFE
    100481F6    C740 14 7654321>MOV DWORD PTR DS:[EAX+14],10325476
    100481FD    C3              RETN

    至此应该能够基本认为是用注册假码的第三位到第十位进行了MD5的加密计算,下面就应该能看到结果了

    ,我们何妨先计算出来看看符不符合。
    34567890 MD5加密后 3AAD95D46A1CE1D2D1DD0CDB347604D9

    继续单步:
    跟进00409348  |.  FF15 0C014100 CALL DWORD PTR DS:[<&ApolloPlan.HIEUtil:>;  

    ApolloPl.HIEUtil::MD5::getDigest

    10047810 >  8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]
    10047814    83C1 04         ADD ECX,4
    10047817    8B11            MOV EDX,DWORD PTR DS:[ECX]
    10047819    8910            MOV DWORD PTR DS:[EAX],EDX
    1004781B    8B51 04         MOV EDX,DWORD PTR DS:[ECX+4]
    1004781E    8950 04         MOV DWORD PTR DS:[EAX+4],EDX
    10047821    8B51 08         MOV EDX,DWORD PTR DS:[ECX+8]
    10047824    8950 08         MOV DWORD PTR DS:[EAX+8],EDX
    10047827    8B49 0C         MOV ECX,DWORD PTR DS:[ECX+C]
    1004782A    8948 0C         MOV DWORD PTR DS:[EAX+C],ECX
    1004782D    C2 0400         RETN 4

    这里是将一系列的数值往定的位置上,与我们上面的得数很相似,看看堆栈 DS:[0012DF70]=D495AD3A在

    数据窗口跟随:
    0012DF70  3A AD 95 D4 6A 1C E1 D2 D1 DD 0C DB 34 76 04 D9  :瓡詊嵋演.?v

    不正是MD5加密后的结果吗!

    继续单步,跟进00409375  |.  E8 76FDFFFF   CALL SuperNam.004090F0

    004090F0  /$  83EC 14       SUB ESP,14
    004090F3  |.  A1 24714100   MOV EAX,DWORD PTR DS:[417124]
    004090F8  |.  33C4          XOR EAX,ESP

    这个CALL里面有一大片都是来循环计算的。

    00409120  |>  8B5424 10     /MOV EDX,DWORD PTR SS:[ESP+10]           ;  看第一次循环
    00409124  |. |0FB6042A      |MOVZX EAX,BYTE PTR DS:[EDX+EBP]         ;  先取MD5值的前两位,

    3A
    00409128  |. |33C9          |XOR ECX,ECX
    0040912A  |. |894C24 15     |MOV DWORD PTR SS:[ESP+15],ECX
    0040912E  |. |894C24 19     |MOV DWORD PTR SS:[ESP+19],ECX
    00409132  |. |8BC8          |MOV ECX,EAX                             ;  3A移到ECX上。
    00409134  |. |C1E9 04       |SHR ECX,4                               ;  ECX位移一下。结果为

    3。
    00409137  |. |8B148D E07041>|MOV EDX,DWORD PTR DS:[ECX*4+4170E0]     ;  对应的结果为“0011

    ”,不就是3的二进制形式吗!
    0040913E  |. |8B0A          |MOV ECX,DWORD PTR DS:[EDX]              ;  将“0011”的ASCII码

    移到ECX。
    00409140  |. |83E0 0F       |AND EAX,0F                              ;  EAX=EAX AND 0F=3A

    AND 0F=A
    00409143  |. |8B1485 E07041>|MOV EDX,DWORD PTR DS:[EAX*4+4170E0]     ;  对应的值为“1010”

    ,正是十六进制数A的十进制形式!
    0040914A  |. |8B02          |MOV EAX,DWORD PTR DS:[EDX]              ;  “1010”的ASCII码放

    到EAX上。
    0040914C  |. |894424 18     |MOV DWORD PTR SS:[ESP+18],EAX           ;  EAX的值存放到堆栈

    SS:[0012DF38]
    00409150  |. |8D4424 14     |LEA EAX,DWORD PTR SS:[ESP+14]
    00409154  |. |894C24 14     |MOV DWORD PTR SS:[ESP+14],ECX           ;  ECX的值存放到堆栈

    SS:[0012DF34]
    00409158  |. |8BC8          |MOV ECX,EAX
    0040915A  |. |8D9B 00000000 |LEA EBX,DWORD PTR DS:[EBX]
    00409160  |> |8A10          |/MOV DL,BYTE PTR DS:[EAX]
    00409162  |. |40            ||INC EAX
    00409163  |. |84D2          ||TEST DL,DL
    00409165  |.^|75 F9         |\JNZ SHORT SuperNam.00409160
    00409167  |. |8BFB          |MOV EDI,EBX
    00409169  |. |2BC1          |SUB EAX,ECX
    0040916B  |. |8BF1          |MOV ESI,ECX
    0040916D  |. |4F            |DEC EDI
    0040916E  |. |8BFF          |MOV EDI,EDI
    00409170  |> |8A4F 01       |/MOV CL,BYTE PTR DS:[EDI+1]
    00409173  |. |47            ||INC EDI
    00409174  |. |84C9          ||TEST CL,CL
    00409176  |.^|75 F8         |\JNZ SHORT SuperNam.00409170
    00409178  |. |8BC8          |MOV ECX,EAX
    0040917A  |. |C1E9 02       |SHR ECX,2
    0040917D  |. |F3:A5         |REP MOVS DWORD PTR ES:[EDI],DWORD PTR D>
    0040917F  |. |8BC8          |MOV ECX,EAX
    00409181  |. |8B4424 2C     |MOV EAX,DWORD PTR SS:[ESP+2C]
    00409185  |. |83E1 03       |AND ECX,3
    00409188  |. |45            |INC EBP
    00409189  |. |3BE8          |CMP EBP,EAX
    0040918B  |. |F3:A4         |REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:>
    0040918D  |.^\7C 91         \JL SHORT SuperNam.00409120              ;  计算的结果就是将加

    密后的字符作为十六进制数转换为二进制数并相连在一起。
    0040918F      5F            POP EDI

    循环结束后看堆栈:
    0012DF24   00B69B50  ASCII

    "001110101010110110010101110101000110101000011100111000011101001011010001110111010000110011

    01101100110100011101100000010011011001"

    返回后继续单步:
    我们注意一下,在刚才返回后在这里
    0040937A  |.  8D9424 880000>LEA EDX,DWORD PTR SS:[ESP+88]

    时EDX上有一大串字符
    堆栈地址=0012DFD0
    EDX=00412500 (SuperNam.00412500), ASCII "678C1-

    1FD08C8669F7FF1324ED26FEACBAC0DC5DEF8F_JKLJLFKKXXX-2C5B-4549-95E3-50C12260F836-5307DB9D-

    7BE1-41ff-817E-8A664C13CC19"


    下面的00409383 CALL SuperNam.004091B0跟进:
    004091B0  /$  8B4424 08     MOV EAX,DWORD PTR SS:[ESP+8]
    004091B4  |.  C600 00       MOV BYTE PTR DS:[EAX],0
    004091B7  |.  8B4424 04     MOV EAX,DWORD PTR SS:[ESP+4]

    看看这个CALL中又有一大片计算。

    00409237  |.  8BF8          MOV EDI,EAX
    00409239  |.  8DA424 000000>LEA ESP,DWORD PTR SS:[ESP]        ;  看第一次循环
    00409240  |>  0FBE59 FF     /MOVSX EBX,BYTE PTR DS:[ECX-1]    ;  先取第二位的。放到EBX上。

    30
    00409244  |.  0FBE51 FE     |MOVSX EDX,BYTE PTR DS:[ECX-2]    ;  取第一位的,放在EDX上。30
    00409248  |.  8D9453 46FFFF>|LEA EDX,DWORD PTR DS:[EBX+EDX*2->;  EDX=EBX+EDX*2-BA=30+30*2-

    BA=FFFFFFD6
    0040924F  |.  0FBE19        |MOVSX EBX,BYTE PTR DS:[ECX]      ;  取第三位放到EBX上。31
    00409252  |.  8D1453        |LEA EDX,DWORD PTR DS:[EBX+EDX*2] ;  

    EDX=EBX+EDX*2=31+FFFFFFD6*2=FFFFFFDD
    00409255  |.  0FBE59 01     |MOVSX EBX,BYTE PTR DS:[ECX+1]    ;  取第四位,放到EBX上,31
    00409259  |.  8D1453        |LEA EDX,DWORD PTR DS:[EBX+EDX*2] ;  

    EDX=EBX+EDX*2=31+FFFFFFDD*2=FFFFFFEB
    0040925C  |.  0FBE59 02     |MOVSX EBX,BYTE PTR DS:[ECX+2]    ;  取第五位,放到EBX上,31
    00409260  |.  031D 20714100 |ADD EBX,DWORD PTR DS:[417120]    ;  EBX=EBX+00412584=004125B5
    00409266  |.  46            |INC ESI                          ;  计数器加1
    00409267  |.  8A1453        |MOV DL,BYTE PTR DS:[EBX+EDX*2]   ;  

    DL=EBX+EDX*2=004125B5+FFFFFFEB*2=0041258B,取值为39,数据窗口跟随看看。
    0040926A  |.  8B5C24 18     |MOV EBX,DWORD PTR SS:[ESP+18]
    0040926E  |.  88541E FF     |MOV BYTE PTR DS:[ESI+EBX-1],DL   ;  将刚才取出来的数放到堆栈

    DS:[0012E394],跟踪堆栈 DS:[0012E394]
    00409272  |.  83C1 05       |ADD ECX,5
    00409275  |.  3BF0          |CMP ESI,EAX                      ;  一共要循环1A次,也就是十进

    制26次。
    00409277  |.^ 7C C7         \JL SHORT SuperNam.00409240
    00409279  |>  8B4424 18     MOV EAX,DWORD PTR SS:[ESP+18]     ;  运行到这里时堆栈中出现了刚

    才循环的结果。堆栈 SS:[0012E308]=0012E394, (ASCII "9CQTDP5C5MJX7NGX3MFMAXJ6V6")
    0040927D  |.  55            PUSH EBP                          ; /block

    数据窗口跟随:
    00412500  36 37 38 43 31 2D 31 46 44 30 38 43 38 36 36 39  678C1-1FD08C8669
    00412510  46 37 46 46 31 33 32 34 45 44 32 36 46 45 41 43  F7FF1324ED26FEAC
    00412520  42 41 43 30 44 43 35 44 45 46 38 46 5F 4A 4B 4C  BAC0DC5DEF8F_JKL
    00412530  4A 4C 46 4B 4B 58 58 58 2D 32 43 35 42 2D 34 35  JLFKKXXX-2C5B-45
    00412540  34 39 2D 39 35 45 33 2D 35 30 43 31 32 32 36 30  49-95E3-50C12260
    00412550  46 38 33 36 2D 35 33 30 37 44 42 39 44 2D 37 42  F836-5307DB9D-7B
    00412560  45 31 2D 34 31 66 66 2D 38 31 37 45 2D 38 41 36  E1-41ff-817E-8A6
    00412570  36 34 43 31 33 43 43 31 39 00 00 00 A0 8C 40 00  64C13CC19...爩@.
    00412580  C0 8C 40 00 32 33 34 35 36 37 38 39 41 42 43 44  缹@.23456789ABCD
    00412590  45 46 47 48 4A 4B 4C 4D 4E 50 51 52 53 54 55 56  EFGHJKLMNPQRSTUV
    004125A0  57 58 59 5A 00 00 00 00 31 31 31 31 00 00 00 00  WXYZ....1111....

    不正好是从上一个CALL出来后出现的一大串字符吗!

    而计算出来的数的们数(9CQTDP5C5MJX7NGX3MFMAXJ6V6)又正好是26位,真码要36位(十六进制数24的十

    进制),36-2-8=26。
    好的方法当然是继续跟了,偷懒的方法就是来试试看能不能注册成功。
    教程够长的了,偷一下懒了,看看现在注册码应该是多少:
    QM 34567890 9CQTDP5C5MJX7NGX3MFMAXJ6V6
    连在一起注册成功了!!!


    【算法总结】
    1、先判断注册码是否为36位;
    2、再判断注册码的前两位是否为字符“QM”,这是注册码的第一部分;
    3、再将注册码的第三位到第十位共八个数进行MD5加密计算,结果设为X,这八个数为注册码的第二部分


    4、将X作为十六进制数转换为十进制数,设为Y;
    5、将Y中的字符的ASCII码每五个作为一组,进行循环计算,每一次的结果在一个固定的字符表中取字符

    ,所有的字符连在一起作为注册码的第三部分;
    6、三者相连就是正确的注册码了。
    ------------------------------------------------------------------------
    【破解总结】
    1、该软件没有加壳。
    2、不是明码比较,而是分段对比,一处不对,下一处就走不到了,所以很难做出内存注册机
    3、算法中采取了以前流行的MD5加密算法。
    4、在MD5加密算法时用的是注册码的一部分,结果是注册码可能与机器无关,做不到一机一码。
    ------------------------------------------------------------------------
    【版权声明】本文只是出于学习和交流目的,请勿用于商业用途,否则后果自负。软件版权归作者所有

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-4-7 20:29:10 | 显示全部楼层
    耐心好~~~ 呵呵...
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-2-2 10:20
  • 签到天数: 38 天

    [LV.5]常住居民I

    发表于 2009-4-8 09:11:31 | 显示全部楼层
    非常详细,非常适合我们这样的新手,感谢楼主,辛苦了!
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    5 小时前
  • 签到天数: 1485 天

    [LV.10]以坛为家III

    发表于 2009-4-9 21:13:53 | 显示全部楼层
    跟楼主学习了。
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2020-7-23 11:27
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    发表于 2009-4-10 11:28:46 | 显示全部楼层
    太强了,太强了,学习
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-4-10 13:01:00 | 显示全部楼层
    学习算法中
    PYG19周年生日快乐!
  • TA的每日心情
    郁闷
    2021-10-2 23:26
  • 签到天数: 46 天

    [LV.5]常住居民I

    发表于 2009-4-10 14:58:20 | 显示全部楼层
    强烈支持下!/:good /:good /:good
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2009-4-11 03:42:23 | 显示全部楼层
    不错,很久都没来了有点遗憾。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-10-25 13:07
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2009-4-13 11:22:48 | 显示全部楼层
    跟着学习下
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    4 天前
  • 签到天数: 1209 天

    [LV.10]以坛为家III

    发表于 2009-4-13 16:43:56 | 显示全部楼层
    太厉害了啊 我看得都头晕了啊 学习了!/:014
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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