首页
社区
课程
招聘
[旧帖] [求助]小菜分析第一个crackme,请帮忙找出注册码 0.00雪花
发表于: 2010-12-13 00:41 602

[旧帖] [求助]小菜分析第一个crackme,请帮忙找出注册码 0.00雪花

2010-12-13 00:41
602
//在cracksme上下的一个"简单"crackme;分析不当之处,各位兄弟多指教;
#include <stdio.h>
#include <string.h>
char flag;
int fuck[256];
char a[] = {0x38,0x7c,0xc5,0x63,0xda};// 004012F0处

//00401316处
char* b[] = {"XPQ4G","6CRCC","FRT9J","B9TKY","DG8FV","CRH9Q","P8RD4","CCHB2","VFGG8","Q3RH6","692HW","3Y9HY","KFHBY","DFTYY","K92GJ"};
/***************************************************
00401010 /$ 8A5424 04 MOV DL,BYTE PTR SS:[ESP+4]
00401014 |. 8A0D D4554000 MOV CL,BYTE PTR DS:[4055D4]
0040101A |. 56 PUSH ESI
0040101B |. BE 08000000 MOV ESI,8
00401020 |> 8AC1 /MOV AL,CL
00401022 |. 32C2 |XOR AL,DL
00401024 |. 24 01 |AND AL,1
00401026 |. 3C 01 |CMP AL,1
00401028 |. 75 03 |JNZ SHORT 0040102D
0040102A |. 80F1 18 |XOR CL,18
0040102D |> D0E9 |SHR CL,1
0040102F |. 3C 01 |CMP AL,1
00401031 |. 75 03 |JNZ SHORT 00401036
00401033 |. 80C9 80 |OR CL,80
00401036 |> D0EA |SHR DL,1
00401038 |. 4E |DEC ESI
00401039 |.^ 75 E5 \JNZ SHORT 00401020
0040103B |. 880D D4554000 MOV BYTE PTR DS:[4055D4],CL
00401041 |. 5E POP ESI
00401042 \. C3 RETN
***********************************************************************/

void feiji(char sn)
{
char al,cl,dl = sn;
int esi;
cl = flag;

for(esi = 8;esi >= 0;esi--)
{
al = cl;
if(((al^dl) & 1) == 1)
{
cl = ((al^0x18)>>1)| 0x80;
}
else
{
cl = cl>>1;

}
dl = dl>>1;
}
flag = cl;
}
/****************************************************************************
00401140 /$ 55 PUSH EBP
00401141 |. 8BEC MOV EBP,ESP
00401143 |. 51 PUSH ECX ;
00401144 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] ; 假序号第7位指针
00401147 |. 33C9 XOR ECX,ECX ; ecx = 0;
00401149 |. 56 PUSH ESI
0040114A |. 57 PUSH EDI ;
0040114B |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ; 假序列号第7位指针
0040114E |. 8848 05 MOV BYTE PTR DS:[EAX+5],CL ; 假序号第12位置0;
00401151 |. 894D 0C MOV DWORD PTR SS:[EBP+C],ECX
00401154 |. 57 PUSH EDI
00401155 |. 56 PUSH ESI
00401156 |. 8B55 08 MOV EDX,DWORD PTR SS:[EBP+8] ; edx =真序列号
00401159 |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; edi = 真序列号
0040115C |. 8B75 FC MOV ESI,DWORD PTR SS:[EBP-4] ; esi = 假序列号7-11位
0040115F |. B9 FFFFFFFF MOV ECX,-1 ; ecx == -1 准备测试位数
00401164 |. 33C0 XOR EAX,EAX ; eax = 0;
00401166 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; 循环扫描真序列号
00401168 |. F7D1 NOT ECX ; 取反减1得到真序列号位数
0040116A |. 8BFA MOV EDI,EDX ; edi = 真序列号
0040116C |. 33D2 XOR EDX,EDX
0040116E |. F3:A6 REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:[ES>; 串比较 真假序列号
00401170 |. 8A46 FF MOV AL,BYTE PTR DS:[ESI-1] ; 取下一位假序列号
00401173 |. 8A57 FF MOV DL,BYTE PTR DS:[EDI-1] ; 最下一位真序列号
00401176 |. 2BC2 SUB EAX,EDX ; 假序列号 - 真序列号
00401178 |. 8945 0C MOV DWORD PTR SS:[EBP+C],EAX ; 保存结果
0040117B |. 5E POP ESI
0040117C |. 5F POP EDI
0040117D |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C] ; return eax;
00401180 |. 5F POP EDI
00401181 |. 5E POP ESI
00401182 |. 8BE5 MOV ESP,EBP
00401184 |. 5D POP EBP
00401185 \. C3 RETN

***************************************************************************************/
int gaogaofeiji(char *p1,char *p2)
{
char *ptrue,*pfalse;
ptrue = p1;
pfalse = p2;
*(pfalse + 5) = 0;//假码第12位置0;相当于字符结束

return(strcmp(ptrue,pfalse));//真码与假码7-11位比较,返回比较结果

}

