首页
社区
课程
招聘
加密与解密随书光盘习题GC Crackme 9和GC Crackme 10破解体会
2006-4-20 19:47 6511

加密与解密随书光盘习题GC Crackme 9和GC Crackme 10破解体会

2006-4-20 19:47
6511
【软件名称】《加密与解密》随书光盘习题GC Crackme 9GC Crackme 9和GC Crackme 10
【应用平台】Win2000
【软件大小】86.0KB和130KB
【软件限制】Serial以及Name/Serial/Unlock Code
【破解声明】该文主要是讲解穷举法在写注册机中的具体应用,适合我这样的菜鸟
【破解工具】OD
【分析过程】

一《加密与解密》随书光盘习题GC Crackme 9GC Crackme 9破解及注册机的详细过程
1 用PEID查看,UPX 0.89.6 - 1.02 / 1.05 - 1.22 (Delphi) stub -> Markus & Lazlo发现加壳,手动脱壳后,发现程序是DELPHI的,本想用DEDE,结果Procedure中什么也看不到,很不爽了。

2 用OD加载脱壳后的程序,通过搜索字符串,发现下面的关键代码:

00427BB2  |.  68 EC7B4200   PUSH Crackme9.00427BEC              ; |Title = "Success"
00427BB7  |.  68 F47B4200   PUSH Crackme9.00427BF4              ; |Text = "Serial Correct!"
00427BBC  |.  6A 00         PUSH 0                              ; |hOwner = NULL
00427BBE  |.  E8 45D9FDFF   CALL <JMP.&USER32.MessageBoxA>      ; \MessageBoxA

向上查看程序,决定在42B748处下断点,点击“check”按钮,果然,中断在此,断点找到,大功告成1/3了。
00427B48  /.  55            PUSH EBP
00427B49  |.  8BEC          MOV EBP,ESP
00427B4B  |.  6A 00         PUSH 0
00427B4D  |.  53            PUSH EBX
00427B4E  |.  8BD8          MOV EBX,EAX
00427B50  |.  33C0          XOR EAX,EAX
00427B52  |.  55            PUSH EBP
00427B53  |.  68 E07B4200   PUSH Crackme9.00427BE0
00427B58  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
00427B5B  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
00427B5E  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
00427B61  |.  8B83 E0010000 MOV EAX,DWORD PTR DS:[EBX+1E0]
00427B67  |.  E8 9CE2FEFF   CALL Crackme9.00415E08
00427B6C  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]        ;  取Serial
00427B6F  |.  E8 B0E8FDFF   CALL Crackme9.00406424
00427B74  |.  A3 60974200   MOV DWORD PTR DS:[429760],EAX       ;  429760中存放Serial的Hex
00427B79  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
00427B7C  |.  8B83 E0010000 MOV EAX,DWORD PTR DS:[EBX+1E0]
00427B82  |.  E8 81E2FEFF   CALL Crackme9.00415E08
00427B87  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
00427B8A  |.  E8 19BCFDFF   CALL Crackme9.004037A8
00427B8F  |.  A2 64974200   MOV BYTE PTR DS:[429764],AL
00427B94  |.  803D 64974200>CMP BYTE PTR DS:[429764],5          ;  Serial长度必须为5
00427B9B  |.  75 2D         JNZ SHORT Crackme9.00427BCA
00427B9D  |.  A1 60974200   MOV EAX,DWORD PTR DS:[429760]       ;  Serial的Hex
00427BA2  |.  E8 11FFFFFF   CALL Crackme9.00427AB8              ;  判断是否正确的注册码的函数
00427BA7  |.  803D 65974200>CMP BYTE PTR DS:[429765],0
00427BAE  |.  75 1A         JNZ SHORT Crackme9.00427BCA         ;  关键跳转
00427BB0  |.  6A 00         PUSH 0                              ; /Style = MB_OK|MB_APPLMODAL
00427BB2  |.  68 EC7B4200   PUSH Crackme9.00427BEC              ; |Title = "Success"
00427BB7  |.  68 F47B4200   PUSH Crackme9.00427BF4              ; |Text = "Serial Correct!"
00427BBC  |.  6A 00         PUSH 0                              ; |hOwner = NULL
00427BBE  |.  E8 45D9FDFF   CALL <JMP.&USER32.MessageBoxA>      ; \MessageBoxA
00427BC3  |.  C605 65974200>MOV BYTE PTR DS:[429765],1
00427BCA  |>  33C0          XOR EAX,EAX
00427BCC  |.  5A            POP EDX
00427BCD  |.  59            POP ECX
00427BCE  |.  59            POP ECX
00427BCF  |.  64:8910       MOV DWORD PTR FS:[EAX],EDX
00427BD2  |.  68 E77B4200   PUSH Crackme9.00427BE7
00427BD7  |>  8D45 FC       LEA EAX,DWORD PTR SS:[EBP-4]
00427BDA  |.  E8 4DB9FDFF   CALL Crackme9.0040352C
00427BDF  \.  C3            RETN

