首页
社区
课程
招聘
《加密与解密》随书光盘习题GC Crackme 12写注册机经过
发表于: 2006-4-23 18:11 6125

《加密与解密》随书光盘习题GC Crackme 12写注册机经过

2006-4-23 18:11
6125

【软件名称】《加密与解密》随书光盘习题GC Crackme 12
【应用平台】Win2000
【软件大小】129 KB
【软件限制】Code, Name/Serial
【破解说明】为了求得正确的Code,我花了很长很长的时间(谁要我是菜鸟了!),我觉得写出我写出该程序的注册程序的过程能够对菜鸟有一定帮助,如果为了爆破,就不必看这篇文章了。我希望完整的描述菜鸟写注册程序的思路,给菜鸟们一定的帮助。
【破解工具】OD
【分析过程】

首先看了下作者的说明:his is a new crackme form Genocide Crew so prepare you brains for some work :) Ok, crackthere are two levels in this one.I tried to make them hard, but I am sure you can handle them  :)

Rules:

First level:
Just find the correct code.
Second level:
Serial is too easy. Write a keygen
to generate the correct serial.

For both levels you must write
tutorials with explanation how you
have done everything.
开工了......
1 用PEID查看UPX 0.89.6 - 1.02 / 1.05 - 1.22 (Delphi) stub -> Markus & Lazlo加壳,脱壳后查看是Delphi写的程序,用DEDE打开,没有发现任何有用的信息.

