【软件名称】《加密与解密》随书光盘习题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直播授课