其中CALL Crackme9.00427AB8              ;  判断是否正确的注册码的函数如下
00427AB8  /$  53            PUSH EBX
00427AB9  |.  56            PUSH ESI
00427ABA  |.  57            PUSH EDI
00427ABB  |.  51            PUSH ECX
00427ABC  |.  8BD8          MOV EBX,EAX
00427ABE  |.  BE 54974200   MOV ESI,Crackme9.00429754
00427AC3  |.  E8 C0FFFFFF   CALL Crackme9.00427A88              ;  设置比较对象的值
00427AC8  |.  C605 65974200>MOV BYTE PTR DS:[429765],1
00427ACF  |.  C60424 01     MOV BYTE PTR SS:[ESP],1
00427AD3  |.  83FB 03       CMP EBX,3
00427AD6  |.  7C 2F         JL SHORT Crackme9.00427B07
00427AD8  |>  8BC3          /MOV EAX,EBX
00427ADA  |.  BF 03000000   |MOV EDI,3
00427ADF  |.  99            |CDQ
00427AE0  |.  F7FF          |IDIV EDI                           ;  Serial/3
00427AE2  |.  33C9          |XOR ECX,ECX
00427AE4  |.  8A0C24        |MOV CL,BYTE PTR SS:[ESP]
00427AE7  |.  88540E FF     |MOV BYTE PTR DS:[ESI+ECX-1],DL     ;  DL为余数,将其存放到429754单元中
00427AEB  |.  8BC3          |MOV EAX,EBX
00427AED  |.  BB 03000000   |MOV EBX,3
00427AF2  |.  99            |CDQ
00427AF3  |.  F7FB          |IDIV EBX
00427AF5  |.  8BD8          |MOV EBX,EAX                        ;  商
00427AF7  |.  83FB 03       |CMP EBX,3
00427AFA  |.  7D 03         |JGE SHORT Crackme9.00427AFF
00427AFC  |.  881C0E        |MOV BYTE PTR DS:[ESI+ECX],BL
00427AFF  |>  FE0424        |INC BYTE PTR SS:[ESP]
00427B02  |.  83FB 03       |CMP EBX,3
00427B05  |.^ 7D D1         \JGE SHORT Crackme9.00427AD8
00427B07  |>  8A0C24        MOV CL,BYTE PTR SS:[ESP]
00427B0A  |.  80F9 01       CMP CL,1
00427B0D  |.  72 31         JB SHORT Crackme9.00427B40
00427B0F  |.  33C0          XOR EAX,EAX
00427B11  |.  8AC1          MOV AL,CL
00427B13  |.  8D4406 FF     LEA EAX,DWORD PTR DS:[ESI+EAX-1]
00427B17  |.  33D2          XOR EDX,EDX
00427B19  |.  8AD1          MOV DL,CL
00427B1B  |.  81C2 47974200 ADD EDX,Crackme9.00429747
00427B21  |>  8A1A          /MOV BL,BYTE PTR DS:[EDX]
00427B23  |.  3A18          |CMP BL,BYTE PTR DS:[EAX]
00427B25  |.  75 09         |JNZ SHORT Crackme9.00427B30
00427B27  |.  C605 65974200>|MOV BYTE PTR DS:[429765],0
00427B2E  |.  EB 09         |JMP SHORT Crackme9.00427B39
00427B30  |>  C605 65974200>|MOV BYTE PTR DS:[429765],1         ;  429765为1就注册不正确
00427B37  |.  EB 07         |JMP SHORT Crackme9.00427B40
00427B39  |>  49            |DEC ECX
00427B3A  |.  4A            |DEC EDX
00427B3B  |.  48            |DEC EAX
00427B3C  |.  84C9          |TEST CL,CL
00427B3E  |.^ 75 E1         \JNZ SHORT Crackme9.00427B21
00427B40  |>  5A            POP EDX
00427B41  |.  5F            POP EDI
00427B42  |.  5E            POP ESI
00427B43  |.  5B            POP EBX
00427B44  \.  C3            RETN