2 在OD中搜索字符串,定位到下面的代码.
0043083E    8BC0            MOV EAX,EAX
00430840    55              PUSH EBP
00430841    8BEC            MOV EBP,ESP
00430843    33C9            XOR ECX,ECX
00430845    51              PUSH ECX
00430846    51              PUSH ECX
00430847    51              PUSH ECX
00430848    51              PUSH ECX
00430849    51              PUSH ECX
0043084A    51              PUSH ECX
0043084B    51              PUSH ECX
0043084C    51              PUSH ECX
0043084D    53              PUSH EBX
0043084E    56              PUSH ESI
0043084F    57              PUSH EDI
00430850    8945 EC         MOV DWORD PTR SS:[EBP-14],EAX
00430853    33C0            XOR EAX,EAX
00430855    55              PUSH EBP
00430856    68 B4094300     PUSH GNCRK12_.004309B4
0043085B    64:FF30         PUSH DWORD PTR FS:[EAX]
0043085E    64:8920         MOV DWORD PTR FS:[EAX],ESP
00430861    33DB            XOR EBX,EBX
00430863    8D55 E8         LEA EDX,DWORD PTR SS:[EBP-18]
00430866    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
00430869    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
0043086F    E8 2899FEFF     CALL GNCRK12_.0041A19C
00430874    837D E8 00      CMP DWORD PTR SS:[EBP-18],0              ; Code不能为空
00430878    0F84 D9000000   JE GNCRK12_.00430957
0043087E    8D55 E4         LEA EDX,DWORD PTR SS:[EBP-1C]
00430881    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
00430884    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
0043088A    E8 0D99FEFF     CALL GNCRK12_.0041A19C
0043088F    8B45 E4         MOV EAX,DWORD PTR SS:[EBP-1C]
00430892    E8 752FFDFF     CALL GNCRK12_.0040380C
00430897    83F8 05         CMP EAX,5                                ; Code 长度不能小于5
0043089A    0F8C B7000000   JL GNCRK12_.00430957
004308A0    8D55 F4         LEA EDX,DWORD PTR SS:[EBP-C]
004308A3    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
004308A6    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
004308AC    E8 EB98FEFF     CALL GNCRK12_.0041A19C
004308B1    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
004308B4    E8 D72CFDFF     CALL GNCRK12_.00403590
004308B9    8D55 E8         LEA EDX,DWORD PTR SS:[EBP-18]
004308BC    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
004308BF    8B80 E8010000   MOV EAX,DWORD PTR DS:[EAX+1E8]
004308C5    E8 D298FEFF     CALL GNCRK12_.0041A19C
004308CA    8B45 E8         MOV EAX,DWORD PTR SS:[EBP-18]
004308CD    E8 3A2FFDFF     CALL GNCRK12_.0040380C
004308D2    8BF0            MOV ESI,EAX
004308D4    8BFE            MOV EDI,ESI
004308D6    85FF            TEST EDI,EDI
004308D8    7E 35           JLE SHORT GNCRK12_.0043090F
004308DA    BB 01000000     MOV EBX,1
004308DF    8BC6            MOV EAX,ESI
004308E1    2BC3            SUB EAX,EBX
004308E3    8B55 F4         MOV EDX,DWORD PTR SS:[EBP-C]
004308E6    8A4402 FF       MOV AL,BYTE PTR DS:[EDX+EAX-1]
004308EA    8B55 F4         MOV EDX,DWORD PTR SS:[EBP-C]
004308ED    8A541A FF       MOV DL,BYTE PTR DS:[EDX+EBX-1]
004308F1    32C2            XOR AL,DL
004308F3    25 FF000000     AND EAX,0FF
004308F8    8D55 E0         LEA EDX,DWORD PTR SS:[EBP-20]
004308FB    E8 8C5DFDFF     CALL GNCRK12_.0040668C
00430900    8B55 E0         MOV EDX,DWORD PTR SS:[EBP-20]
00430903    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
00430906    E8 092FFDFF     CALL GNCRK12_.00403814
0043090B    43              INC EBX
0043090C    4F              DEC EDI
0043090D  ^ 75 D0           JNZ SHORT GNCRK12_.004308DF              ; 上面循环代码都是对Code进行处理,生成Data1数据.
0043090F    33C0            XOR EAX,EAX
00430911    BB 01000000     MOV EBX,1
00430916    3BF3            CMP ESI,EBX
00430918    7C 11           JL SHORT GNCRK12_.0043092B
0043091A    8B55 F0         MOV EDX,DWORD PTR SS:[EBP-10]
0043091D    0FB6541A FF     MOVZX EDX,BYTE PTR DS:[EDX+EBX-1]
00430922    03C2            ADD EAX,EDX
00430924    83C3 02         ADD EBX,2
00430927    3BF3            CMP ESI,EBX
00430929  ^ 7D EF           JGE SHORT GNCRK12_.0043091A              
0043092B    3D F7000000     CMP EAX,0F7                                     ; 对Data1进行数学处理,判断是否与0xF7相等
00430930    74 04           JE SHORT GNCRK12_.00430936               ; 不相等,就认为是错误的Code
00430932    33DB            XOR EBX,EBX
00430934    EB 21           JMP SHORT GNCRK12_.00430957
00430936    55              PUSH EBP
00430937    E8 74FCFFFF     CALL GNCRK12_.004305B0                   ; 对字符串"4401201204455"进行处理
0043093C    59              POP ECX
0043093D    55              PUSH EBP
0043093E    E8 B9FDFFFF     CALL GNCRK12_.004306FC                   ; 对Data1进行处理,生成Data2数据
00430943    59              POP ECX
00430944    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]             ; 对字符串"4401201204455"进行处理的结果为"56602124021"
00430947    8B55 F4         MOV EDX,DWORD PTR SS:[EBP-C]             ; 对Data1进行处理,得到的Data2数据
0043094A    E8 CD2FFDFF     CALL GNCRK12_.0040391C                   ; 判断Data2与"56602124021"是否相等
0043094F    75 04           JNZ SHORT GNCRK12_.00430955              ; 关键跳转,相等则认为Good Code,否则认为是Wrong Code
00430951    B3 01           MOV BL,1
00430953    EB 02           JMP SHORT GNCRK12_.00430957
00430955    33DB            XOR EBX,EBX
00430957    80FB 01         CMP BL,1
0043095A    75 15           JNZ SHORT GNCRK12_.00430971
0043095C    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
0043095F    8B80 F8010000   MOV EAX,DWORD PTR DS:[EAX+1F8]
00430965    BA CC094300     MOV EDX,GNCRK12_.004309CC                ; ASCII "Good Code"
0043096A    E8 5D98FEFF     CALL GNCRK12_.0041A1CC
0043096F    EB 13           JMP SHORT GNCRK12_.00430984
00430971    8B45 EC         MOV EAX,DWORD PTR SS:[EBP-14]
00430974    8B80 F8010000   MOV EAX,DWORD PTR DS:[EAX+1F8]
0043097A    BA E0094300     MOV EDX,GNCRK12_.004309E0                ; ASCII "Wrong Code"
0043097F    E8 4898FEFF     CALL GNCRK12_.0041A1CC
00430984    33C0            XOR EAX,EAX
00430986    5A              POP EDX
00430987    59              POP ECX
00430988    59              POP ECX
00430989    64:8910         MOV DWORD PTR FS:[EAX],EDX
0043098C    68 BB094300     PUSH GNCRK12_.004309BB
00430991    8D45 E0         LEA EAX,DWORD PTR SS:[EBP-20]
00430994    E8 F72BFDFF     CALL GNCRK12_.00403590
00430999    8D45 E4         LEA EAX,DWORD PTR SS:[EBP-1C]
0043099C    BA 02000000     MOV EDX,2
004309A1    E8 0E2CFDFF     CALL GNCRK12_.004035B4
004309A6    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
004309A9    BA 04000000     MOV EDX,4
004309AE    E8 012CFDFF     CALL GNCRK12_.004035B4
004309B3    C3              RETN
分析到此为止,如果想爆破的话,只需要将代码中的关键跳转改一下就行了。但这是CrackMe啊,菜鸟学习是为了找出注册码啊。
下面具体分析代码