/*****************************************************************
00401190 /$ 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8] ; 假序列号指针
00401194 |. 8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4] ; 第一个参数 用户名第一位字符 & OF
00401198 |. 83C0 06 ADD EAX,6 ; 序列号指针+6
0040119B |. 8B148D 605040>MOV EDX,DWORD PTR DS:[ECX*4+405060] ; 真序列号
004011A2 |. 50 PUSH EAX ; 第7位假序列号指针
004011A3 |. 52 PUSH EDX ; 好像是真序列号
004011A4 |. E8 97FFFFFF CALL 00401140 ; 返回假序号 - 真序号
004011A9 |. 83C4 08 ADD ESP,8
004011AC |. F7D8 NEG EAX ; 如果eax != 0;neg后 CF = 1
004011AE |. 1BC0 SBB EAX,EAX ; eax - eax - CF
004011B0 |. 40 INC EAX ; 如果返回的结果不为0,那这里则为0;
004011B1 \. C3 RETN

****************************************************************/
int gaofeiji(int i,char *p)
{
char *ptrue,*pfalse;
int k;
k = i;
pfalse = p;
pfalse = pfalse + 6;//假码第7位
ptrue = (char *)b[k];//真序号的位置取决于用户名第一个字符
return(gaogaofeiji(ptrue,pfalse));//返回gaogaofeiji的返回值

}

/**************************************
004010A0 /$ 56 PUSH ESI
004010A1 |. 57 PUSH EDI
004010A2 |. 8B7C24 0C MOV EDI,DWORD PTR SS:[ESP+C]
004010A6 |. 33D2 XOR EDX,EDX
004010A8 |. B9 D8554000 MOV ECX,004055D8 ; 数组基址
004010AD |> 8BC2 /MOV EAX,EDX ; for(ecx == 004055d8;ecx < 004059d8; ecx = ecx + 4)
004010AF |. BE 08000000 |MOV ESI,8 ; for(esi = 8; esi > 0;esi--)
004010B4 |> A8 01 |/TEST AL,1
004010B6 |. 74 06 ||JE SHORT 004010BE
004010B8 |. D1E8 ||SHR EAX,1
004010BA |. 33C7 ||XOR EAX,EDI
004010BC |. EB 02 ||JMP SHORT 004010C0
004010BE |> D1E8 ||SHR EAX,1
004010C0 |> 4E ||DEC ESI
004010C1 |.^ 75 F1 |\JNZ SHORT 004010B4
004010C3 |. 8901 |MOV DWORD PTR DS:[ECX],EAX
004010C5 |. 83C1 04 |ADD ECX,4
004010C8 |. 42 |INC EDX ;
004010C9 |. 81F9 D8594000 |CMP ECX,004059D8 ; ASCII "8|與?
004010CF |.^ 7C DC \JL SHORT 004010AD
004010D1 |. 5F POP EDI
004010D2 |. 5E POP ESI
004010D3 \. C3 RETN

*******************************************************************/
void gaosmfeiji(void)
{
int i,esi,eax,edx = 0;

for(i = 0;i < 256;i++)
{
eax = edx;
for(esi = 8;esi > 0;esi--)
{
if(0 == (eax&0x1))
{
eax = eax>>1;
}
else
{
eax = eax>>1;
eax = eax^0xedb88320;
}

}
fuck[i] = eax;
edx = edx + 1;

}
}