如果用手计算估计你和我一样都想爆破算了。如今电脑配置都这么好,不能浪费了,让它去算吧。穷举一下了。

根据上面的程序很容易得到C语言的注册机:
#include "stdio.h"

void main()
{
        int a[10]={2,0,2,0,1,2,2,1,0,2};
        int b[10];
        int sn,sn1;
        int length;
        int i;
        int flag=0;
        for(sn=3;sn<99999;sn++)
        {
                sn1=sn;
                i=0;
                b[i++]=sn1%3;
                sn1=sn1/3;
                while(sn1>=3)
                {
                        b[i++]=sn1%3;
                        sn1=sn1/3;
                }
                b[i]=sn1;
                length=i+1;
                flag=0;
                for(i=0;i<length;i++)
                {
                        if(a[i]==b[i])
                                flag=1;
                        else
                        {
                                flag=0;
                                break;
                        }
                }
                if(flag)
                        printf("The %.5d is the correct serial\n",sn);
                       
        }
}

二《加密与解密》随书光盘习题GC Crackme 9GC Crackme 10破解及注册机的详细过程

1 用PEID查看发现UPX 0.89.6 - 1.02 / 1.05 - 1.22 -> Markus & Lazlo加壳,用OD手动脱壳。
2 用OD搜索字符串并未发现什么有用的信息,但是用WinDasm搜索字符串发现下面重要信息,心里那个高兴啊!。。。。。。

:0042D630 C60511F7420000          mov byte ptr [0042F711], 00
:0042D637 C60512F7420000          mov byte ptr [0042F712], 00
:0042D63E E8ADFDFFFF              call 0042D3F0
:0042D643 803D10F7420000          cmp byte ptr [0042F710], 00
:0042D64A 752F                    jne 0042D67B
:0042D64C E867FEFFFF              call 0042D4B8
:0042D651 803D11F7420001          cmp byte ptr [0042F711], 01
:0042D658 7521                    jne 0042D67B
:0042D65A E8F5FEFFFF              call 0042D554
:0042D65F 803D12F7420001          cmp byte ptr [0042F712], 01
:0042D666 7513                    jne 0042D67B
:0042D668 6A00                    push 00000000
:0042D66A 687CD64200              push 0042D67C

* Possible StringData Ref from Data Obj ->"Good work cracker!"
                                  |
:0042D66F 6888D64200              push 0042D688
:0042D674 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01C4h
在0042D630下断点。
0042D630    C605 11F74200 0>MOV BYTE PTR DS:[42F711],0     ; 42F711标志置位0
0042D637    C605 12F74200 0>MOV BYTE PTR DS:[42F712],0     ; 42F712标志置位0
0042D63E    E8 ADFDFFFF     CALL GNCRK10_.0042D3F0         ; 检查输入是否合法
0042D643    803D 10F74200 0>CMP BYTE PTR DS:[42F710],0
0042D64A    75 2F           JNZ SHORT GNCRK10_.0042D67B
0042D64C    E8 67FEFFFF     CALL GNCRK10_.0042D4B8         ; 检查Unlock Code是否正确
0042D651    803D 11F74200 0>CMP BYTE PTR DS:[42F711],1
0042D658    75 21           JNZ SHORT GNCRK10_.0042D67B
0042D65A    E8 F5FEFFFF     CALL GNCRK10_.0042D554         ; 检查Serial是否正确
0042D65F    803D 12F74200 0>CMP BYTE PTR DS:[42F712],1
0042D666    75 13           JNZ SHORT GNCRK10_.0042D67B
0042D668    6A 00           PUSH 0
0042D66A    68 7CD64200     PUSH GNCRK10_.0042D67C         ; ASCII "Success!"
0042D66F    68 88D64200     PUSH GNCRK10_.0042D688         ; ASCII "Good work cracker!"
0042D674    6A 00           PUSH 0
0042D676    E8 817FFDFF     CALL <JMP.&USER32.MessageBoxA>
0042D67B    C3              RETN
其中CALL GNCRK10_.0042D3F0         ; 检查输入是否合法函数如下:

0042D3F0    55              PUSH EBP
0042D3F1    8BEC            MOV EBP,ESP
0042D3F3    6A 00           PUSH 0
0042D3F5    6A 00           PUSH 0
0042D3F7    33C0            XOR EAX,EAX
0042D3F9    55              PUSH EBP
0042D3FA    68 ABD44200     PUSH GNCRK10_.0042D4AB
0042D3FF    64:FF30         PUSH DWORD PTR FS:[EAX]
0042D402    64:8920         MOV DWORD PTR FS:[EAX],ESP
0042D405    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
0042D408    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D40D    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
0042D413    E8 64CAFEFF     CALL GNCRK10_.00419E7C
0042D418    837D FC 00      CMP DWORD PTR SS:[EBP-4],0     ; 用户名不能为空
0042D41C    74 20           JE SHORT GNCRK10_.0042D43E
0042D41E    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
0042D421    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D426    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
0042D42C    E8 4BCAFEFF     CALL GNCRK10_.00419E7C
0042D431    8B45 F8         MOV EAX,DWORD PTR SS:[EBP-8]
0042D434    E8 8763FDFF     CALL GNCRK10_.004037C0
0042D439    83F8 05         CMP EAX,5                      ; 取用户名长度,长度必须大于等于5
0042D43C    7D 09           JGE SHORT GNCRK10_.0042D447
0042D43E    C605 10F74200 0>MOV BYTE PTR DS:[42F710],1     ; 42F710位用户名以及Unlock Code是否合法的标志位
0042D445    EB 07           JMP SHORT GNCRK10_.0042D44E
0042D447    C605 10F74200 0>MOV BYTE PTR DS:[42F710],0
0042D44E    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
0042D451    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D456    8B80 EC010000   MOV EAX,DWORD PTR DS:[EAX+1EC]
0042D45C    E8 1BCAFEFF     CALL GNCRK10_.00419E7C
0042D461    837D FC 00      CMP DWORD PTR SS:[EBP-4],0     ; 0xCE967C取得Serial,不能为空
0042D465    74 19           JE SHORT GNCRK10_.0042D480
0042D467    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
0042D46A    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D46F    8B80 F0010000   MOV EAX,DWORD PTR DS:[EAX+1F0]
0042D475    E8 02CAFEFF     CALL GNCRK10_.00419E7C
0042D47A    837D F8 00      CMP DWORD PTR SS:[EBP-8],0     ; 0xCE968C取得Unlock Code,不能为空
0042D47E    75 09           JNZ SHORT GNCRK10_.0042D489
0042D480    C605 10F74200 0>MOV BYTE PTR DS:[42F710],1
0042D487    EB 07           JMP SHORT GNCRK10_.0042D490
0042D489    C605 10F74200 0>MOV BYTE PTR DS:[42F710],0
0042D490    33C0            XOR EAX,EAX
0042D492    5A              POP EDX
0042D493    59              POP ECX
0042D494    59              POP ECX
0042D495    64:8910         MOV DWORD PTR FS:[EAX],EDX
0042D498    68 B2D44200     PUSH GNCRK10_.0042D4B2
0042D49D    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
0042D4A0    BA 02000000     MOV EDX,2
0042D4A5    E8 BE60FDFF     CALL GNCRK10_.00403568
0042D4AA    C3              RETN
0042D4AB  ^\E9 385BFDFF     JMP GNCRK10_.00402FE8
0042D4B0  ^ EB EB           JMP SHORT GNCRK10_.0042D49D
0042D4B2    59              POP ECX
0042D4B3    59              POP ECX
0042D4B4    5D              POP EBP
0042D4B5    C3              RETN