其中对Code进行处理,生成Data1数据的代码比较简单,我就不详细分析这段代码,而是给出C语言重写的代码如下所示:
data1[0]='\0';
ebx=1;
for(int i=0;i<length-1;i++)
{       
        eax=length;
        eax=eax-ebx;
        al=code[eax-1];
        dl=code[ebx-1];
        al=al^dl;
        sprintf(temp,"%d",al);
        strcat(data1,temp);
        ebx++;
}                               
sprintf(temp,"%d",code[i]);
strcat(data1,temp);

00430937    E8 74FCFFFF     CALL GNCRK12_.004305B0 这个函数是对对字符串"4401201204455"进行处理,得到结果字符串"56602124021",然后与Data2相比较,如果只是为了找到注册码的话,这段代码也可以不分析了。因为,我们通过跟踪知道了结果是"56602124021"。其实这段代码与0043093E    CALL GNCRK12_.004306FC对Data1进行处理,生成Data2数据函数是一样的了。自己跟一下就知道了。此处也不说了。

0043093E    CALL GNCRK12_.004306FC对Data1进行处理,生成Data2数据函数则比较麻烦,下面具体说明:
004306FC    55              PUSH EBP
004306FD    8BEC            MOV EBP,ESP
004306FF    83C4 F0         ADD ESP,-10
00430702    53              PUSH EBX
00430703    56              PUSH ESI
00430704    57              PUSH EDI
00430705    33C0            XOR EAX,EAX
00430707    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
0043070A    8B7D 08         MOV EDI,DWORD PTR SS:[EBP+8]
0043070D    83C7 F0         ADD EDI,-10
00430710    33C0            XOR EAX,EAX
00430712    55              PUSH EBP
00430713    68 30084300     PUSH GNCRK12_.00430830
00430718    64:FF30         PUSH DWORD PTR FS:[EAX]
0043071B    64:8920         MOV DWORD PTR FS:[EAX],ESP
0043071E    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
00430721    83C0 F4         ADD EAX,-0C
00430724    E8 672EFDFF     CALL GNCRK12_.00403590
00430729    8B07            MOV EAX,DWORD PTR DS:[EDI]
0043072B    E8 DC30FDFF     CALL GNCRK12_.0040380C
00430730    8BF0            MOV ESI,EAX
00430732    D1FE            SAR ESI,1
00430734    79 03           JNS SHORT GNCRK12_.00430739
00430736    83D6 00         ADC ESI,0
00430739    85F6            TEST ESI,ESI
0043073B    0F8E D9000000   JLE GNCRK12_.0043081A
00430741    BB 01000000     MOV EBX,1
00430746    8B07            MOV EAX,DWORD PTR DS:[EDI]
00430748    E8 BF30FDFF     CALL GNCRK12_.0040380C
0043074D    D1F8            SAR EAX,1
0043074F    79 03           JNS SHORT GNCRK12_.00430754
00430751    83D0 00         ADC EAX,0
00430754    8B17            MOV EDX,DWORD PTR DS:[EDI]
00430756    8A5402 FE       MOV DL,BYTE PTR DS:[EDX+EAX-2]
0043075A    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
0043075D    8850 01         MOV BYTE PTR DS:[EAX+1],DL
00430760    C600 01         MOV BYTE PTR DS:[EAX],1
00430763    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
00430766    8D45 F4         LEA EAX,DWORD PTR SS:[EBP-C]
00430769    E8 C21FFDFF     CALL GNCRK12_.00402730
0043076E    8B07            MOV EAX,DWORD PTR DS:[EDI]
00430770    E8 9730FDFF     CALL GNCRK12_.0040380C
00430775    D1F8            SAR EAX,1
00430777    79 03           JNS SHORT GNCRK12_.0043077C
00430779    83D0 00         ADC EAX,0
0043077C    8B17            MOV EDX,DWORD PTR DS:[EDI]
0043077E    8A5402 FF       MOV DL,BYTE PTR DS:[EDX+EAX-1]
00430782    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
00430785    8850 01         MOV BYTE PTR DS:[EAX+1],DL
00430788    C600 01         MOV BYTE PTR DS:[EAX],1
0043078B    8D55 F0         LEA EDX,DWORD PTR SS:[EBP-10]
0043078E    8D45 F4         LEA EAX,DWORD PTR SS:[EBP-C]
00430791    B1 02           MOV CL,2
00430793    E8 681FFDFF     CALL GNCRK12_.00402700
00430798    8D55 F4         LEA EDX,DWORD PTR SS:[EBP-C]               ; 取出Data1中的中间两个字符构成的整数字符串,即Data1[strlen(Data1)/2-2]和Data1[strlen(Data1)/2-1]构成的整数字符串
0043079B    8D45 FC         LEA EAX,DWORD PTR SS:[EBP-4]
0043079E    E8 0D30FDFF     CALL GNCRK12_.004037B0
004307A3    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
004307A6    E8 115FFDFF     CALL GNCRK12_.004066BC                     ; 将取出Data1中的中间两个字符构成的整数字符串转化为10进制的数据,相等于调用sscanf函数
004307AB    50              PUSH EAX                                   ; 将得到的结果压栈,后面使用
004307AC    8D45 F8         LEA EAX,DWORD PTR SS:[EBP-8]
004307AF    8B17            MOV EDX,DWORD PTR DS:[EDI]
004307B1    8A541A FF       MOV DL,BYTE PTR DS:[EDX+EBX-1]
004307B5    8850 01         MOV BYTE PTR DS:[EAX+1],DL
004307B8    C600 01         MOV BYTE PTR DS:[EAX],1
004307BB    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
004307BE    8D45 F4         LEA EAX,DWORD PTR SS:[EBP-C]
004307C1    E8 6A1FFDFF     CALL GNCRK12_.00402730
004307C6    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
004307C9    8B17            MOV EDX,DWORD PTR DS:[EDI]
004307CB    8A141A          MOV DL,BYTE PTR DS:[EDX+EBX]
004307CE    8850 01         MOV BYTE PTR DS:[EAX+1],DL
004307D1    C600 01         MOV BYTE PTR DS:[EAX],1
004307D4    8D55 F0         LEA EDX,DWORD PTR SS:[EBP-10]
004307D7    8D45 F4         LEA EAX,DWORD PTR SS:[EBP-C]
004307DA    B1 02           MOV CL,2
004307DC    E8 1F1FFDFF     CALL GNCRK12_.00402700
004307E1    8D55 F4         LEA EDX,DWORD PTR SS:[EBP-C]
004307E4    8D45 FC         LEA EAX,DWORD PTR SS:[EBP-4]               ; 从第一个Data1的数据开始,循环取出Data1中相连的两个字符,循环次数为strlen(Data1)/2
004307E7    E8 C42FFDFF     CALL GNCRK12_.004037B0
004307EC    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
004307EF    E8 C85EFDFF     CALL GNCRK12_.004066BC                     ; 将EAX中的数据转化为10进制数据
004307F4    8BD0            MOV EDX,EAX                                ; 传入EDX
004307F6    58              POP EAX                                    ; 前面压栈的数据
004307F7    33C2            XOR EAX,EDX                                ; 异或运算
004307F9    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
004307FC    E8 8B5EFDFF     CALL GNCRK12_.0040668C                     ; 将EAX转化为10进制,变为字符串
00430801    8B55 FC         MOV EDX,DWORD PTR SS:[EBP-4]
00430804    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
00430807    83C0 F4         ADD EAX,-0C
0043080A    E8 0530FDFF     CALL GNCRK12_.00403814                     ; 将上面得到的结果写到内存单元0xCE3018中,供下面比较使用
0043080F    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
00430812    43              INC EBX
00430813    4E              DEC ESI
00430814  ^ 0F85 2CFFFFFF   JNZ GNCRK12_.00430746
0043081A    33C0            XOR EAX,EAX
0043081C    5A              POP EDX
0043081D    59              POP ECX
0043081E    59              POP ECX
0043081F    64:8910         MOV DWORD PTR FS:[EAX],EDX
00430822    68 37084300     PUSH GNCRK12_.00430837
00430827    8D45 FC         LEA EAX,DWORD PTR SS:[EBP-4]
0043082A    E8 612DFDFF     CALL GNCRK12_.00403590
0043082F    C3              RETN
00430830  - E9 FF27FDFF     JMP GNCRK12_.00403034
00430835  ^ EB F0           JMP SHORT GNCRK12_.00430827
00430837    5F              POP EDI
00430838    5E              POP ESI
00430839    5B              POP EBX
0043083A    8BE5            MOV ESP,EBP
0043083C    5D              POP EBP
0043083D    C3              RETN

