-
-
[原创]CrackMe.happytown.VC.0019 算法分析
-
发表于: 2006-11-20 15:42 5851
-
【文章标题】: CrackMe.happytown.VC.0019 简单算法分析
【文章作者】: 红尘岁月
【作者邮箱】: butter9999@21cn.com
【软件名称】: CrackMe.happytown.VC.0019
【软件大小】: 56K
【下载地址】: http://bbs.pediy.com/showthread.php?s=&threadid=35158
【加壳方式】: 无
【编写语言】: VC
【使用工具】: OD
【操作平台】: Win9x/NT/2000/XP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
0040106D PUSH 3E9 ; /ControlID = 3E9 (1001.)
00401072 PUSH ESI ; |hWnd
00401073 CALL DWORD PTR DS:[<&USER32.GetDlgItem>] ; \GetDlgItem
00401079 PUSH EAX ; /hWnd
0040107A CALL DWORD PTR DS:[<&USER32.SetFocus>] ; \SetFocus
00401080 PUSH ESI
00401081 CALL CrackMe_.00401130 ; 关键call计算
00401086 ADD ESP,4
00401089 TEST EAX,EAX
0040108B POP ESI
0040108C JE CrackMe_.0040111F ; 爆破点
00401092 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401094 PUSH CrackMe_.004060C4 ; |Title = "Congratulations"
00401099 PUSH CrackMe_.004060B4 ; |Text = "Good job, man!"
0040109E PUSH 0 ; |hOwner = NULL
004010A0 CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ; \MessageBoxA
004010A6 XOR EAX,EAX
004010A8 RETN 10
/////////////////////////////////////////////////////////////////////////
跟进算法Call
/////////////////////////////////////////////////////////////////////////
00401130 SUB ESP,51C
00401136 PUSH EBX
00401137 PUSH EBP
00401138 PUSH ESI
00401139 PUSH EDI
0040113A MOV ECX,7
0040113F MOV ESI,CrackMe_.004060D4 ; mstr1= ASCII "TRADECANMAKEEVERYONEBETTEROFF"
00401144 LEA EDI,DWORD PTR SS:[ESP+10]
00401148 XOR EAX,EAX
0040114A REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
0040114C MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
0040114E MOV ECX,31
00401153 LEA EDI,DWORD PTR SS:[ESP+F9]
0040115A MOV BYTE PTR SS:[ESP+F8],0
00401162 MOV BYTE PTR SS:[ESP+1C0],0
0040116A REP STOS DWORD PTR ES:[EDI]
0040116C STOS WORD PTR ES:[EDI]
0040116E STOS BYTE PTR ES:[EDI]
0040116F MOV ECX,31
00401174 XOR EAX,EAX
00401176 LEA EDI,DWORD PTR SS:[ESP+1C1]
0040117D MOV BYTE PTR SS:[ESP+288],0
00401185 REP STOS DWORD PTR ES:[EDI]
00401187 STOS WORD PTR ES:[EDI]
00401189 STOS BYTE PTR ES:[EDI]
0040118A MOV ECX,0A8
0040118F XOR EAX,EAX
00401191 LEA EDI,DWORD PTR SS:[ESP+289]
00401198 MOV BYTE PTR SS:[ESP+30],0
0040119D REP STOS DWORD PTR ES:[EDI]
0040119F STOS WORD PTR ES:[EDI]
004011A1 STOS BYTE PTR ES:[EDI]
004011A2 MOV ECX,31
004011A7 XOR EAX,EAX
004011A9 LEA EDI,DWORD PTR SS:[ESP+31]
004011AD XOR ESI,ESI
004011AF REP STOS DWORD PTR ES:[EDI]
004011B1 STOS WORD PTR ES:[EDI]
004011B3 STOS BYTE PTR ES:[EDI]
004011B4 LEA EDI,DWORD PTR SS:[ESP+288]
004011BB /XOR ECX,ECX
004011BD |/LEA EAX,DWORD PTR DS:[ECX+ESI]
004011C0 ||MOV EBX,1A
004011C5 ||CDQ
004011C6 ||IDIV EBX
004011C8 ||ADD DL,41
004011CB ||MOV BYTE PTR DS:[EDI+ECX],DL
004011CE ||INC ECX
004011CF ||CMP ECX,EBX
004011D1 |\JL SHORT CrackMe_.004011BD
004011D3 |INC ESI
004011D4 |ADD EDI,EBX
004011D6 |CMP ESI,EBX
004011D8 \JL SHORT CrackMe_.004011BB
004011DA MOV EBP,DWORD PTR SS:[ESP+530]
004011E1 LEA EAX,DWORD PTR SS:[ESP+F8]
上面是这些是为计算做准备,初始化一些内存
004011E8 PUSH 0C9 ; /Count = C9 (201.)
004011ED PUSH EAX ; |Buffer
004011EE PUSH 3E8 ; |ControlID = 3E8 (1000.)
004011F3 PUSH EBP ; |hWnd
004011F4 CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>] ; \GetDlgItemTextA
004011FA MOV ESI,EAX
004011FC CMP ESI,4 ; 用户名长度必须nlen>=4
004011FF JL CrackMe_.00401305
00401205 CMP ESI,0F
00401208 JG CrackMe_.00401305 ; 用户名长度必须nlen<16
0040120E LEA ECX,DWORD PTR SS:[ESP+F8] ; name
00401215 PUSH ESI ; nlen
00401216 PUSH ECX
00401217 CALL CrackMe_.00401320 ; 算法call2:必须为字符且做小写转为大写
0040121C ADD ESP,8
0040121F TEST EAX,EAX
00401221 JE CrackMe_.00401305
00401227 MOV EAX,1D
0040122C CDQ
0040122D IDIV ESI
0040122F TEST EAX,EAX ; A=0x1d/nlen,B=0x1d%nlen
00401231 JLE SHORT CrackMe_.0040124D
00401233 MOV EDI,DWORD PTR DS:[<&KERNEL32.lstrcatA>] ; kernel32.lstrcatA
00401239 MOV ESI,EAX
0040123B /LEA EDX,DWORD PTR SS:[ESP+F8] ; 新的用户名newname=重复name字符串A次
00401242 |LEA EAX,DWORD PTR SS:[ESP+30]
00401246 |PUSH EDX
00401247 |PUSH EAX
00401248 |CALL EDI
0040124A |DEC ESI
0040124B \JNZ SHORT CrackMe_.0040123B
0040124D MOV EBX,DWORD PTR DS:[<&KERNEL32.lstrlenA>] ; kernel32.lstrlenA
00401253 LEA ECX,DWORD PTR SS:[ESP+30]
00401257 PUSH ECX ; /String
00401258 CALL EBX ; \lstrlenA
0040125A MOV ESI,1D
0040125F XOR EDI,EDI
00401261 SUB ESI,EAX
00401263 TEST ESI,ESI
00401265 JLE SHORT CrackMe_.0040127E
00401267 /LEA EDX,DWORD PTR SS:[ESP+30] ; newname后再加上name前B个字符
0040126B |PUSH EDX
0040126C |CALL EBX ; lstrlenA
0040126E |MOV CL,BYTE PTR SS:[ESP+EDI+F8]
00401275 |INC EDI
00401276 |CMP EDI,ESI
00401278 |MOV BYTE PTR SS:[ESP+EAX+30],CL
0040127C \JL SHORT CrackMe_.00401267
0040127E LEA EDX,DWORD PTR SS:[ESP+1C0]
00401285 PUSH 0C9 ; /Count = C9 (201.)
0040128A PUSH EDX ; |Buffer
0040128B PUSH 3E9 ; |ControlID = 3E9 (1001.)
00401290 PUSH EBP ; |hWnd
00401291 CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>] ; \GetDlgItemTextA
00401297 CMP EAX,1D
0040129A JNZ SHORT CrackMe_.00401305 ; 注册码长度klen=29
0040129C PUSH EAX
0040129D LEA EAX,DWORD PTR SS:[ESP+1C4]
004012A4 PUSH EAX
004012A5 CALL CrackMe_.00401320 ; 算法call2:必须为字符且做小写转为大写
004012AA ADD ESP,8
004012AD TEST EAX,EAX
004012AF JE SHORT CrackMe_.00401305
004012B1 XOR EDX,EDX
004012B3 /MOV AL,BYTE PTR SS:[ESP+EDX+30] ; newname[i]
004012B7 |SUB AL,41 ; A=newname[i]-0x41
004012B9 |XOR ECX,ECX ; ione=0
004012BB |MOVSX EAX,AL
004012BE |LEA ESI,DWORD PTR DS:[EAX+EAX*2] ; B=3A
004012C1 |LEA EAX,DWORD PTR DS:[EAX+ESI*4] ; C=13A
004012C4 |LEA ESI,DWORD PTR SS:[ESP+EAX*2+288] ; D=esp+26A+0x288 ,在esp+0x288处有大量字符串,设为mstr3
004012CB |MOV AL,BYTE PTR SS:[ESP+EDX+1C0] ; key[i] ,key为用户输入的注册码
004012D2 |/CMP AL,BYTE PTR DS:[ESI+ECX] ; 用key[i]与mstr3[D+ione]比较
004012D5 ||JNZ SHORT CrackMe_.004012E9
004012D7 ||MOV BL,BYTE PTR SS:[ESP+EDX+10] ; mstr1[i] ,mstr1= ASCII "TRADECANMAKEEVERYONEBETTEROFF"
004012DB ||CMP BL,BYTE PTR SS:[ESP+ECX+288] ; mstr3[ione],实际只用了前26个字母,可新设mstr2[30]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
004012E2 ||JNZ SHORT CrackMe_.00401305 ;必须相等
004012E4 ||MOV ECX,1D
004012E9 ||INC ECX ;ione++
004012EA ||CMP ECX,1D ;ione是否小于29
004012ED |\JL SHORT CrackMe_.004012D2
004012EF |INC EDX
004012F0 |CMP EDX,1D
004012F3 \JL SHORT CrackMe_.004012B3
004012F5 POP EDI
004012F6 POP ESI
004012F7 POP EBP
004012F8 MOV EAX,1
004012FD POP EBX
004012FE ADD ESP,51C
00401304 RETN
/////////////////////////////////////////////////////////////////////////
算法call2:必须为字符且做小写转为大写
/////////////////////////////////////////////////////////////////////////
00401320 PUSH EBX
00401321 MOV EBX,DWORD PTR SS:[ESP+C]
00401325 PUSH ESI
00401326 XOR ESI,ESI ; 参数2
00401328 TEST EBX,EBX
0040132A PUSH EDI
0040132B JLE SHORT CrackMe_.0040137A
0040132D MOV EDI,DWORD PTR SS:[ESP+10] ; 参数1
00401331 /CMP DWORD PTR DS:[406300],1
00401338 |JLE SHORT CrackMe_.0040134E
0040133A |MOVSX EAX,BYTE PTR DS:[ESI+EDI] ;
0040133E |PUSH 103
00401343 |PUSH EAX
00401344 |CALL CrackMe_.0040145C
00401349 |ADD ESP,8
0040134C |JMP SHORT CrackMe_.00401361
0040134E |MOVSX ECX,BYTE PTR DS:[ESI+EDI] ;
00401352 |MOV EDX,DWORD PTR DS:[4060F4] ; CrackMe_.004060FE
00401358 |MOV AX,WORD PTR DS:[EDX+ECX*2]
0040135C |AND EAX,103
00401361 |TEST EAX,EAX
00401363 |JE SHORT CrackMe_.00401383 ; 不能为数字
00401365 |MOVSX EAX,BYTE PTR DS:[ESI+EDI]
00401369 |PUSH EAX
0040136A |CALL CrackMe_.00401390 ; 小写转为大写
0040136F |ADD ESP,4
00401372 |MOV BYTE PTR DS:[ESI+EDI],AL
00401375 |INC ESI
00401376 |CMP ESI,EBX
00401378 \JL SHORT CrackMe_.00401331
0040137A POP EDI
0040137B POP ESI
0040137C MOV EAX,1
00401381 POP EBX
00401382 RETN
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
算法总结:
1) 用户名必须大于3小于16,注册码必须为29位,注册码应该不能为数字吧.
2) 用户名循环填充到29位
3) 先用[newname[i]-0x41]*26算去基地址D
4) 再用mstr1[i]在mstr2中找到第二个地址ione
5) D+ione就是key[i]在mstr3中的位置
代码如下:
void CCrackme_hxd001Dlg::OnOK()
{
// TODO: Add extra validation here
char name[20];
int nlen;
nlen=GetDlgItemText(IDC_EDIT1,name,20);
if(nlen<4||nlen>16)
{
MessageBox("用户名大于4小于16!");
return ;
}
//初始化
char key[30]="";
char newname[30];
char mstr1[30]="TRADECANMAKEEVERYONEBETTEROFF";
char mstr2[30]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char mstr3[677]="ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXY\
ZACDEFGHIJKLMNOPQRSTUVWXYZABDEFGHIJKLMNOPQRSTUVWXY\
ZABCEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXY\
ZABCDEGHIJKLMNOPQRSTUVWXYZABCDEFHIJKLMNOPQRSTUVWXY\
ZABCDEFGIJKLMNOPQRSTUVWXYZABCDEFGHJKLMNOPQRSTUVWXY\
ZABCDEFGHIKLMNOPQRSTUVWXYZABCDEFGHIJLMNOPQRSTUVWXY\
ZABCDEFGHIJKMNOPQRSTUVWXYZABCDEFGHIJKLNOPQRSTUVWXY\
ZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMNPQRSTUVWXY\
ZABCDEFGHIJKLMNOQRSTUVWXYZABCDEFGHIJKLMNOPRSTUVWXY\
ZABCDEFGHIJKLMNOPQSTUVWXYZABCDEFGHIJKLMNOPQRTUVWXY\
ZABCDEFGHIJKLMNOPQRSUVWXYZABCDEFGHIJKLMNOPQRSTVWXY\
ZABCDEFGHIJKLMNOPQRSTUWXYZABCDEFGHIJKLMNOPQRSTUVXY\
ZABCDEFGHIJKLMNOPQRSTUVWYZABCDEFGHIJKLMNOPQRSTUVWX\
ZABCDEFGHIJKLMNOPQRSTUVWXY";
int i,m,ione;
for(i=0;i<29;i++)
{
m=i%nlen;
newname[i]=name[m];
}
newname[29]='\0';
strupr(newname);
for(i=0;i<29;i++)
{
m=newname[i]-0x41;
ione=0;
while(mstr1[i]!=mstr2[ione])ione++;
ione=26*m+ione;
key[i]=mstr3[ione];
}
key[i]='\0';
SetDlgItemText(IDC_EDIT2,key);
}
例如:
用户名:ccbhcsy
注册码:VTBKGUYPOBRGWTGTZVPWZGVULTGDH
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年11月20日 15:40:49
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课