其中CALL GNCRK10_.0042D4B8         ; 检查Unlock Code是否正确函数如下:
0042D4B8    55              PUSH EBP
0042D4B9    8BEC            MOV EBP,ESP
0042D4BB    6A 00           PUSH 0
0042D4BD    53              PUSH EBX
0042D4BE    33C0            XOR EAX,EAX
0042D4C0    55              PUSH EBP
0042D4C1    68 46D54200     PUSH GNCRK10_.0042D546
0042D4C6    64:FF30         PUSH DWORD PTR FS:[EAX]
0042D4C9    64:8920         MOV DWORD PTR FS:[EAX],ESP
0042D4CC    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
0042D4CF    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D4D4    8B80 F0010000   MOV EAX,DWORD PTR DS:[EAX+1F0]
0042D4DA    E8 9DC9FEFF     CALL GNCRK10_.00419E7C
0042D4DF    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]   ; 取得Unlock Code
0042D4E2    E8 5991FDFF     CALL GNCRK10_.00406640         ; 计算Unlock Code的Hex
0042D4E7    8BD8            MOV EBX,EAX
0042D4E9    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
0042D4EC    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D4F1    8B80 F0010000   MOV EAX,DWORD PTR DS:[EAX+1F0]
0042D4F7    E8 80C9FEFF     CALL GNCRK10_.00419E7C
0042D4FC    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]   ; 取得Unlock Code
0042D4FF    E8 BC62FDFF     CALL GNCRK10_.004037C0         ; 取Unlock Code的长度
0042D504    84C0            TEST AL,AL
0042D506    76 10           JBE SHORT GNCRK10_.0042D518
0042D508    81F3 865E0100   XOR EBX,15E86                  ; Unlock Code的Hex异或0x15E86
0042D50E    81E3 F01E0100   AND EBX,11EF0                  ; Unlock Code的Hex与0x11EF0
0042D514    FEC8            DEC AL
0042D516  ^ 75 F0           JNZ SHORT GNCRK10_.0042D508    ; Unlock Code的长度循环次数
0042D518    81FB E00A0100   CMP EBX,10AE0                  ; 结果必须与0x10AE0相等,否则非法.
0042D51E    75 09           JNZ SHORT GNCRK10_.0042D529
0042D520    C605 11F74200 0>MOV BYTE PTR DS:[42F711],1     ; 置Unlock Code合法标志位
0042D527    EB 07           JMP SHORT GNCRK10_.0042D530
0042D529    C605 11F74200 0>MOV BYTE PTR DS:[42F711],0     ; 置Unlock Code不合法标志位
0042D530    33C0            XOR EAX,EAX
0042D532    5A              POP EDX
0042D533    59              POP ECX
0042D534    59              POP ECX
0042D535    64:8910         MOV DWORD PTR FS:[EAX],EDX
0042D538    68 4DD54200     PUSH GNCRK10_.0042D54D
0042D53D    8D45 FC         LEA EAX,DWORD PTR SS:[EBP-4]
0042D540    E8 FF5FFDFF     CALL GNCRK10_.00403544
0042D545    C3              RETN
0042D546  ^ E9 9D5AFDFF     JMP GNCRK10_.00402FE8
0042D54B  ^ EB F0           JMP SHORT GNCRK10_.0042D53D
0042D54D    5B              POP EBX
0042D54E    59              POP ECX
0042D54F    5D              POP EBP
0042D550    C3              RETN
计算正确Unlock Code的算法很简单,但要你一眼看出来估计也不是易事,我是菜鸟,差点就想爆破算了,但我还是忍了,决定一定要算出来了。参考了Cronos写的Tutorial,其中关于计算Unlock Code的说明如下:
“You can see the relevant parts of the above checking routine. This is all on the unlock code (string3 I called it at the time). It is obviously converted into a number and saved in ebx. We then get the length of it, loop around doing some maths and check it against an expected value before setting a flag.
There's actually an easy way to solve this problem and here is how. We loop based on the length of the number (call this unlock code X for now), and then check it against a 5 digit number, so let X have 5 digits, so we do 5 loops, ok. Now the problem is ((X xor 15e86) and 11ef0) etc etc = 10ae0. What do you notice about this ? Well for a start one digit in X has no effect on any others. Take the last digit of X. It is anded with 0 right ? On each iteration, so it will always be 0 at the end. So the last digit of X can be anything, we'll call it 0. You can actually solve the whole problem digit by digit. Or you could solve it bit by bit.....so this isnt so hard. The final code ? I used 1460h, or 5216 decimal. Ah but that has only 4 digits.......ok, input 05216......happy now ?

但这种办法需要你详细的用手计算了,如果你的数学功底不好的话,又不够细心,估计你看得都晕了。想如今电脑配置都这么好,不能浪费了,让它去算吧。穷举一下了。