根据算法,我们用C语言写出算法可以如下所示:
char temp[4];
for(i=0;i<strlen(data1)/2;i++)
{
        temp[0]=data1[strlen(data1)/2-2];
        temp[1]=data1[strlen(data1)/2-1];
        sscanf(temp,"%d",&eax);
        temp[0]=data1[i];
        temp[1]=data1[i+1];
        sscanf(temp,"%d",&edx);
        eax=eax^edx;
        sprintf(temp,"%d",eax);
        strcat(data2,temp);
}
最后生成的Data2要与"56602124021"字符串相等。
则我们可以认为Data1必须满足下面的条件:
(1)strlen(data1)/2=6
(2)Data1[0]Data1[1]^Data1[4]Data1[5]=56
     Data1[1]Data1[2]^Data1[4]Data1[5]=60
     Data1[2]Data1[3]^Data1[4]Data1[5]=21
     Data1[3]Data1[4]^Data1[4]Data1[5]=24
     Data1[4]Data1[5]^Data1[4]Data1[5]=0
     Data1[5]Data1[6]^Data1[4]Data1[5]=21
     事实上这两个条件只与Data1的前7位数据有要求了。
为了判断满足这样条件的Data[1]有多少个,我写个一个穷举小程序如下:
#include "stdio.h"
#include "string.h"