/******************************************************************************************
00401060 /$ 56 PUSH ESI ;
00401061 |. 8B7424 0C MOV ESI,DWORD PTR SS:[ESP+C] ; esi = 用户名字符数
00401065 |. 83C8 FF OR EAX,FFFFFFFF
00401068 |. 85F6 TEST ESI,ESI ; 测试用户名字符数是不是为0
0040106A |. 76 24 JBE SHORT 00401090 ;
0040106C |. 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8] ; ecx = 用户名指针
00401070 |. 53 PUSH EBX
00401071 |> 8BD0 /MOV EDX,EAX
00401073 |. 33DB |XOR EBX,EBX ; ebx = 0;
00401075 |. 8A19 |MOV BL,BYTE PTR DS:[ECX] ; 取用户名字符
00401077 |. 81E2 FF000000 |AND EDX,0FF
0040107D |. 33D3 |XOR EDX,EBX ; edx^username[i]
0040107F |. C1E8 08 |SHR EAX,8
00401082 |. 8B1495 D85540>|MOV EDX,DWORD PTR DS:[EDX*4+4055D8] ; edx = a[edx];4055d8:int a[256]
00401089 |. 33C2 |XOR EAX,EDX ; eax^a[edx]
0040108B |. 41 |INC ECX ; 用户名指针+1
0040108C |. 4E |DEC ESI ; 循环控制位 是用户名的字符数
0040108D |.^ 75 E2 \JNZ SHORT 00401071 ; for(esi=strlen(username);esi>=0;esi--)
0040108F |. 5B POP EBX
00401090 |> F7D0 NOT EAX
00401092 |. 5E POP ESI
00401093 \. C3 RETN
**************************************************************************************************/
int bengxx(char *pusername,int lenname)
{
int esi = lenname;
int edx;
int eax = 0xFFFFFFFF;
char bl;
if(esi)//好像不用测试用户名为不为空
{
for(esi;esi > 0;esi--)
{
edx = eax;
bl = *pusername;
edx = edx&0xFF;
edx = edx^bl;
eax = eax>>8;
edx = fuck[edx];
printf("edx = %x\n",edx);
eax = eax^edx;
pusername = pusername + 1;
}
}
return(~eax);
}
//********************************************************************************
int main(void)
{

int i,lenname,ecx,edx;
char bl = 0;
char sn,cl,al;
char buff[9];
char *ppwd,*pusername;

char username[21] = {0},password[33] = {0};
ppwd = password;
pusername = username;

printf("username:\n");
scanf_s("%s",username,20);
lenname = strlen(username);
if((lenname < 2) | (lenname > 14))
return -1;
printf("password:\n");
scanf_s("%s",password,32);

if(strlen(password) != 29)
{
return -1;
}

for(i = 0;i< 4;i++)
{
flag = 0;
bl = bl&0xff;
sn = password[i];
feiji(sn);
if(flag != a[i])
return -1;

}

i = username[0];
i = i & 0x0f;
sn = gaofeiji(i,ppwd);

if(gaofeiji(i,ppwd) != 0)//比较真假码,不相等则out
{ //真码取决于用户名第一个字符,假码为7-11位
return -1;
}

gaosmfeiji();

//00401354 |. FF15 A0404000 CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
sprintf_s(buff,9,"%02X",bengxx(pusername,lenname));

/******************************************************************
00401363 |> /0FBE5404 0C /MOVSX EDX,BYTE PTR SS:[ESP+EAX+C] ; wsprintf保存的
00401368 |. |0FBE31 |MOVSX ESI,BYTE PTR DS:[ECX] ; 假序列号 第13 到17位
0040136B |. |2BD6 |SUB EDX,ESI
0040136D |0F85 89000000 JNZ 004013FC
00401373 |. |83C0 02 |ADD EAX,2
00401376 |. |41 |INC ECX ; 指针加1
00401377 |. |83F8 08 |CMP EAX,8 ; for(eax = 0;eax < 8;eax = eax +2)
0040137A |.^\7C E7 \JL SHORT 00401363
****************************************************************************/
ecx = 12;
for(i = 0;i < 8;i = i + 2)
{
bl = buff[i+2];
sn = password[ecx];
if(!(bl^sn))
{
return -1;
}
ecx = ecx + 1;
//没完
}
/***********************************************************************
0040137E |> /E8 7DFCFFFF /CALL 00401000 ;
00401383 |. |8A4434 18 |MOV AL,BYTE PTR SS:[ESP+ESI+18] ; 用户名
00401387 |. |50 |PUSH EAX
00401388 |. |E8 83FCFFFF |CALL 00401010 ;
0040138D |. |83C4 04 |ADD ESP,4
00401390 |. |E8 BBFCFFFF |CALL 00401050 ;
00401395 |. |8AC8 |MOV CL,AL
00401397 |. |80F9 1A |CMP CL,1A ;
0040139A |. |884C24 50 |MOV BYTE PTR SS:[ESP+50],CL ;
0040139E |. |72 25 |JB SHORT 004013C5 ;
004013A0 |. |80F9 17 |CMP CL,17 ;
004013A3 |. |76 20 |JBE SHORT 004013C5
004013A5 |. |8B5424 50 |MOV EDX,DWORD PTR SS:[ESP+50] ;
004013A9 |. |B8 ABAAAAAA |MOV EAX,AAAAAAAB
004013AE |. |81E2 FF000000 |AND EDX,0FF
004013B4 |. |83EA 15 |SUB EDX,15 ;
004013B7 |. |F7E2 |MUL EDX ; AAAAAAAB * ( flag- 21)
004013B9 |. |D1EA |SHR EDX,1 ; edx /2
004013BB |> |80C1 FD |/ADD CL,0FD ; for(edx;edx >=0;edx--)
004013BE |. |4A ||DEC EDX ; cl += 0xFD
004013BF |.^|75 FA |\JNZ SHORT 004013BB
004013C1 |. |884C24 50 |MOV BYTE PTR SS:[ESP+50],CL
004013C5 |> |8B4424 50 |MOV EAX,DWORD PTR SS:[ESP+50]
004013C9 |. |25 FF000000 |AND EAX,0FF
004013CE |. |8A88 44504000 |MOV CL,BYTE PTR DS:[EAX+405044];这里可能是一个结构体
;结构体的最后是序列号数组
;倒数第二元素个是指向数组序列号指针数组
;倒数第三个元素是26个字符数组

004013D4 |. |8A4434 3E |MOV AL,BYTE PTR SS:[ESP+ESI+3E]
004013D8 |3AC8 CMP CL,AL
004013DA |75 20 JNZ SHORT 004013FC ; 不等就out
004013DC |. |46 |INC ESI
004013DD |. |83FE 05 |CMP ESI,5
004013E0 |.^\7C 9C \JL SHORT 0040137E ; for(esi = 0;esi < 5;esi++)

004011C0 /$ 51 PUSH ECX
004011C1 |. 53 PUSH EBX
004011C2 |. 55 PUSH EBP
004011C3 |. 33ED XOR EBP,EBP
004011C5 |. 56 PUSH ESI
004011C6 |. 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14]
004011CA |. 57 PUSH EDI
004011CB |. 896C24 10 MOV DWORD PTR SS:[ESP+10],EBP ; ecx = 0;
004011CF |> BF 30504000 /MOV EDI,00405030 ; ASCII "1234567890ABCDEF"
004011D4 |. 83C9 FF |OR ECX,FFFFFFFF
004011D7 |. 33C0 |XOR EAX,EAX
004011D9 |. 33D2 |XOR EDX,EDX
004011DB |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
004011DD |. 8A5C2E 18 |MOV BL,BYTE PTR DS:[ESI+EBP+18] ; 循环取假码25至29位
004011E1 |. F7D1 |NOT ECX
004011E3 |. 49 |DEC ECX ; 计算常量的长度
004011E4 |. 74 22 |JE SHORT 00401208
004011E6 |> 3A9A 30504000 |/CMP BL,BYTE PTR DS:[EDX+405030] ; 循环查表
004011EC |. 74 16 ||JE SHORT 00401204 ; 查到就跳
004011EE |. BF 30504000 ||MOV EDI,00405030 ; ASCII "1234567890ABCDEF"
004011F3 |. 83C9 FF ||OR ECX,FFFFFFFF
004011F6 |. 33C0 ||XOR EAX,EAX
004011F8 |. 42 ||INC EDX
004011F9 |. F2:AE ||REPNE SCAS BYTE PTR ES:[EDI]
004011FB |. F7D1 ||NOT ECX
004011FD |. 49 ||DEC ECX ; 计算常量的长度
004011FE |. 3BD1 ||CMP EDX,ECX
00401200 |.^ 72 E4 |\JB SHORT 004011E6
00401202 |. EB 04 |JMP SHORT 00401208 ; 如果从这里跳那么字符就不在 0~F当中
00401204 |> FF4424 10 |INC DWORD PTR SS:[ESP+10] ; 查到相等计数器+1
00401208 |> 45 |INC EBP
00401209 |. 83FD 05 |CMP EBP,5
0040120C |.^ 7C C1 \JL SHORT 004011CF ; for(ebp;ebp<5;ebp++)
0040120E |. 837C24 10 05 CMP DWORD PTR SS:[ESP+10],5
00401213 |. 74 08 JE SHORT 0040121D ; 相等表示5个字符都在表中 不等 out
00401215 |. 5F POP EDI
00401216 |. 5E POP ESI
00401217 |. 5D POP EBP
00401218 |. 33C0 XOR EAX,EAX ; return 0;
0040121A |. 5B POP EBX
0040121B |. 59 POP ECX
0040121C |. C3 RETN
0040121D |> 8A46 18 MOV AL,BYTE PTR DS:[ESI+18] ; 第25位
00401220 |. B1 46 MOV CL,46 ; F
00401222 |. 3AC1 CMP AL,CL ; 第25位是不是F
00401224 |. 75 0F JNZ SHORT 00401235 ; 不是就跳
00401226 |. 384E 19 CMP BYTE PTR DS:[ESI+19],CL ; 第26位
00401229 |. 75 0A JNZ SHORT 00401235
0040122B |. 384E 20 CMP BYTE PTR DS:[ESI+20],CL ; 第27位
0040122E |. 75 05 JNZ SHORT 00401235
00401230 |. 384E 21 CMP BYTE PTR DS:[ESI+21],CL ; 第28位
00401233 |. 74 3F JE SHORT 00401274
00401235 |> B1 41 MOV CL,41 ; A
00401237 |. 3AC1 CMP AL,CL
00401239 |. 75 0F JNZ SHORT 0040124A
0040123B |. 384E 19 CMP BYTE PTR DS:[ESI+19],CL
0040123E |. 75 0A JNZ SHORT 0040124A
00401240 |. 384E 20 CMP BYTE PTR DS:[ESI+20],CL
00401243 |. 75 05 JNZ SHORT 0040124A
00401245 |. 384E 21 CMP BYTE PTR DS:[ESI+21],CL
00401248 |. 74 2A JE SHORT 00401274
0040124A |> 3C 42 CMP AL,42 ; B
0040124C |. 75 26 JNZ SHORT 00401274
0040124E |. 384E 19 CMP BYTE PTR DS:[ESI+19],CL
00401251 |. 75 0E JNZ SHORT 00401261
00401253 |. 8A56 20 MOV DL,BYTE PTR DS:[ESI+20]
00401256 |. B1 44 MOV CL,44 ; D
00401258 |. 3AD1 CMP DL,CL
0040125A |. 75 05 JNZ SHORT 00401261
0040125C |. 384E 21 CMP BYTE PTR DS:[ESI+21],CL
0040125F |. 74 13 JE SHORT 00401274
00401261 |> 3C 42 CMP AL,42
00401263 |. 75 0F JNZ SHORT 00401274
00401265 |. 807E 19 31 CMP BYTE PTR DS:[ESI+19],31
00401269 |. 75 09 JNZ SHORT 00401274
0040126B |. 807E 20 30 CMP BYTE PTR DS:[ESI+20],30
0040126F |. 75 03 JNZ SHORT 00401274
00401271 |. 8A46 21 MOV AL,BYTE PTR DS:[ESI+21]
00401274 |> 5F POP EDI
00401275 |. 5E POP ESI
00401276 |. 5D POP EBP
00401277 |. B8 01000000 MOV EAX,1 ; 上面switch不知道要搞什么,反正return 1;
0040127C |. 5B POP EBX
0040127D |. 59 POP ECX
0040127E \. C3 RETN

******************************************************************************/

/*********
http://crackmes.de/users/virw/xc2/
大概流程:
1.用户名前四位字符运算后与常量比较,不等out
2.输入序号第7位到第11位(5位)与真序号比较,真序号取决于用户名第一位字符;
3.生成一个数组,根据生成后的数组运算,得到的结果%02x格式化输出,并取出1,3,5,7位分别与
输入序号的13,14,15,16位比较,不等 out
4.乱七八糟运算完了之后与字符常量比较,字符常量在26个字母表中
字母表的顺序就是键盘三排字母从上至下,从左往右排
5.输入序号25至29位在1~F之间
头晕晕了,欢迎敲砖。新手上路

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//