根据上面算法,我们以5位数的Unlock Code计算为例说明,其求解正确的Unlock Code程序如下:
void computeUnlockCode()
{
        int c[5];//说明c[5]代表穷举Unlock Code的Hex值的各位
        int d[5];
        int i,j;
        long temp;
        //c[0]代表Code的最高位,c[4]代表最低位。
        //说明以5位Unlock Code为例说明,十进制的99999=0x1869F,所以我们只取c[0]=0,1,如果计算出来的
        for(c[0]=0;c[0]<=0x1;c[0]++)
                for(c[1]=0;c[1]<=0xF;c[1]++)
                        for(c[2]=0;c[2]<=0xF;c[2]++)
                                for(c[3]=0;c[3]<=0xF;c[3]++)
                                        for(c[4]=0;c[4]<=0xF;c[4]++)
                                        {
                                                d[0]=c[0];
                                                d[1]=c[1];
                                                d[2]=c[2];
                                                d[3]=c[3];
                                                d[4]=c[4];
                                                for(i=0;i<5;i++)
                                                {       
                                                        d[0]=d[0]^0x1;
                                                        d[0]=d[0]&0x1;
                                                        d[1]=d[1]^0x5;
                                                        d[1]=d[1]&0x1;
                                                        d[2]=d[2]^0xE;
                                                        d[2]=d[2]&0xE;
                                                        d[3]=d[3]^0x8;
                                                        d[3]=d[3]&0xF;
                                                        d[4]=d[4]^0x6;
                                                        d[4]=d[4]&0x0;
                                                }
                                                if(d[0]==0x1 && d[1]==0 && d[2]==0xA && d[3]==0xE && d[4]==0)
                                                        printf("The 0x%X%X%X%X%X is the correct unlock code\n",c[0],c[1],c[2],c[3],c[4]);
                                        }
                                       
}

其中CALL GNCRK10_.0042D554         ; 检查Serial是否正确函数如下:
0042D554    55              PUSH EBP
0042D555    8BEC            MOV EBP,ESP
0042D557    83C4 F8         ADD ESP,-8
0042D55A    53              PUSH EBX
0042D55B    56              PUSH ESI
0042D55C    57              PUSH EDI
0042D55D    33C0            XOR EAX,EAX
0042D55F    8945 F8         MOV DWORD PTR SS:[EBP-8],EAX
0042D562    33C0            XOR EAX,EAX
0042D564    55              PUSH EBP
0042D565    68 22D64200     PUSH GNCRK10_.0042D622
0042D56A    64:FF30         PUSH DWORD PTR FS:[EAX]
0042D56D    64:8920         MOV DWORD PTR FS:[EAX],ESP
0042D570    33DB            XOR EBX,EBX
0042D572    BF 1B990800     MOV EDI,8991B                       ; 给EDI设置初值
0042D577    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
0042D57A    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D57F    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
0042D585    E8 F2C8FEFF     CALL GNCRK10_.00419E7C
0042D58A    8B55 F8         MOV EDX,DWORD PTR SS:[EBP-8]        ; 用户名
0042D58D    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D592    8B08            MOV ECX,DWORD PTR DS:[EAX]
0042D594    FF51 18         CALL DWORD PTR DS:[ECX+18]
0042D597    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
0042D59A    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D59F    8B80 EC010000   MOV EAX,DWORD PTR DS:[EAX+1EC]
0042D5A5    E8 D2C8FEFF     CALL GNCRK10_.00419E7C
0042D5AA    8B45 F8         MOV EAX,DWORD PTR SS:[EBP-8]        ; 取Serial长度
0042D5AD    E8 8E90FDFF     CALL GNCRK10_.00406640
0042D5B2    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX        ; 取Serial得Hex
0042D5B5    EB 20           JMP SHORT GNCRK10_.0042D5D7
0042D5B7    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D5BC    8B40 08         MOV EAX,DWORD PTR DS:[EAX+8]
0042D5BF    0FB64430 FF     MOVZX EAX,BYTE PTR DS:[EAX+ESI-1]
0042D5C4    B9 05000000     MOV ECX,5
0042D5C9    99              CDQ
0042D5CA    F7F9            IDIV ECX
0042D5CC    69C2 5FFD0E00   IMUL EAX,EDX,0EFD5F                 ; 用户名字符除以5的余数
0042D5D2    33F8            XOR EDI,EAX
0042D5D4    80C3 02         ADD BL,2
0042D5D7    A1 0CF74200     MOV EAX,DWORD PTR DS:[42F70C]
0042D5DC    8B40 08         MOV EAX,DWORD PTR DS:[EAX+8]
0042D5DF    E8 DC61FDFF     CALL GNCRK10_.004037C0
0042D5E4    8BF3            MOV ESI,EBX
0042D5E6    81E6 FF000000   AND ESI,0FF
0042D5EC    3BC6            CMP EAX,ESI
0042D5EE  ^ 7D C7           JGE SHORT GNCRK10_.0042D5B7         ; 用户名长度的循环
0042D5F0    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]        ; Serial的Hex
0042D5F3    35 1B990800     XOR EAX,8991B                       ; Serial的Hex异或0x8991B
0042D5F8    3BF8            CMP EDI,EAX
0042D5FA    75 09           JNZ SHORT GNCRK10_.0042D605
0042D5FC    C605 12F74200 0>MOV BYTE PTR DS:[42F712],1
0042D603    EB 07           JMP SHORT GNCRK10_.0042D60C
0042D605    C605 12F74200 0>MOV BYTE PTR DS:[42F712],0
0042D60C    33C0            XOR EAX,EAX
0042D60E    5A              POP EDX
0042D60F    59              POP ECX
0042D610    59              POP ECX
0042D611    64:8910         MOV DWORD PTR FS:[EAX],EDX
0042D614    68 29D64200     PUSH GNCRK10_.0042D629
0042D619    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
0042D61C    E8 235FFDFF     CALL GNCRK10_.00403544
0042D621    C3              RETN
0042D622  ^ E9 C159FDFF     JMP GNCRK10_.00402FE8
0042D627  ^ EB F0           JMP SHORT GNCRK10_.0042D619
0042D629    5F              POP EDI
0042D62A    5E              POP ESI
0042D62B    5B              POP EBX
0042D62C    59              POP ECX
0042D62D    59              POP ECX
0042D62E    5D              POP EBP
0042D62F    C3              RETN