#define length 6
void main()
{
        char Data1[2*length];
        int  s=-1;
        char temp[2];
        char midTemp[2];
        int eax,edx,i;
        int  n;
        int  target[length]={56,60,21,24,0,21};

        for(Data1[0]='0';Data1[0]<='9';Data1[0]++)
                for(Data1[1]='0';Data1[1]<='9';Data1[1]++)
                        for(Data1[2]='0';Data1[2]<='9';Data1[2]++)
                                for(Data1[3]='0';Data1[3]<='A';Data1[3]++)
                                        for(Data1[4]='0';Data1[4]<='9';Data1[4]++)
                                                for(Data1[5]='0';Data1[5]<='9';Data1[5]++)
                                                        for(Data1[6]='0';Data1[6]<='9';Data1[6]++)
                                                        {
                                                                        int mid=(Data1[length-2]-0x30)*10+Data1[length-1]-0x30;
                                                                        for(i=0;i<length;i++)
                                                                        {
                                                                                int t=(Data1[i]-0x30)*10+Data1[i+1]-0x30;       
                                                                                if((t^mid )!=target[i])
                                                                                        break;
                                                                        }
                                                                        if(i==length)
                                                                        {
                                                                                printf("The correct t is %c%c%c%c%c%c%c\n",Data1[0],Data1[1],Data1[2],Data1[3],Data1[4],Data1[5],Data1[6]);
                                                                                printf("The mid number is %c%c\n",Data1[4],Data1[5]);
                                                                        }

                                                                }
}
通过程序运算结果发现,Data1的前7位数据必须为"4401201"(发现没有其实就是"4401201204455"前7位数据了).
下面具体分析Code,由于0043092B    3D F7000000     CMP EAX,0F7; 对Data1进行数学处理,其结果必须与0xF7相等,而数学处理过程如下:
ebx=1;
eax=0;
while(ebx<=length)//length 为Code的长度
{
        edx=data1[ebx-1];
        eax+=edx;
        ebx+=2;
}
如果要0xF7/N使得结果在0x30到0x39之间的话,N必须为5.所以Code的长度必须为10或者11,在下面运算过程中,我为了简单假设其长度为10.根据上面所述,可以穷举出正确的Code.程序如下所示.

