tianxj 发表于 2008-1-4 08:55:03

2007年度认证CrackMe的算法分析(易语言版)

标 题: 【原创】2007年度认证CrackMe的算法分析(易语言版)
作 者: acafeel
时 间: 2007-12-29,14:01
链 接: http://bbs.pediy.com/showthread.php?t=57302

【文章标题】: 2007年度认证CrackMe的算法分析(易语言版)
【文章作者】: aCaFeeL
【软件名称】: CrackMe2007.EXE
【软件大小】: 241 KB (247,021 字节)
【下载地址】: https://www.chinapyg.com/
【加壳方式】: NsPacK V3.7
【保护方式】: 压缩加壳
【编写语言】: delphi
【使用工具】: OllyDBG v1.10、C32Asm v0.412、DeDe v3.5、W32Dasm v8.93、ImportREC v1.6f、LordPE v1.4、PEid v0.94、Filemon v7.01
【操作平台】: Windows 98 second 或者 Windows XP sp2
【软件介绍】: 2007年度成员认证CrackMe程序
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】

    简单说下注册流程:
   
    Form1.OnCreat事件: 检测文件自身的大小、名称,生成机器码,检测key文件,其格式成功、长度相等便成功读入,将读入的注册名运算
                     后与读入的注册码比较,如数据相等,则Button1按钮也就可用了;
   
    Timer2.Timer 事件: 再次检测文件大小、检测key文件,成功才会启用Button1按钮,否则是Button1_a假注册按钮;
   
    Button1.Click事件: 将Email的字符串运算之后,连接注册名,再次运算后,得到大数运算需要的KEY,大数运算后得到注册码的第一部份
                     数据,然后将机器码作浮点实数运算,结果转换为字符串后成为注册码的第二部分数据;
   
    Edit4.Change 事件: 重复Button1.Click事件的前面,然后将MD5加密后的真、假注册码比较,相同,再比较尾部是否为字符串"PYG2007",
                     相等,便启动Timer1.Timer事件;
   
    Timer1.Timer 事件: 将Email的字符串运算后连接注册名,再次运算后,得到大数运算需要的KEY。。。后面雷同,省略了。
   
   
   
    具体分析过程,如下:
   
    CrackMe用了NsPacK V3.7压缩,将其脱壳后,在窗口启动时下断点,得到与注册相关的信息如下:
   
    》》》》》》
    004747B9   .64:FF30            push    dword ptr fs:            ;窗口创建时:
    004747BC   .64:8920            mov   dword ptr fs:, esp
    004747BF   .E8 3811FEFF      call    Cra.004558FC
    004747C4   .8D45 F4            lea   eax, dword ptr
    004747C7   .BA E04C4700      mov   edx, Cra.00474CE0          ;CrackMe2007.EXE
    004747CC   .E8 93FDF8FF      call    Cra.00404564
    004747D1   .8D95 18FEFFFF      lea   edx, dword ptr
    004747D7   .A1 0C934700      mov   eax, dword ptr
    004747DC   .8B00               mov   eax, dword ptr
    004747DE   .E8 E9FDFDFF      call    Cra.004545CC
    004747E3   .8B85 18FEFFFF      mov   eax, dword ptr (TApplication):AnsiString
    004747E9   .E8 360EFEFF      call    Cra.00455624
    004747EE   .8BD8               mov   ebx, eax
    004747F0   .E8 0711FEFF      call    Cra.004558FC
    004747F5   .EB 01            jmp   short Cra.004747F8
    004747F7      0F               db      0F
    004747F8   >31F0               xor   eax, esi
    004747FA   .EB 0C            jmp   short Cra.00474808
    004747FC   >33C8               xor   ecx, eax
    004747FE   .EB 03            jmp   short Cra.00474803
    00474800   >EB 09            jmp   short Cra.0047480B
    00474802      0F               db      0F
    00474803   >59               pop   ecx
    00474804   .74 05            je      short Cra.0047480B
    00474806   .^ 75 F8            jnz   short Cra.00474800
    00474808   >51               push    ecx
    00474809   .^ EB F1            jmp   short Cra.004747FC
    0047480B   >81FB C0450400      cmp   ebx, 445C0                      ;比较文件大小 与 280000
    00474811      7F 39            jg      short Cra.0047484C         ;小于或等于,则不跳,表示没有被脱壳
    00474813   .8D95 14FEFFFF      lea   edx, dword ptr
    00474819   .A1 0C934700      mov   eax, dword ptr
    0047481E   .8B00               mov   eax, dword ptr
    00474820   .E8 A7FDFDFF      call    Cra.004545CC               ;得到程序名称
    00474825   .8B85 14FEFFFF      mov   eax, dword ptr
    0047482B   .50               push    eax
    0047482C   .8D95 10FEFFFF      lea   edx, dword ptr
    00474832   .8B45 F4            mov   eax, dword ptr
    00474835   .E8 8228FEFF      call    Cra.004570BC               ;Base64解密
    0047483A   .8B95 10FEFFFF      mov   edx, dword ptr       ;界密结果: "CrackMe2007.EXE"
    00474840   .58               pop   eax
    00474841   .E8 9200F9FF      call    Cra.004048D8               ;比较文件名称
    00474846      0F84 CA000000      je      Cra.00474916               ;相等,则跳!
    0047484C   >8B45 FC            mov   eax, dword ptr
    0047484F   .8B80 14030000      mov   eax, dword ptr       ;TButton1
    00474855   .33D2               xor   edx, edx
    00474857   .E8 A0FBFBFF      call    Cra.004343FC               ;Controls.TControl.SetVisible(TControl;Boolean)
    0047485C   .8B45 FC            mov   eax, dword ptr
    0047485F   .8B80 14030000      mov   eax, dword ptr       ;TButton1
    00474865   .33D2               xor   edx, edx
    00474867   .8B08               mov   ecx, dword ptr
    00474869   .FF51 64            call    dword ptr
    0047486C   .8B45 FC            mov   eax, dword ptr
    0047486F   .8B80 30030000      mov   eax, dword ptr       ;TButton1_a
    00474875   .B2 01            mov   dl, 1
    00474877   .8B08               mov   ecx, dword ptr
    00474879   .FF51 64            call    dword ptr
    0047487C   .8B45 FC            mov   eax, dword ptr
    0047487F   .8B80 30030000      mov   eax, dword ptr       ;TButton1_a
    00474885   .B2 01            mov   dl, 1
    00474887   .E8 70FBFBFF      call    Cra.004343FC               ;Controls.TControl.SetVisible(TControl;Boolean)
    0047488C   .8B45 FC            mov   eax, dword ptr
    0047488F   .8B80 00030000      mov   eax, dword ptr       ;TEdit2
    00474895   .33D2               xor   edx, edx
    00474897   .E8 A48AFBFF      call    Cra.0042D340               ;StdCtrls.TCustomEdit.SetReadOnly
    0047489C   .E8 170FFEFF      call    Cra.004557B8               ;TApplication._PROC_004557B8()
    004748A1   .33C0               xor   eax, eax
    004748A3   .55               push    ebp
    004748A4   .68 F4484700      push    Cra.004748F4
    004748A9   .64:FF30            push    dword ptr fs:            ;***** TRY
    004748AC   .64:8920            mov   dword ptr fs:, esp
    004748AF   .B8 084D4700      mov   eax, Cra.00474D08          ;c:\
    004748B4   .E8 E30CFEFF      call    Cra.0045559C
    004748B9   .69C0 39300000      imul    eax, eax, 3039
    004748BF   .05 2770430B      add   eax, 0B437027
    004748C4   .33D2               xor   edx, edx
    004748C6   .52               push    edx                           ; /Arg2 => 00000000
    004748C7   .50               push    eax                           ; |Arg1
    004748C8   .8D85 0CFEFFFF      lea   eax, dword ptr       ; |
    004748CE   .E8 B93EF9FF      call    Cra.0040878C               ; \Cra.0040878C
    004748D3   .8B95 0CFEFFFF      mov   edx, dword ptr
    004748D9   .8B45 FC            mov   eax, dword ptr
    004748DC   .8B80 FC020000      mov   eax, dword ptr       ;TEdit1
    004748E2   .E8 25FCFBFF      call    Cra.0043450C               ;Controls.TControl.SetText(TControl;TCaption)
    004748E7   .33C0               xor   eax, eax
    004748E9   .5A               pop   edx
    004748EA   .59               pop   ecx
    004748EB   .59               pop   ecx
    004748EC   .64:8910            mov   dword ptr fs:, edx
    004748EF   .E9 9E030000      jmp   Cra.00474C92
    004748F4   .^ E9 23F3F8FF      jmp   Cra.00403C1C
    004748F9   .8B45 FC            mov   eax, dword ptr
    004748FC   .8B80 FC020000      mov   eax, dword ptr       ;TEdit1
    00474902   .BA 144D4700      mov   edx, Cra.00474D14          ;123456789
    00474907   .E8 00FCFBFF      call    Cra.0043450C
    0047490C   .E8 73F6F8FF      call    Cra.00403F84
    00474911   .E9 7C030000      jmp   Cra.00474C92
    00474916   >EB 01            jmp   short Cra.00474919         ;检测正确,跳来了这里
    00474918      0F               db      0F
    00474919   >31F0               xor   eax, esi
    0047491B   .EB 0C            jmp   short Cra.00474929
    0047491D   >33C8               xor   ecx, eax
    0047491F   .EB 03            jmp   short Cra.00474924
    00474921   >EB 09            jmp   short Cra.0047492C
    00474923      0F               db      0F
    00474924   >59               pop   ecx
    00474925   .74 05            je      short Cra.0047492C
    00474927   .^ 75 F8            jnz   short Cra.00474921
    00474929   >51               push    ecx
    0047492A   .^ EB F1            jmp   short Cra.0047491D
    0047492C   >E8 770FFEFF      call    Cra.004558A8               ;CreateFileA -> 打开Key文件
    00474931   .E8 820EFEFF      call    Cra.004557B8               ;TApplication._PROC_004557B8()
    00474936   .33C0               xor   eax, eax
    00474938   .55               push    ebp
    00474939   .68 86494700      push    Cra.00474986
    0047493E   .64:FF30            push    dword ptr fs:            ;***** TRY
    00474941   .64:8920            mov   dword ptr fs:, esp
    00474944   .B8 084D4700      mov   eax, Cra.00474D08          ;c:\
    00474949   .E8 4E0CFEFF      call    Cra.0045559C               ;得到C:\下的卷标号
    0047494E   .69C0 39300000      imul    eax, eax, 3039                  ;卷标号与$3039 相乘 -> eax
    00474954   .05 2770430B      add   eax, 0B437027                   ;其结果 + $0B437027 -> eax
    00474959   .33D2               xor   edx, edx
    0047495B   .52               push    edx                           ; /Arg2 => 00000000
    0047495C   .50               push    eax                           ; |Arg1
    0047495D   .8D85 08FEFFFF      lea   eax, dword ptr       ; |
    00474963   .E8 243EF9FF      call    Cra.0040878C               ; \[将上面的结果转换为无符号数字(即:机器码)
    00474968   .8B95 08FEFFFF      mov   edx, dword ptr       ;结果 -》 eax
    0047496E   .8B45 FC            mov   eax, dword ptr
    00474971   .8B80 FC020000      mov   eax, dword ptr       ;TEdit1
    00474977   .E8 90FBFBFF      call    Cra.0043450C               ;Controls.TControl.SetText(TControl;TCaption)
    0047497C   .33C0               xor   eax, eax
    0047497E   .5A               pop   edx
    0047497F   .59               pop   ecx
    00474980   .59               pop   ecx
    00474981   .64:8910            mov   dword ptr fs:, edx
    00474984   .EB 1D            jmp   short Cra.004749A3
    00474986   .^ E9 91F2F8FF      jmp   Cra.00403C1C
    0047498B   .8B45 FC            mov   eax, dword ptr
    0047498E   .8B80 FC020000      mov   eax, dword ptr
    00474994   .BA 144D4700      mov   edx, Cra.00474D14          ;123456789
    00474999   .E8 6EFBFBFF      call    Cra.0043450C
    0047499E   .E8 E1F5F8FF      call    Cra.00403F84
    004749A3   >E8 100EFEFF      call    Cra.004557B8
    004749A8   .8D4D F8            lea   ecx, dword ptr
    004749AB   .33D2               xor   edx, edx
    004749AD   .B8 284D4700      mov   eax, Cra.00474D28          ;tR^A+.-%=tpc*
    004749B2   .E8 0D0DFEFF      call    Cra.004556C4               ;解密后:oJG_4207.dau=
    004749B7   .E8 FC0DFEFF      call    Cra.004557B8
    004749BC   .8D4D F8            lea   ecx, dword ptr
    004749BF   .33D2               xor   edx, edx
    004749C1   .B8 404D4700      mov   eax, Cra.00474D40          ;thg^%#()_=3WD
    004749C6   .E8 F90CFEFF      call    Cra.004556C4               ;解密后:op~@:?5;L-"AS
    004749CB   .E8 E80DFEFF      call    Cra.004557B8
    004749D0   .8D4D F8            lea   ecx, dword ptr
    004749D3   .33D2               xor   edx, edx
    004749D5   .B8 584D4700      mov   eax, Cra.00474D58          ;FDS_^&$#@@~~_
    004749DA   .E8 E50CFEFF      call    Cra.004556C4               ;解密后:]\JAA:91SPohH
    004749DF   .E8 D40DFEFF      call    Cra.004557B8
    004749E4   .8D4D F8            lea   ecx, dword ptr
    004749E7   .33D2               xor   edx, edx
    004749E9   .B8 704D4700      mov   eax, Cra.00474D70          ;TV%B^&()_+#$%
    004749EE   .E8 D10CFEFF      call    Cra.004556C4               ;解密后:ON<\A:5;L;222
    004749F3   .E8 C00DFEFF      call    Cra.004557B8               ;(最初的 CPU 选择)
    004749F8   .8D4D F8            lea   ecx, dword ptr
    004749FB   .33D2               xor   edx, edx
    004749FD   .B8 884D4700      mov   eax, Cra.00474D88          ;2-atr^%hGIj-%
    00474A02   .E8 BD0CFEFF      call    Cra.004556C4               ;解密后:)5xjmB8zTY{;2
    00474A07   .E8 AC0DFEFF      call    Cra.004557B8
    00474A0C   .EB 01            jmp   short Cra.00474A0F
    00474A0E      0F               db      0F
    00474A0F   >31F0               xor   eax, esi
    00474A11   .EB 0C            jmp   short Cra.00474A1F
    00474A13   >33C8               xor   ecx, eax
    00474A15   .EB 03            jmp   short Cra.00474A1A
    00474A17   >EB 09            jmp   short Cra.00474A22
    00474A19      0F               db      0F
    00474A1A   >59               pop   ecx
    00474A1B   .74 05            je      short Cra.00474A22
    00474A1D   .^ 75 F8            jnz   short Cra.00474A17
    00474A1F   >51               push    ecx
    00474A20   .^ EB F1            jmp   short Cra.00474A13
    00474A22   >8D4D F8            lea   ecx, dword ptr
    00474A25   .BA 01000000      mov   edx, 1
    00474A2A   .B8 A04D4700      mov   eax, Cra.00474DA0          ;KA^A-,-%=tpb-
    00474A2F   .E8 900CFEFF      call    Cra.004556C4               ;解密后:PYG_2007.dat:
    00474A34   .E8 7F0DFEFF      call    Cra.004557B8
    00474A39   .8D95 00FEFFFF      lea   edx, dword ptr
    00474A3F   .33C0               xor   eax, eax
    00474A41   .E8 DEDFF8FF      call    Cra.00402A24
    00474A46   .8B85 00FEFFFF      mov   eax, dword ptr
    00474A4C   .8D95 04FEFFFF      lea   edx, dword ptr
    00474A52   .E8 9142F9FF      call    Cra.00408CE8
    00474A57   .8D85 04FEFFFF      lea   eax, dword ptr
    00474A5D   .8B55 F8            mov   edx, dword ptr           ;KEy文件名称 -》 edx
    00474A60   .E8 2FFDF8FF      call    Cra.00404794
    00474A65   .8B85 04FEFFFF      mov   eax, dword ptr
    00474A6B   .E8 B40BFEFF      call    Cra.00455624
    00474A70   .8BD8               mov   ebx, eax
    00474A72   .E8 410DFEFF      call    Cra.004557B8
    00474A77   .83FB FF            cmp   ebx, -1
    00474A7A   .0F84 A2010000      je      Cra.00474C22               ;如为空,则跳走
    00474A80   .83FB 20            cmp   ebx, 20                         ;长度是否为: 32
    00474A83   .0F85 99010000      jnz   Cra.00474C22               ;不相等,也跳走
    00474A89   .8D95 F8FDFFFF      lea   edx, dword ptr
    00474A8F   .33C0               xor   eax, eax
    00474A91   .E8 8EDFF8FF      call    Cra.00402A24
    00474A96   .8B85 F8FDFFFF      mov   eax, dword ptr
    00474A9C   .8D95 FCFDFFFF      lea   edx, dword ptr
    00474AA2   .E8 4142F9FF      call    Cra.00408CE8
    00474AA7   .8D85 FCFDFFFF      lea   eax, dword ptr
    00474AAD   .8B55 F8            mov   edx, dword ptr
    00474AB0   .E8 DFFCF8FF      call    Cra.00404794
    00474AB5   .8B95 FCFDFFFF      mov   edx, dword ptr
    00474ABB   .8D85 1CFEFFFF      lea   eax, dword ptr
    00474AC1   .E8 DEE2F8FF      call    Cra.00402DA4
    00474AC6   .8D85 1CFEFFFF      lea   eax, dword ptr
    00474ACC   .E8 6FE0F8FF      call    Cra.00402B40
    00474AD1   .E8 8EDDF8FF      call    Cra.00402864
    00474AD6   .8D55 F0            lea   edx, dword ptr
    00474AD9   .8D85 1CFEFFFF      lea   eax, dword ptr
    00474ADF   .E8 38E6F8FF      call    Cra.0040311C
    00474AE4   .8D85 1CFEFFFF      lea   eax, dword ptr
    00474AEA   .E8 99E6F8FF      call    Cra.00403188
    00474AEF   .E8 70DDF8FF      call    Cra.00402864
    00474AF4   .8D85 1CFEFFFF      lea   eax, dword ptr
    00474AFA   .E8 61E3F8FF      call    Cra.00402E60
    00474AFF   .E8 60DDF8FF      call    Cra.00402864
    00474B04   .8D4D E8            lea   ecx, dword ptr
    00474B07   .BA 10000000      mov   edx, 10
    00474B0C   .8B45 F0            mov   eax, dword ptr
    00474B0F   .E8 3453FBFF      call    Cra.00429E48
    00474B14   .33DB               xor   ebx, ebx
    00474B16   .B8 01000000      mov   eax, 1                        ;循环初时计算KEY文件中的前16位
    00474B1B   >8B55 F0            mov   edx, dword ptr
    00474B1E   .0FB65402 FF      movzx   edx, byte ptr
    00474B23   .83EA 0F            sub   edx, 0F                         ;减去F
    00474B26   .83F2 20            xor   edx, 20                         ;xor 20
    00474B29   .03DA               add   ebx, edx                        ;ebx := ebx + edx;
    00474B2B   .40               inc   eax
    00474B2C   .83F8 11            cmp   eax, 11                         ;十进制:17
    00474B2F   .^ 75 EA            jnz   short Cra.00474B1B         ;小于17
    00474B31   .66:9C            pushfw
    00474B33   .6A 0A            push    0A
    00474B35   >E8 02000000      call    Cra.00474B3C
    00474B3A   .^ 73 F9            jnb   short Cra.00474B35
    00474B3C   $83C4 04            add   esp, 4
    00474B3F   .FF0C24             dec   dword ptr
    00474B42   .^ 79 F1            jns   short Cra.00474B35
    00474B44   .83C4 04            add   esp, 4
    00474B47   .66:9D            popfw
    00474B49   .69C3 697A0000      imul    eax, ebx, 7A69                  ;整数乘法 x $7A69
    00474B4F   .8BD8               mov   ebx, eax
    00474B51   .8D85 F4FDFFFF      lea   eax, dword ptr
    00474B57   .50               push    eax                           ; /Arg1
    00474B58   .899D ECFDFFFF      mov   dword ptr , ebx      ; |
    00474B5E   .C685 F0FDFFFF 00   mov   byte ptr , 0         ; |
    00474B65   .8D95 ECFDFFFF      lea   edx, dword ptr       ; |
    00474B6B   .33C9               xor   ecx, ecx                        ; |
    00474B6D   .B8 B84D4700      mov   eax, Cra.00474DB8          ; |%0x
    00474B72   .E8 B149F9FF      call    Cra.00409528               ; \[将上面的结果转换成字符串
    00474B77   .8B85 F4FDFFFF      mov   eax, dword ptr       ;字符串 -> eax 中
    00474B7D   .8D55 EC            lea   edx, dword ptr
    00474B80   .E8 CB37F9FF      call    Cra.00408350
    00474B85   .66:9C            pushfw
    00474B87   .6A 0A            push    0A
    00474B89   >E8 02000000      call    Cra.00474B90
    00474B8E   .^ 73 F9            jnb   short Cra.00474B89
    00474B90   $83C4 04            add   esp, 4
    00474B93   .FF0C24             dec   dword ptr
    00474B96   .^ 79 F1            jns   short Cra.00474B89
    00474B98   .83C4 04            add   esp, 4
    00474B9B   .66:9D            popfw
    00474B9D   .8D95 E8FDFFFF      lea   edx, dword ptr
    00474BA3   .8B45 E8            mov   eax, dword ptr          ;取后面的16个字符串
    00474BA6   .E8 F539F9FF      call    Cra.004085A0               ;返回一个删除了空制字符和空格的结果字符串
    00474BAB   .8B85 E8FDFFFF      mov   eax, dword ptr       ;-》 eax
    00474BB1   .8B55 EC            mov   edx, dword ptr          ;前16位数的运算结果
    00474BB4   .E8 1FFDF8FF      call    Cra.004048D8               ;比较两字符串 是否 相等?
    00474BB9   .0F85 D3000000      jnz   Cra.00474C92               ;不相等,便跳走!
    00474BBF   .8B45 FC            mov   eax, dword ptr
    》》》》》》
   
   
    通过对上面的的分析,知道了机器码为:得到C:盘的卷标序列号,然后乘以12345,再加上188968999的结果的无符号数;
   
    而KEY文件的名称为:PYG_2007.dat,其长度必须是32字节,前16位保存注册名,后16位保存注册码,其算法表述为:

    .局部变量 pos, 整数型
    .局部变量 ebx, 整数型
    .局部变量 edx, 整数型
    .局部变量 ResultName, 文本型
    .局部变量 name, 字节型, , "16"
    .局部变量 code, 字节型, , "16"
   
    .计次循环首 (16, pos)
      name = 0
    .计次循环尾 ()
   
    .计次循环首 (16, pos)
      code = 32' 默认为16个空格符号
    .计次循环尾 ()
   
    .计次循环首 (取文本长度 (编辑框name.内容), pos)
      name = 取代码 (取文本中间 (编辑框name.内容, pos, 1), )
    .计次循环尾 ()
   
    ebx = 0
    .计次循环首 (16, pos)
      edx = 到整数 (name ) - 15
      edx = 位异或 (edx, 32)
      ebx = ebx + edx
    .计次循环尾 ()
   
    ebx = ebx × 31337
    ResultName = 取十六进制文本 (ebx)
   
    .计次循环首 (取文本长度 (ResultName), pos)
      code = 取代码 (取文本中间 (ResultName, pos, 1), )
    .计次循环尾 ()
   
   
    然后,将name和code的缓冲区中的数据写入到PYG_2007.dat文件中,即可!
   
   
    前面的条件符合之后,再看Timer2.Timer事件中的代码,如下:
   
    》》》》》》
    0047672E   .64:FF30            push    dword ptr fs:            ;Timer2.Timer事件:
    00476731   .64:8920            mov   dword ptr fs:, esp
    00476734   .E8 C3F1FDFF      call    Cra.004558FC
    00476739   .8D95 1CFEFFFF      lea   edx, dword ptr
    0047673F   .A1 0C934700      mov   eax, dword ptr
    00476744   .8B00               mov   eax, dword ptr
    00476746   .E8 81DEFDFF      call    Cra.004545CC               ;得到程序名称
    0047674B   .8B85 1CFEFFFF      mov   eax, dword ptr
    00476751   .E8 CEEEFDFF      call    Cra.00455624
    00476756   .3D C0450400      cmp   eax, 445C0                      ;十进制:280000
    0047675B      0F8E CA000000      jle   Cra.0047682B               ;小于,便跳!(表示:加了壳)
    00476761   .8B45 FC            mov   eax, dword ptr
    (省略)
    0047682B   >E8 78F0FDFF      call    Cra.004558A8               ;CreateFileA
    00476830   .E8 83EFFDFF      call    Cra.004557B8
    00476835   .33C0               xor   eax, eax
    00476837   .55               push    ebp
    00476838   .68 85684700      push    Cra.00476885
    0047683D   .64:FF30            push    dword ptr fs:            ;***** TRY
    00476840   .64:8920            mov   dword ptr fs:, esp
    00476843   .B8 886B4700      mov   eax, Cra.00476B88          ;c:\
    00476848   .E8 4FEDFDFF      call    Cra.0045559C               ;得到C:\的序列号
    0047684D   .69C0 39300000      imul    eax, eax, 3039
    00476853   .05 2770430B      add   eax, 0B437027                   ;eax 的10进制结果为机器码
    00476858   .33D2               xor   edx, edx
    0047685A   .52               push    edx                           ; /Arg2 => 00000000
    0047685B   .50               push    eax                           ; |Arg1
    0047685C   .8D85 14FEFFFF      lea   eax, dword ptr       ; |
    00476862   .E8 251FF9FF      call    Cra.0040878C               ; \Cra.0040878C
    00476867   .8B95 14FEFFFF      mov   edx, dword ptr       ;//机器码,上面结果的无符号数字
    0047686D   .8B45 FC            mov   eax, dword ptr
    (省略)
    0047694E   .8B85 10FEFFFF      mov   eax, dword ptr
    00476954   .E8 CBECFDFF      call    Cra.00455624
    00476959   .8BD8               mov   ebx, eax
    0047695B   .E8 58EEFDFF      call    Cra.004557B8
    00476960   .83FB FF            cmp   ebx, -1                         ;为空
    00476963   .0F84 72010000      je      Cra.00476ADB               ;不能跳!
    00476969   .83FB 20            cmp   ebx, 20                         ;十进制:32
    0047696C   .0F85 69010000      jnz   Cra.00476ADB               ;不能跳!
    00476972   .8D95 04FEFFFF      lea   edx, dword ptr
    (省略)
    004769FD   .33DB               xor   ebx, ebx
    004769FF   .B8 01000000      mov   eax, 1
    00476A04   >8B55 F4            mov   edx, dword ptr           ;取前16位数字
    00476A07   .0FB65402 FF      movzx   edx, byte ptr
    00476A0C   .83EA 0F            sub   edx, 0F
    00476A0F   .83F2 20            xor   edx, 20
    00476A12   .03DA               add   ebx, edx
    00476A14   .40               inc   eax
    00476A15   .83F8 11            cmp   eax, 11                         ;十进制:17
    00476A18   .^ 75 EA            jnz   short Cra.00476A04         ;小于17
    00476A1A   .69C3 697A0000      imul    eax, ebx, 7A69                  ;整乘法
    00476A20   .8BD8               mov   ebx, eax
    00476A22   .8D85 00FEFFFF      lea   eax, dword ptr
    00476A28   .50               push    eax                           ; /Arg1
    00476A29   .899D F8FDFFFF      mov   dword ptr , ebx      ; |
    00476A2F   .C685 FCFDFFFF 00   mov   byte ptr , 0         ; |
    00476A36   .8D95 F8FDFFFF      lea   edx, dword ptr       ; |
    00476A3C   .33C9               xor   ecx, ecx                        ; |
    00476A3E   .B8 386C4700      mov   eax, Cra.00476C38          ; |%0x
    00476A43   .E8 E02AF9FF      call    Cra.00409528               ; \Cra.00409528
    00476A48   .8B85 00FEFFFF      mov   eax, dword ptr       ;//结果
    00476A4E   .8D55 F0            lea   edx, dword ptr
    00476A51   .E8 FA18F9FF      call    Cra.00408350               ;SysUtils.UpperCase(AnsiString):AnsiString;
    00476A56   .8D95 F4FDFFFF      lea   edx, dword ptr
    00476A5C   .8B45 EC            mov   eax, dword ptr          ;取后16位数字
    00476A5F   .E8 3C1BF9FF      call    Cra.004085A0               ;SysUtils.Trim(AnsiString):AnsiString;overload;
    00476A64   .8B85 F4FDFFFF      mov   eax, dword ptr
    00476A6A   .8B55 F0            mov   edx, dword ptr
    00476A6D   .E8 66DEF8FF      call    Cra.004048D8               ;System.@LStrCmp;
    00476A72   .0F85 C3000000      jnz   Cra.00476B3B               ;不能跳!要相等
    00476A78   .8B45 FC            mov   eax, dword ptr
    (省略)
    》》》》》》
   
   
    通过对上面的分析,发现其检测的代码和窗口创建时候的几乎雷同,故跳过,不用分析了;
    但是必须注意:
    要将 0047675B   /0F8E CA000000      jle   Cra.0047682B 这行改为jmp强制跳转哟!
    不然到不了Button1按钮中的代码,呵呵;谁让我不是带壳调试呐 ;)
   
   
    将上面修改之后,这时点击『注册』按钮,便来到了Button1按钮点击后的事件中(不是Button1_a按钮哟),其代码如下:
   
    》》》》》》
    00474263|.51               push    ecx                           ;Button1 按钮中的代码:
    00474264|.53               push    ebx
    00474265|.56               push    esi
    00474266|.8945 FC            mov   dword ptr , eax
    00474269|.8D45 E8            lea   eax, dword ptr
    0047426C|.8B15 88594500      mov   edx, dword ptr          ;Cra.0045598C
    00474272|.E8 0D0CF9FF      call    Cra.00404E84               ;System.@InitializeRecord
    00474277|.8D45 E0            lea   eax, dword ptr          ;System.@AddRefRecord
    0047427A|.8B15 88594500      mov   edx, dword ptr          ;Cra.0045598C
    00474280|.E8 FF0BF9FF      call    Cra.00404E84               ;System.@InitializeRecord
    00474285|.8D45 D8            lea   eax, dword ptr          ;System.@AddRefRecord
    00474288|.8B15 88594500      mov   edx, dword ptr          ;Cra.0045598C
    0047428E|.E8 F10BF9FF      call    Cra.00404E84               ;System.@InitializeRecord
    00474293|.33C0               xor   eax, eax
    00474295|.55               push    ebp
    00474296|.68 15474700      push    Cra.00474715
    0047429B|.64:FF30            push    dword ptr fs:
    0047429E|.64:8920            mov   dword ptr fs:, esp
    004742A1|.E8 1215FEFF      call    Cra.004557B8
    004742A6|.8D55 84            lea   edx, dword ptr
    004742A9|.8B45 FC            mov   eax, dword ptr
    004742AC|.8B80 04030000      mov   eax, dword ptr       ;TEdit3
    004742B2|.E8 2502FCFF      call    Cra.004344DC               ;Controls.TControl.GetText(TControl):TCaption
    004742B7|.8B45 84            mov   eax, dword ptr
    004742BA|.E8 1512FEFF      call    Cra.004554D4
    004742BF|.84C0               test    al, al                        ;是否输入了Email?
    004742C1|.75 0F            jnz   short Cra.004742D2         ;有,则跳
    004742C3|.8D45 F8            lea   eax, dword ptr
    004742C6|.BA 30474700      mov   edx, Cra.00474730          ;[email protected]
    004742CB|.E8 9402F9FF      call    Cra.00404564
    004742D0|.EB 11            jmp   short Cra.004742E3
    004742D2|>8D55 F8            lea   edx, dword ptr
    004742D5|.8B45 FC            mov   eax, dword ptr
    004742D8|.8B80 04030000      mov   eax, dword ptr       ;TEdit3
    004742DE|.E8 F901FCFF      call    Cra.004344DC               ;得到Email的长度 -> eax
    004742E3|>33DB               xor   ebx, ebx
    004742E5|.C745 98 596F7520   mov   dword ptr , 20756F59    ;'You '
    004742EC|.C745 9C 6C6F7665   mov   dword ptr , 65766F6C    ;'love'
    004742F3|.C745 A0 20505947   mov   dword ptr , 47595020    ;' PYG'
    004742FA|.8B45 F8            mov   eax, dword ptr           ;Email -> eax
    004742FD|.E8 8A04F9FF      call    Cra.0040478C               ;得到Email的长度 -> eax
    00474302|.8BC8               mov   ecx, eax
    00474304|.85C9               test    ecx, ecx                        ;Emai长度是否为0?
    00474306|.7E 19            jle   short Cra.00474321
    00474308|.BE 01000000      mov   esi, 1
    0047430D|>8B45 F8            /mov   eax, dword ptr          ;Email -> eax
    00474310|.0FB64430 FF      |movzx   eax, byte ptr       ;依次取Email的ASCII码
    00474315|.83C0 0F            |add   eax, 0F                        ;加上 $F
    00474318|.83F0 20            |xor   eax, 20                        ;异或 $20
    0047431B|.03D8               |add   ebx, eax                     ;ebx := ebx + eax;(结果)
    0047431D|.46               |inc   esi
    0047431E|.49               |dec   ecx                            ;减去1
    0047431F|.^ 75 EC            \jnz   short Cra.0047430D      ;不为0,则循环
    00474321|>8BC3               mov   eax, ebx                        ;-> eax
    00474323|.33D2               xor   edx, edx
    00474325|.52               push    edx                           ; /Arg2 => 00000000
    00474326|.50               push    eax                           ; |Arg1
    00474327|.8D45 F4            lea   eax, dword ptr           ; |
    0047432A|.E8 5D44F9FF      call    Cra.0040878C               ; \[将上面的结果转换为10进制的字符串
    0047432F|.8D55 80            lea   edx, dword ptr
    00474332|.8B45 FC            mov   eax, dword ptr
    00474335|.8B80 00030000      mov   eax, dword ptr       ;TEdit2
    0047433B|.E8 9C01FCFF      call    Cra.004344DC
    00474340|.8B4D 80            mov   ecx, dword ptr          ;注册名 -> ecx
    00474343|.8D45 F0            lea   eax, dword ptr
    00474346|.8B55 F4            mov   edx, dword ptr           ;前面计算结果的十进制数 字符串
    00474349|.E8 8A04F9FF      call    Cra.004047D8               ;两字符串连接
    0047434E|.8B45 F0            mov   eax, dword ptr          ;新结果 -> eax
    00474351|.E8 3604F9FF      call    Cra.0040478C               ;得到新字符串的长度 -> eax
    00474356|.8BC8               mov   ecx, eax                        ;ecx := eax;
    00474358|.85C9               test    ecx, ecx                        ;新字符串是否为空?
    0047435A|.7E 22            jle   short Cra.0047437E         ;为空,则跳
    0047435C|.BE 01000000      mov   esi, 1
    00474361|>8B45 F0            /mov   eax, dword ptr       ;新字符串 -> eax
    00474364|.0FB64430 FF      |movzx   eax, byte ptr       ;依次取该字符串的ASCII码 -> eax
    00474369|.0345 98            |add   eax, dword ptr       ;初始值: $20756F59 加法
    0047436C|.25 FF000000      |and   eax, 0FF                     ;与 运输 $FF
    00474371|.03C3               |add   eax, ebx                     ;加上前面的结果
    00474373|.99               |cdq
    00474374|.33C2               |xor   eax, edx
    00474376|.2BC2               |sub   eax, edx                     ;eax := eax - edx;
    00474378|.8BD8               |mov   ebx, eax                     ;-> ebx
    0047437A|.46               |inc   esi
    0047437B|.49               |dec   ecx                            ;减去1
    0047437C|.^ 75 E3            \jnz   short Cra.00474361      ;不为0,这循环运算
    0047437E|>8BC3               mov   eax, ebx
    00474380|.C1E0 0A            shl   eax, 0A                         ;上面的结果 shl $0A
    00474383|.0345 9C            add   eax, dword ptr          ;再加上 $65766F6C
    00474386|.99               cdq
    00474387|.33C2               xor   eax, edx
    00474389|.2BC2               sub   eax, edx
    0047438B|.8BD8               mov   ebx, eax
    0047438D|.8BC3               mov   eax, ebx
    0047438F|.33D2               xor   edx, edx
    00474391|.52               push    edx                           ; /Arg2 => 00000000
    00474392|.50               push    eax                           ; |Arg1
    00474393|.8D85 7CFFFFFF      lea   eax, dword ptr          ; |
    00474399|.E8 EE43F9FF      call    Cra.0040878C               ; \Cra.0040878C
    0047439E|.8B85 7CFFFFFF      mov   eax, dword ptr          ;上面运算结果的10进制字符串 ->eax
    004743A4|.8D55 E8            lea   edx, dword ptr
    004743A7|.E8 B017FEFF      call    Cra.00455B5C               ;字上面的符串转换为大数
    004743AC|.8B45 A0            mov   eax, dword ptr          ;' PYG'的ascII码 -> eax
    004743AF|.05 40E20100      add   eax, 1E240                      ;eax := $47595020 + $1E240
    004743B4|.33D2               xor   edx, edx
    004743B6|.52               push    edx                           ; /Arg2 => 00000000
    004743B7|.50               push    eax                           ; |$475B3260 <- eax
    004743B8|.8D85 78FFFFFF      lea   eax, dword ptr          ; |
    004743BE|.E8 C943F9FF      call    Cra.0040878C               ; \Cra.0040878C
    004743C3|.8B85 78FFFFFF      mov   eax, dword ptr          ;上面运算结果的10进制字符串(就是固定的)
    004743C9|.8D55 E0            lea   edx, dword ptr
    004743CC|.E8 8B17FEFF      call    Cra.00455B5C               ;字上面的符串转换为大数
    004743D1|.8D4D D8            lea   ecx, dword ptr
    004743D4|.8D55 E0            lea   edx, dword ptr
    004743D7|.8D45 E8            lea   eax, dword ptr
    004743DA|.E8 891BFEFF      call    Cra.00455F68               ;//计算第一组数据 大数加法
    004743DF|.8D55 D4            lea   edx, dword ptr
    004743E2|.8D45 D8            lea   eax, dword ptr
    004743E5|.E8 D219FEFF      call    Cra.00455DBC               ;//将其转换为10进制的字符串(去掉前面的0)
    004743EA|.8D4D D8            lea   ecx, dword ptr
    004743ED|.8D55 E0            lea   edx, dword ptr
    004743F0|.8D45 E8            lea   eax, dword ptr
    004743F3|.E8 041FFEFF      call    Cra.004562FC               ;//计算第二组数据 大数乘法
    004743F8|.8D55 D0            lea   edx, dword ptr
    004743FB|.8D45 D8            lea   eax, dword ptr
    004743FE|.E8 B919FEFF      call    Cra.00455DBC               ;//将其转换为10进制的字符串(去掉前面的0)
    00474403|.8D4D D8            lea   ecx, dword ptr
    00474406|.8D55 E0            lea   edx, dword ptr
    00474409|.8D45 E8            lea   eax, dword ptr
    0047440C|.E8 AB1DFEFF      call    Cra.004561BC               ;//计算第三组数据 不是大数运算哟!
    00474411|.8D45 D8            lea   eax, dword ptr
    00474414|.E8 A71EFEFF      call    Cra.004562C0
    00474419|.8D55 CC            lea   edx, dword ptr
    0047441C|.8D45 D8            lea   eax, dword ptr
    0047441F|.E8 9819FEFF      call    Cra.00455DBC               ;//将其转换为10进制的字符串(去掉前面的0)
    00474424|.FF75 D4            push    dword ptr             ;//(ASCII)1
    00474427|.FF75 D0            push    dword ptr             ;//(ASCII)2
    0047442A|.FF75 CC            push    dword ptr             ;//(ASCII)3
    0047442D|.8D45 C8            lea   eax, dword ptr
    00474430|.BA 03000000      mov   edx, 3
    00474435|.E8 1204F9FF      call    Cra.0040484C               ;System.@LStrCatN
    0047443A|.8D55 E8            lea   edx, dword ptr
    0047443D|.8B45 C8            mov   eax, dword ptr          ;//(ASCII)1+2+3 -> eax
    00474440|.E8 1717FEFF      call    Cra.00455B5C               ;字上面的符串转换为大数
    00474445|.8D95 74FFFFFF      lea   edx, dword ptr
    0047444B|.B8 00DE0000      mov   eax, 0DE00                      ;KEy: $DC00 -> eax
    00474450|.E8 4B42F9FF      call    Cra.004086A0               ;转为字符串
    00474455|.8B85 74FFFFFF      mov   eax, dword ptr          ;即为(ASCII "56832") -> eax
    0047445B|.8D55 E0            lea   edx, dword ptr
    0047445E|.E8 F916FEFF      call    Cra.00455B5C               ;字上面的符串转换为大数
    00474463|.8D4D D8            lea   ecx, dword ptr
    00474466|.8D55 E0            lea   edx, dword ptr
    00474469|.8D45 E8            lea   eax, dword ptr
    0047446C|.E8 8B1EFEFF      call    Cra.004562FC               ;得到注册码的第一部份 大数乘法
    00474471|.8D55 C4            lea   edx, dword ptr
    00474474|.8D45 D8            lea   eax, dword ptr
    00474477|.E8 4019FEFF      call    Cra.00455DBC               ;//将其转换为10进制的字符串(去掉前面的0)
    0047447C|.8D45 C4            lea   eax, dword ptr
    0047447F|.BA 20000000      mov   edx, 20                         ;取长度为:32
    00474484|.E8 8F06F9FF      call    Cra.00404B18               ;从头开始截取32长度
    00474489|.8D85 6CFFFFFF      lea   eax, dword ptr
    0047448F|.50               push    eax
    00474490|.8D95 64FFFFFF      lea   edx, dword ptr
    00474496|.8B45 FC            mov   eax, dword ptr
    00474499|.8B80 FC020000      mov   eax, dword ptr       ;TEdit1
    0047449F|.E8 3800FCFF      call    Cra.004344DC               ;Controls.TControl.GetText(TControl):TCaption
    004744A4|.8B85 64FFFFFF      mov   eax, dword ptr          ;//机器码 -> eax
    004744AA|.E8 0558F9FF      call    Cra.00409CB4               ;机器码转化为实数
    004744AF|.D80D 44474700      fmul    dword ptr             ;* 3.000000
    004744B5|.D805 48474700      fadd    dword ptr             ;+ 521725.0
    004744BB|.83C4 F4            add   esp, -0C
    004744BE|.DB3C24             fstp    tbyte ptr                ; |出栈 -> ST7
    004744C1|.9B               wait                                    ; |
    004744C2|.8D85 68FFFFFF      lea   eax, dword ptr          ; |
    004744C8|.E8 8757F9FF      call    Cra.00409C54               ; \[转化为字符串
    004744CD|.8B85 68FFFFFF      mov   eax, dword ptr          ;//ST7 由机器码得来 -> eax
    004744D3|.B9 08000000      mov   ecx, 8                        ;ecx := 8;
    004744D8|.BA 01000000      mov   edx, 1
    004744DD|.E8 0A05F9FF      call    Cra.004049EC               ;System.@LStrCopy
    004744E2|.8B85 6CFFFFFF      mov   eax, dword ptr          ;//上面结果的前8位字符 -> eax
    004744E8|.E8 C757F9FF      call    Cra.00409CB4               ;再次转化为实数
    004744ED|.D80D 4C474700      fmul    dword ptr             ;* 321.0000
    004744F3|.DB2D 50474700      fld   tbyte ptr             ;9614516412.0000000000 -> ST0
    004744F9|.DEC1               faddp   st(1), st                     ;ST1 + ST0
    004744FB|.DB2D 5C474700      fld   tbyte ptr             ;96145164.000000000000 -> ST0
    00474501|.DEE9               fsubp   st(1), st                     ;ST1 - ST0
    00474503|.83C4 F4            add   esp, -0C
    00474506|.DB3C24             fstp    tbyte ptr                ; |出栈 -> ST7
    00474509|.9B               wait                                    ; |
    0047450A|.8D85 70FFFFFF      lea   eax, dword ptr          ; |
    00474510|.E8 3F57F9FF      call    Cra.00409C54               ; \Cra.00409C54
    00474515|.8B95 70FFFFFF      mov   edx, dword ptr          ;//ST7 注册码第2部分 -> edx
    0047451B|.8D45 C4            lea   eax, dword ptr
    0047451E|.E8 7102F9FF      call    Cra.00404794               ;注册码第1/2部分连接
    00474523|.8D55 88            lea   edx, dword ptr
    00474526|.8B45 C4            mov   eax, dword ptr          ;注册码1/2部分连接后 -> eax
    00474529|.E8 9E29FEFF      call    Cra.00456ECC               ;将上面的结果MD5加密
    0047452E|.8D95 60FFFFFF      lea   edx, dword ptr
    00474534|.8D45 88            lea   eax, dword ptr
    00474537|.E8 042AFEFF      call    Cra.00456F40
    0047453C|.8B85 60FFFFFF      mov   eax, dword ptr          ;MD5加密结果 -> eax
    00474542|.8D55 C0            lea   edx, dword ptr
    00474545|.E8 063EF9FF      call    Cra.00408350               ;转为大写
    0047454A|.8D45 BC            lea   eax, dword ptr
    0047454D|.50               push    eax
    0047454E|.B9 08000000      mov   ecx, 8
    00474553|.BA 01000000      mov   edx, 1
    00474558|.8B45 C0            mov   eax, dword ptr
    0047455B|.E8 8C04F9FF      call    Cra.004049EC               ;System.@LStrCopy
    00474560|.8D45 B8            lea   eax, dword ptr
    00474563|.50               push    eax
    00474564|.B9 08000000      mov   ecx, 8
    00474569|.BA 09000000      mov   edx, 9
    0047456E|.8B45 C0            mov   eax, dword ptr          ;MD5加密结果 -> eax
    00474571|.E8 7604F9FF      call    Cra.004049EC               ;System.@LStrCopy
    00474576|.8D4D B4            lea   ecx, dword ptr
    00474579|.BA 10000000      mov   edx, 10
    0047457E|.8B45 C0            mov   eax, dword ptr
    00474581|.E8 C258FBFF      call    Cra.00429E48               ;StrUtils.RightStr(AnsiString;Integer):AnsiString
    00474586|.8D95 5CFFFFFF      lea   edx, dword ptr
    0047458C|.8B45 FC            mov   eax, dword ptr
    0047458F|.8B80 28030000      mov   eax, dword ptr       ;TEdit4
    00474595|.E8 42FFFBFF      call    Cra.004344DC               ;Controls.TControl.GetText(TControl):TCaption
    0047459A|.8B85 5CFFFFFF      mov   eax, dword ptr          ;获取输入的注册码 -> eax
    004745A0|.8D55 88            lea   edx, dword ptr
    004745A3|.E8 2429FEFF      call    Cra.00456ECC               ;将输入的注册码 MD5加密
    004745A8|.8D95 58FFFFFF      lea   edx, dword ptr
    004745AE|.8D45 88            lea   eax, dword ptr
    004745B1|.E8 8A29FEFF      call    Cra.00456F40               ;MD5加密
    004745B6|.8B85 58FFFFFF      mov   eax, dword ptr          ;加密结果 -> eax
    004745BC|.8D55 B0            lea   edx, dword ptr
    004745BF|.E8 8C3DF9FF      call    Cra.00408350               ;转为大写
    004745C4|.8D45 AC            lea   eax, dword ptr
    004745C7|.50               push    eax
    004745C8|.B9 08000000      mov   ecx, 8
    004745CD|.BA 01000000      mov   edx, 1
    004745D2|.8B45 B0            mov   eax, dword ptr
    004745D5|.E8 1204F9FF      call    Cra.004049EC               ;System.@LStrCopy
    004745DA|.8D45 A8            lea   eax, dword ptr
    004745DD|.50               push    eax
    004745DE|.B9 08000000      mov   ecx, 8
    004745E3|.BA 09000000      mov   edx, 9
    004745E8|.8B45 B0            mov   eax, dword ptr
    004745EB|.E8 FC03F9FF      call    Cra.004049EC               ;System.@LStrCopy
    004745F0|.8D4D A4            lea   ecx, dword ptr
    004745F3|.BA 10000000      mov   edx, 10
    004745F8|.8B45 B0            mov   eax, dword ptr
    004745FB|.E8 4858FBFF      call    Cra.00429E48             ;StrUtils.RightStr(AnsiString;Integer):AnsiString
    00474600|.8B45 BC            mov   eax, dword ptr          ;//被MD5加密的真正的注册码 前8位
    00474603|.8B55 AC            mov   edx, dword ptr          ;//被MD5加密的输入的注册码 前8位
    00474606|.E8 CD02F9FF      call    Cra.004048D8               ;比较,是否相同?
    0047460B      75 7F            jnz   short Cra.0047468C         ;不同,则跳出
    0047460D|.8B45 B8            mov   eax, dword ptr          ;//被MD5加密的真正的注册码9~16位
    00474610|.8B55 A8            mov   edx, dword ptr          ;//被MD5加密的输入的注册码9~16位
    00474613|.E8 C002F9FF      call    Cra.004048D8               ;System.@LStrCmp
    00474618|.75 72            jnz   short Cra.0047468C         ;不同,则跳出
    0047461A|.8B45 B4            mov   eax, dword ptr          ;//被MD5加密的真正的注册码 其余剩下的
    0047461D|.8B55 A4            mov   edx, dword ptr          ;//被MD5加密的输入的注册码 其余剩下的
    00474620|.E8 B302F9FF      call    Cra.004048D8               ;System.@LStrCmp
    00474625|.75 65            jnz   short Cra.0047468C         ;不同,则跳出
    00474627|.B8 70474700      mov   eax, Cra.00474770          ;注册假成功!
    0047462C|.E8 6742FBFF      call    Cra.00428898            ;* Reference to: Dialogs.ShowMessage(AnsiString);
    00474631|.8D95 54FFFFFF      lea   edx, dword ptr
    00474637|.B8 84474700      mov   eax, Cra.00474784          ;糟糕!中计了!
    0047463C|.E8 7B2AFEFF      call    Cra.004570BC
    00474641|.8B85 54FFFFFF      mov   eax, dword ptr
    00474647|.E8 4C42FBFF      call    Cra.00428898               ;Dialogs.ShowMessage(AnsiString)
    0047464C|.8B45 FC            mov   eax, dword ptr
    》》》》》》
   
   
    通过对上面的分析,知道了其算法为:
   
    读取E-mail中的字符串,检查是否为空,不为空,则依次取其字符码,循环运算,得到一个数字,然后将该数字转换为10进制的字符串,
    再和Key文件中读入的注册名相连接,然后再参与一个循环运算,得到的数字转换为10进制的字符串后,即为大数运算的一个变量,而另一
    个大数变量则是固定的16进制数:475B3260,即为2进制的:1000111010110110011001001100000,将两者先做加法运算,得到第一个字符
    串STR1;再做乘法运算,得到第二个字符串STR2;然后将Email和注册名连接运算后的结果再次加上16进制数$80000000,然后减去16进制数
    $475B3260,再和16进制数$7FFFFFFF作与(and)运算,其结果转化为字符串后,即为第三个字符串STR3;将三个字符串连接起来后,再以
    字符串'56832'作key,进行大数乘法运算,得到新的结果后,取该结果前面的32位字符,即成为最终注册码的第一部分;
   
    接着,将机器码转化为实数,乘以 3.000000 后,加上 521725.0 后,取该结果的前8位字符,然后再次将该结果转化为实数,乘以 321.00
    00 后,加上 9614516412.0000000000 后,再减去 96145164.000000000000 之后,转换为字符串便得到了最终注册码的第二部分;
   
   
   
    将上面的一、二部分连接后,便得到了一个长字符串;将该字符串再次输入到CrackMe的注册码编辑框中,这是被断在了Edit4编辑框被改
    变的事件处,通过对其分析,发现其前部分几乎和Button1按钮点击事件的代码雷同,而不同的仅是如下的代码:
   
    》》》》》》
    004754C3   . /74 05            je      short Cra.004754CA
    004754C5   .^|75 F8            jnz   short Cra.004754BF
    004754C7   > |51               push    ecx
    004754C8   .^|EB F1            jmp   short Cra.004754BB
    004754CA   > \8B45 BC            mov   eax, dword ptr          ;被MD5加密的真正的注册码 前8位
    004754CD   .8B55 AC            mov   edx, dword ptr          ;被MD5加密的输入的注册码 前8位
    004754D0   .E8 03F4F8FF      call    Cra.004048D8               ;比较
    004754D5      75 7B            jnz   short Cra.00475552         ;相等,则不跳
    004754D7   .8B45 B8            mov   eax, dword ptr          ;被MD5加密的真正的注册码9~16位
    004754DA   .8B55 A8            mov   edx, dword ptr          ;被MD5加密的输入的注册码9~16位
    004754DD   .E8 F6F3F8FF      call    Cra.004048D8               ;比较
    004754E2      75 6E            jnz   short Cra.00475552         ;相等,则不跳
    004754E4   .8B45 B4            mov   eax, dword ptr          ;被MD5加密的真正的注册码 其余剩下的
    004754E7   .8B55 A4            mov   edx, dword ptr          ;被MD5加密的输入的注册码 其余剩下的
    004754EA   .E8 E9F3F8FF      call    Cra.004048D8               ;比较
    004754EF      75 61            jnz   short Cra.00475552         ;相等,则不跳
    004754F1   .8B45 A0            mov   eax, dword ptr
    004754F4   .BA 44564700      mov   edx, Cra.00475644          ;'PYG2007'
    004754F9   .E8 DAF3F8FF      call    Cra.004048D8               ;比较
    004754FE      75 12            jnz   short Cra.00475512         ;相等,则不跳
    00475500   .8B45 FC            mov   eax, dword ptr
    00475503   .8B80 34030000      mov   eax, dword ptr       ;Timer1 : TTimer
    00475509   .B2 01            mov   dl, 1
    0047550B   .E8 B444FBFF      call    Cra.004299C4               ;ExtCtrls.TTimer.SetEnabled(TTimer;Boolean);
    00475510   .EB 40            jmp   short Cra.00475552         ;成功!! 跳向光明之颠!!
    00475512   >8B45 FC            mov   eax, dword ptr
    》》》》》》
   
   
    发现上面的代码要检查注册码的最后是否有‘PYG2007’这个字符串,将其加上后,呵呵,注册成功了哟!飞向光明之颠!!
   
   
    通过对上面的分析后,写出了该CrackMe的易语言相关算法代码如下:(已经写成为一个函数,方便你的调用,嘿嘿)


    .支持库 eCalc
   
    .子程序 相关注册算法, 文本型, , PYG_CrackMe 2007 的注册算法
    .参数 Email, 文本型
    .局部变量 i, 整数型, , , integer
    .局部变量 x, 整数型, , , integer
    .局部变量 EmailKey1, 整数型, , , integer
    .局部变量 EmailKey2, 整数型, , , integer
    .局部变量 tempSTR, 文本型, , , string
    .局部变量 KeyStr1, 文本型, , , string
    .局部变量 KeyStr2, 文本型, , , string
    .局部变量 KeyStr3, 文本型, , , string
    .局部变量 KeyStrA, 文本型, , , string
    .局部变量 KeyStrB, 文本型, , , string
    .局部变量 KeyStr, 文本型, , , string
    .局部变量 tempFG1, 大数, , , 大数运算的变量
    .局部变量 tempFG2, 大数, , , 大数运算的变量
    .局部变量 FGIntKey, 大数, , , 大数运算的变量
    .局部变量 tempMAC, 双精度小数型, , , real
   
    .判断开始 (编辑框name.内容 = “”)
      返回 (“请输入你的大名,呵呵 ;)”)
    .判断 (取文本长度 (编辑框name.内容) > 16)
      返回 (“注册名长度不能超过16位字符 ;)”)
    .判断 (编辑框email.内容 = “”)' 是否输入了电子邮件
      返回 (“请输入你的电邮,呵呵 ;)”)
    .判断 (寻找文本 (编辑框email.内容, “@”, 1, 真) = -1)
      返回 (“电邮中没有 @ 符号 ;)”)
    .判断 (寻找文本 (编辑框email.内容, “.”, 1, 真) = -1)
      返回 (“电邮中没有 . 符号 ;)”)
    .默认
   
      EmailKey1 = 0
      .计次循环首 (取文本长度 (Email), x)
            i = 取代码 (取文本中间 (Email, x, 1), ) + 15
            i = 位异或 (i, 32)
            EmailKey1 = EmailKey1 + i
      .计次循环尾 ()
      tempSTR = 到文本 (EmailKey1) + 编辑框name.内容
   
      EmailKey2 = 取代码 (取文本中间 (tempSTR, 1, 1), ) + 544567129
      EmailKey2 = 位与 (EmailKey2, 255)
      EmailKey2 = EmailKey2 + EmailKey1
   
      .如果真 (取文本长度 (tempSTR) > 1)
            .计次循环首 (取文本长度 (tempSTR) - 1, x)
                x = x + 1' 从第2次开始,x初始值为1
                i = 取代码 (取文本中间 (tempSTR, x, 1), ) + 544567129
                i = 位与 (i, 255)
                EmailKey2 = EmailKey2 + i
            .计次循环尾 ()
      .如果真结束
   
      EmailKey2 = 左移 (EmailKey2, 10)
      EmailKey2 = EmailKey2 + 1702260588
   
      tempSTR = 到文本 (EmailKey2)
   
      KeyStr1 = 大数运算_加 (tempSTR, “1197159008”) ' 十进制数: 1197159008 即为十六进制数: 475B3260
   
      KeyStr2 = 大数运算_乘 (tempSTR, “1197159008”)
   
      EmailKey2 = EmailKey2 + 2147483648 - 1197159008
      EmailKey2 = 位与 (EmailKey2, 2147483647)
      KeyStr3 = 到文本 (EmailKey2)
   
      KeyStrA = KeyStr1 + KeyStr2 + KeyStr3
      KeyStrB = “56832”
      KeyStr = 大数运算_乘 (KeyStrA, KeyStrB)
      KeyStr = 取文本左边 (KeyStr, 32)' 最终注册码的第一部分
   
      tempMAC = 到数值 (编辑框id.内容)
      tempMAC = tempMAC × 3
      tempMAC = tempMAC + 521725
      tempSTR = 取文本左边 (到文本 (tempMAC), 8)
      tempMAC = 到数值 (tempSTR)
      tempMAC = tempMAC × 321
      tempMAC = tempMAC + 9614516412
      tempMAC = tempMAC - 96145164
      tempSTR = 到文本 (tempMAC)' 最终注册码的第二部分
   
      KeyStr = KeyStr + tempSTR + “PYG2007”' 连接一/二/三部分
   
      生成KEY文件 ()
   
      返回 (KeyStr)
   
   
   
    最后,再在计算按钮中添加如下代码,即可:
   
    .子程序 _计算按钮_被单击, , , keygen计算代码
   
    编辑框code.内容 = 相关注册算法 (编辑框email.内容)
   
   
   
    好的,就到这里结束吧!在我的附件中放有:PYG官方的'CrackMe2007.EXE'原版CrackMe程序以及我写的注册机'注册机(易语言版)
    .exe'供参考,分析难免有不当之处,还请给我指出来!
   

--------------------------------------------------------------------------------
【版权声明】: 本文由 aCaFeeL 原创, 转载请注明作者并保持文章的完整性, 谢谢! 再见!!

tianxj 发表于 2008-1-4 09:05:34

放上附件


[ 本帖最后由 tianxj 于 2008-1-5 10:09 编辑 ]

clh1979cmh 发表于 2008-1-4 14:41:00

可民惜俺没有这币呀

vecri 发表于 2008-1-4 14:43:24

斑竹不厚道了吧..这个还要收钱..~~/:L 可怜我们这些穷人..

tianxj 发表于 2008-1-5 06:40:55

连一个币也没有?晕了/:L

allcam 发表于 2008-1-5 07:46:27

/:014 都分析完了还说弄不了/:002

darling995 发表于 2008-1-5 09:22:07

老大这就别收费了,穷呀/:011

云飘飘 发表于 2008-1-11 13:25:57

向高手学习!
/:014

lovelin 发表于 2008-1-29 13:46:33

努力学习中^o^/:014

ZHOU2X 发表于 2008-2-12 11:44:08

PYGcrackMe2007(完整).rar 里的源码的解压密码是什么?/:L
页: [1] 2
查看完整版本: 2007年度认证CrackMe的算法分析(易语言版)