根据上面的程序很容易写出注册程序如下:

void main()
{
        char name[20];
        int  length;
        int  temp;
        int  temp1;
        int  ediTemp=0x8991B;
        int  sn,i;
        scanf("%s",name);
        if((length=strlen(name))<5)
        {
                printf("The user name should at least 5 length\n");
                return;
        }
        for(i=0;i<length;i++)
        {
                if(name[i]>=0x61 && name[i]<=0x7a)
                        name[i]-=0x20;
        }
        for(i=0;i<length/2;i++)
        {
                temp=name[2*i+1]%5;
                temp1=temp*0xEFD5F;
                ediTemp=temp1^ediTemp;
        }
        sn=ediTemp^0x8991B;
        printf("The Serial is %d",sn);
        computeUnlockCode();
}
【分析总结】要想得到所有正确的注册码,往往需要穷举了。为了给我这样的菜鸟一定的帮助,我拿《加密与解密》随书光盘习题GC Crackme 9GC Crackme 9和GC Crackme 10为例说明了。希望给菜鸟一定的帮助。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞7
打赏
分享
最新回复 (9)
雪    币: 32403
活跃值: (18850)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2006-4-20 20:32
2
0
文章很精彩
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ABCdiyPE 2006-4-20 21:24
3
0
支持一下!!!!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iBingz 2006-4-20 21:30
4
0

    终于可以发贴了,真不明白论坛为什么要在注册一天后才可以发帖!!!
                           
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
petnt 12 2006-4-21 18:24
5
0
感谢楼主!顶!
雪    币: 313
活跃值: (250)
能力值: ( LV9,RANK:650 )
在线值:
发帖
回帖
粉丝
hbqjxhw 16 2006-4-21 19:33
6
0
精彩,文章适合我等菜鸟学习
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
zhaoocn 7 2006-4-22 09:10
7
0
穷举法不错
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yujinjianx 2006-4-22 16:42
8
0
上传crackme
雪    币: 264
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
菩提! 2006-4-22 22:24
9
0
在加密过程中经常会使用异或运算,而该运算不是可逆的

这个也行?
lz有点水
雪    币: 264
活跃值: (327)
能力值: ( LV9,RANK:550 )
在线值:
发帖
回帖
粉丝
laowanghai 13 2006-4-23 18:05
10
0
最初由 菩提! 发布
这个也行?
lz有点水


我当时想表达的意思是,该运算结果反推原始数据不是唯一的
游客
登录 | 注册 方可回帖
返回