#include "stdio.h"
#include "string.h"
#define length 10
void main()
{
        int ebx=1;
        int eax,edx;
        char code[length];
        int al,dl;
        char  data1[length*2];
        char  data2[length*2];
        char temp[4];
       
        for(code[0]='0';code[0]<='9';code[0]++)
                for(code[1]='0';code[1]<='9';code[1]++)
                        for(code[2]='0';code[2]<='9';code[2]++)
                                for(code[3]='9';code[3]<='9';code[3]++)
                                        for(code[4]='5';code[4]<='9';code[4]++)
                                                for(code[5]='5';code[5]<='9';code[5]++)
                                                        for(code[6]='0';code[6]<='9';code[6]++)
                                                                for(code[7]='4';code[7]<='9';code[7]++)
                                                                        for(code[8]='4';code[8]<='9';code[8]++)
                                                                                for(code[9]='0';code[9]<='9';code[9]++)
                                        {
                                                ebx=1;
                                                int j=0;
                                                data1[0]='\0';
                                                for(int i=0;i<length-1;i++)
                                                {       
                                                        eax=length;
                                                        eax=eax-ebx;
                                                        al=code[eax-1];
                                                        dl=code[ebx-1];
                                                        al=al^dl;
                                                        sprintf(temp,"%d",al);
                                                        strcat(data1,temp);
                                                        ebx++;
                                                }
                                               
                                                sprintf(temp,"%d",code[i]);
                                                strcat(data1,temp);
                                                ebx=1;
                                                eax=0;
                                       
                                                while(ebx<=length)
                                                {
                                                        edx=data1[ebx-1];
                                                        eax+=edx;
                                                        ebx+=2;
                                                }
                                       
                                                if(eax==0xF7
                                                        && data1[0]=='4'&&data1[1]=='4'&&data1[2]=='0'&&data1[3]=='1'
                                                                &&data1[4]=='2'&&data1[5]=='0'&&data1[6]=='1'
                                                                )
                                                {
                                                        printf("%c%c%c%c%c%c%c%c%c%c  满足要求\n",code[0],code[1],code[2],code[3],code[4],code[5],code[6],code[7],code[8],code[9]);
                                                       
                                                }
                                        }                               
}

3 下面开始Serial的Crack了.这部分比较简单,我只给出分析和注册程序了.
00430C98    55              PUSH EBP
00430C99    68 150D4300     PUSH GNCRK12_.00430D15
00430C9E    64:FF30         PUSH DWORD PTR FS:[EAX]
00430CA1    64:8920         MOV DWORD PTR FS:[EAX],ESP
00430CA4    8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
00430CA7    8B83 10020000   MOV EAX,DWORD PTR DS:[EBX+210]
00430CAD    E8 EA94FEFF     CALL GNCRK12_.0041A19C
00430CB2    837D FC 00      CMP DWORD PTR SS:[EBP-4],0       ; 判断注册码是否为空
00430CB6    74 3B           JE SHORT GNCRK12_.00430CF3
00430CB8    8D55 F8         LEA EDX,DWORD PTR SS:[EBP-8]
00430CBB    8B83 10020000   MOV EAX,DWORD PTR DS:[EBX+210]
00430CC1    E8 D694FEFF     CALL GNCRK12_.0041A19C
00430CC6    8B45 F8         MOV EAX,DWORD PTR SS:[EBP-8]
00430CC9    E8 3E2BFDFF     CALL GNCRK12_.0040380C
00430CCE    83F8 05         CMP EAX,5                        ; 注册码长度不能小于5
00430CD1    7C 20           JL SHORT GNCRK12_.00430CF3
00430CD3    C605 12274300 0>MOV BYTE PTR DS:[432712],1
00430CDA    803D 11274300 0>CMP BYTE PTR DS:[432711],1
00430CE1    75 17           JNZ SHORT GNCRK12_.00430CFA
00430CE3    803D 12274300 0>CMP BYTE PTR DS:[432712],1
00430CEA    75 0E           JNZ SHORT GNCRK12_.00430CFA
00430CEC    E8 3FFDFFFF     CALL GNCRK12_.00430A30           ; 判断注册码是否正确的函数

其中判断注册码是否正确的函数
00430A30    55              PUSH EBP
00430A31    8BEC            MOV EBP,ESP
00430A33    81C4 70FFFFFF   ADD ESP,-90
00430A39    53              PUSH EBX
00430A3A    56              PUSH ESI
00430A3B    57              PUSH EDI
00430A3C    33C0            XOR EAX,EAX
00430A3E    8985 70FFFFFF   MOV DWORD PTR SS:[EBP-90],EAX
00430A44    8985 74FFFFFF   MOV DWORD PTR SS:[EBP-8C],EAX
00430A4A    8945 B8         MOV DWORD PTR SS:[EBP-48],EAX
00430A4D    8945 B4         MOV DWORD PTR SS:[EBP-4C],EAX
00430A50    33C0            XOR EAX,EAX
00430A52    55              PUSH EBP
00430A53    68 B50B4300     PUSH GNCRK12_.00430BB5
00430A58    64:FF30         PUSH DWORD PTR FS:[EAX]
00430A5B    64:8920         MOV DWORD PTR FS:[EAX],ESP
00430A5E    E8 D567FDFF     CALL GNCRK12_.00407238
00430A63    83C4 F8         ADD ESP,-8
00430A66    DD1C24          FSTP QWORD PTR SS:[ESP]
00430A69    9B              WAIT
00430A6A    E8 A167FDFF     CALL GNCRK12_.00407210
00430A6F    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX     ; CALL GNCRK12_.00407210的结果存放到[EBP-4]中
00430A72    8D95 74FFFFFF   LEA EDX,DWORD PTR SS:[EBP-8C]
00430A78    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430A7D    8B80 08020000   MOV EAX,DWORD PTR DS:[EAX+208]
00430A83    E8 1497FEFF     CALL GNCRK12_.0041A19C
00430A88    8B95 74FFFFFF   MOV EDX,DWORD PTR SS:[EBP-8C]    ; 取出用户名
00430A8E    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430A93    8B08            MOV ECX,DWORD PTR DS:[EAX]
00430A95    FF51 18         CALL DWORD PTR DS:[ECX+18]
00430A98    8D55 B8         LEA EDX,DWORD PTR SS:[EBP-48]
00430A9B    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430AA0    8B80 10020000   MOV EAX,DWORD PTR DS:[EAX+210]
00430AA6    E8 F196FEFF     CALL GNCRK12_.0041A19C
00430AAB    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430AB0    8B40 08         MOV EAX,DWORD PTR DS:[EAX+8]
00430AB3    E8 542DFDFF     CALL GNCRK12_.0040380C           ; 取出用户名长度
00430AB8    D1F8            SAR EAX,1                        ; 用户名长度除2
00430ABA    79 03           JNS SHORT GNCRK12_.00430ABF
00430ABC    83D0 00         ADC EAX,0
00430ABF    8945 BC         MOV DWORD PTR SS:[EBP-44],EAX
00430AC2    8B75 BC         MOV ESI,DWORD PTR SS:[EBP-44]
00430AC5    85F6            TEST ESI,ESI
00430AC7    7E 3B           JLE SHORT GNCRK12_.00430B04
00430AC9    BA 01000000     MOV EDX,1
00430ACE    8D85 78FFFFFF   LEA EAX,DWORD PTR SS:[EBP-88]
00430AD4    8B0D 0C274300   MOV ECX,DWORD PTR DS:[43270C]
00430ADA    8B49 08         MOV ECX,DWORD PTR DS:[ECX+8]
00430ADD    0FB64C11 FF     MOVZX ECX,BYTE PTR DS:[ECX+EDX-1>
00430AE2    8B5D BC         MOV EBX,DWORD PTR SS:[EBP-44]    ; 用户名长度除2
00430AE5    2BDA            SUB EBX,EDX
00430AE7    8B3D 0C274300   MOV EDI,DWORD PTR DS:[43270C]
00430AED    8B7F 08         MOV EDI,DWORD PTR DS:[EDI+8]
00430AF0    0FB65C1F FF     MOVZX EBX,BYTE PTR DS:[EDI+EBX-1>
00430AF5    0FAF5D FC       IMUL EBX,DWORD PTR SS:[EBP-4]    ; 乘以[EBP-4]的值
00430AF9    33CB            XOR ECX,EBX
00430AFB    8908            MOV DWORD PTR DS:[EAX],ECX
00430AFD    42              INC EDX
00430AFE    83C0 04         ADD EAX,4
00430B01    4E              DEC ESI
00430B02  ^ 75 D0           JNZ SHORT GNCRK12_.00430AD4
00430B04    55              PUSH EBP
00430B05    E8 F2FEFFFF     CALL GNCRK12_.004309FC
00430B0A    59              POP ECX
00430B0B    8D45 B4         LEA EAX,DWORD PTR SS:[EBP-4C]
00430B0E    E8 7D2AFDFF     CALL GNCRK12_.00403590
00430B13    8B75 BC         MOV ESI,DWORD PTR SS:[EBP-44]    ; 用户名长度的一半
00430B16    85F6            TEST ESI,ESI
00430B18    7E 31           JLE SHORT GNCRK12_.00430B4B
00430B1A    8D7D C0         LEA EDI,DWORD PTR SS:[EBP-40]
00430B1D    8D9D 78FFFFFF   LEA EBX,DWORD PTR SS:[EBP-88]
00430B23    8B07            MOV EAX,DWORD PTR DS:[EDI]       ; 0x232
00430B25    3103            XOR DWORD PTR DS:[EBX],EAX
00430B27    8D95 70FFFFFF   LEA EDX,DWORD PTR SS:[EBP-90]
00430B2D    8B03            MOV EAX,DWORD PTR DS:[EBX]
00430B2F    E8 585BFDFF     CALL GNCRK12_.0040668C
00430B34    8B95 70FFFFFF   MOV EDX,DWORD PTR SS:[EBP-90]    ; 将前面运算的结果转化为10进制的字符串
00430B3A    8D45 B4         LEA EAX,DWORD PTR SS:[EBP-4C]
00430B3D    E8 D22CFDFF     CALL GNCRK12_.00403814
00430B42    83C3 04         ADD EBX,4
00430B45    83C7 04         ADD EDI,4
00430B48    4E              DEC ESI
00430B49  ^ 75 D8           JNZ SHORT GNCRK12_.00430B23
00430B4B    8B45 B8         MOV EAX,DWORD PTR SS:[EBP-48]    ; 输入的注册码
00430B4E    8B55 B4         MOV EDX,DWORD PTR SS:[EBP-4C]    ; 正确的注册码
00430B51    E8 C62DFDFF     CALL GNCRK12_.0040391C
00430B56    75 17           JNZ SHORT GNCRK12_.00430B6F      ; 关键跳转
00430B58    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430B5D    8B80 14020000   MOV EAX,DWORD PTR DS:[EAX+214]
00430B63    BA CC0B4300     MOV EDX,GNCRK12_.00430BCC        ; ASCII " Registered!"
00430B68    E8 5F96FEFF     CALL GNCRK12_.0041A1CC
00430B6D    EB 15           JMP SHORT GNCRK12_.00430B84
00430B6F    A1 0C274300     MOV EAX,DWORD PTR DS:[43270C]
00430B74    8B80 14020000   MOV EAX,DWORD PTR DS:[EAX+214]
00430B7A    BA E40B4300     MOV EDX,GNCRK12_.00430BE4        ; ASCII "Unregistered"
00430B7F    E8 4896FEFF     CALL GNCRK12_.0041A1CC
00430B84    33C0            XOR EAX,EAX
00430B86    5A              POP EDX
00430B87    59              POP ECX
00430B88    59              POP ECX
00430B89    64:8910         MOV DWORD PTR FS:[EAX],EDX
00430B8C    68 BC0B4300     PUSH GNCRK12_.00430BBC
00430B91    8D85 70FFFFFF   LEA EAX,DWORD PTR SS:[EBP-90]
00430B97    E8 F429FDFF     CALL GNCRK12_.00403590
00430B9C    8D85 74FFFFFF   LEA EAX,DWORD PTR SS:[EBP-8C]
00430BA2    E8 E929FDFF     CALL GNCRK12_.00403590
00430BA7    8D45 B4         LEA EAX,DWORD PTR SS:[EBP-4C]
00430BAA    BA 02000000     MOV EDX,2
00430BAF    E8 002AFDFF     CALL GNCRK12_.004035B4
00430BB4    C3              RETN

根据上面程序很容易写出注册程序如下所示:
#include "stdio.h"
#include "string.h"

void main()
{
        char name[20];
        int length;
        printf("please input your name!\n");
        scanf("%s",name);
        length=strlen(name);
        if(length/2>3)
        {
                printf("the name should be less than 7 chars\n");
        }
        int *temp1;
        char *sn;
        char temp[3];
        temp1=new int[length/2];
        sn=new char[3*(length/2)];
        int edx=1;
        int ebx;
        int ecx;
        int t1,t2;
        for(int i=0;i<length/2;i++)
        {       
                t1=name[edx-1];
                ebx=length/2;
                ebx-=edx;
                t2=name[ebx-1];
                t2=t2*1;
                t1=t1^t2;
                temp1[i]=t1;
                edx++;
        }
        sn[0]='\0';
        for(i=0;i<length/2;i++)
        {       
                temp1[i]=temp1[i]^(0x232+2*i);
                sprintf(temp,"%d",temp1[i]);
                strcat(sn,temp);
        }
        printf("the right serial is %s\n",sn);

}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
顶了
学习ing ~~~~~~~~
2006-4-23 20:16
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
汇编是块难啃的骨头。。。

都看的晕了,可气的是自己机器上的MASM汇编环境至今还未配置成功。。。
都在别人机器上玩的
2006-4-23 20:23
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
上传crackme
2006-4-24 10:39
0
游客
登录 | 注册 方可回帖
返回
//