-
-
[原创]crackme的注册码分析(第一次做keygen)
-
发表于:
2010-9-5 08:34
7379
-
[原创]crackme的注册码分析(第一次做keygen)
【软件名称】SplishSplash
【使用工具】ollydbg
【作者】IT小小鸟
【声明】我是初学者,报着请教的心愿,希望各位前辈不吝赐教!!!
1.下断点bp GetDlgItemTextA,输入name为starstarstarstar,serial为7474747474747474,断在以下,name和serial都必须为16个字符
0040143D 6A 1F PUSH 1F
0040143F 68 A6304000 PUSH SplishSp.004030A6
00401444 68 EB030000 PUSH 3EB
00401449 FF75 08 PUSH DWORD PTR SS:[EBP+8]
0040144C E8 DB010000 CALL <JMP.&user32.GetDlgItemTextA>
00401451 83F8 00 CMP EAX,0
00401454 74 47 JE SHORT SplishSp.0040149D
00401456 8D05 3A304000 LEA EAX,DWORD PTR DS:[40303A]
0040145C 8D1D A6304000 LEA EBX,DWORD PTR DS:[4030A6]
00401462 8038 00 CMP BYTE PTR DS:[EAX],0
00401465 74 0C JE SHORT SplishSp.00401473
00401467 8A08 MOV CL,BYTE PTR DS:[EAX]
00401469 8A13 MOV DL,BYTE PTR DS:[EBX]
0040146B 38D1 CMP CL,DL
0040146D 75 1A JNZ SHORT SplishSp.00401489
0040146F 40 INC EAX
00401470 43 INC EBX
00401471 ^ EB EF JMP SHORT SplishSp.00401462
00401473 6A 00 PUSH 0
00401475 68 56304000 PUSH SplishSp.00403056 ; hardcoded
0040147A 68 60304000 PUSH SplishSp.00403060 ; yes, you find the hardcoded serial!
0040147F FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401482 E8 D5010000 CALL <JMP.&user32.MessageBoxA>
00401487 EB 14 JMP SHORT SplishSp.0040149D
00401489 6A 00 PUSH 0
0040148B 68 56304000 PUSH SplishSp.00403056 ; hardcoded
00401490 68 84304000 PUSH SplishSp.00403084 ; this is not the hardcoded serial!
00401495 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401498 E8 BF010000 CALL <JMP.&user32.MessageBoxA>
0040149D E9 E7000000 JMP SplishSp.00401589
004014A2 817D 10 EF03000>CMP DWORD PTR SS:[EBP+10],3EF
004014A9 0F85 DA000000 JNZ SplishSp.00401589
004014AF 6A 1F PUSH 1F
004014B1 68 0F314000 PUSH SplishSp.0040310F ; ASCII "2012302020123012"
004014B6 68 ED030000 PUSH 3ED
004014BB FF75 08 PUSH DWORD PTR SS:[EBP+8]
004014BE E8 69010000 CALL <JMP.&user32.GetDlgItemTextA>
004014C3 A3 5C314000 MOV DWORD PTR DS:[40315C],EAX //取得name的长度
004014C8 6A 1F PUSH 1F
004014CA 68 2F314000 PUSH SplishSp.0040312F ; ASCII "7474747474747474"
004014CF 68 EE030000 PUSH 3EE
004014D4 FF75 08 PUSH DWORD PTR SS:[EBP+8]
004014D7 E8 50010000 CALL <JMP.&user32.GetDlgItemTextA>
004014DC A3 60314000 MOV DWORD PTR DS:[403160],EAX //取得serial的长度
004014E1 3B05 5C314000 CMP EAX,DWORD PTR DS:[40315C] //比较name和serial的长度
004014E7 0F85 80000000 JNZ SplishSp.0040156D //不等则死
004014ED 833D 60314000 0>CMP DWORD PTR DS:[403160],0 //serial是否为空
004014F4 74 77 JE SHORT SplishSp.0040156D //跳则死
----------------------------------------------------------------------------------------------------
2.下面是关键算法处
004014F6 60 PUSHAD
004014F7 33C0 XOR EAX,EAX
004014F9 8D35 0F314000 LEA ESI,DWORD PTR DS:[40310F] //取name的地址
004014FF 8B0D 5C314000 MOV ECX,DWORD PTR DS:[40315C] //取name的长度
00401505 33DB XOR EBX,EBX
00401507 8A4431 FF MOV AL,BYTE PTR DS:[ECX+ESI-1] //逆序取name的每一位
0040150B 43 INC EBX //EBX自加
0040150C 33C3 XOR EAX,EBX //取出的name每位与EBX异或,code^=b
0040150E 3C 44 CMP AL,44 //与44比较
00401510 ^ 72 F9 JB SHORT SplishSp.0040150B //小于,继续循环
00401512 3C 4D CMP AL,4D //与4D比较
00401514 ^ 77 F5 JA SHORT SplishSp.0040150B //大于,继续循环
00401516 884431 FF MOV BYTE PTR DS:[ECX+ESI-1],AL
0040151A 806C31 FF 14 SUB BYTE PTR DS:[ECX+ESI-1],14 //code-=0x14
0040151F 49 DEC ECX
00401520 83F9 00 CMP ECX,0
00401523 ^ 77 E2 JA SHORT SplishSp.00401507
00401525 61 POPAD
00401526 8D05 0F314000 LEA EAX,DWORD PTR DS:[40310F]
0040152C 8D1D 2F314000 LEA EBX,DWORD PTR DS:[40312F]
00401532 8038 00 CMP BYTE PTR DS:[EAX],0 //serial每一位ASCII码与0比较
00401535 74 0C JE SHORT SplishSp.00401543 //相等则注册成功
00401537 8A08 MOV CL,BYTE PTR DS:[EAX] // 假serial与算出的serial每位比较
00401539 8A13 MOV DL,BYTE PTR DS:[EBX]
0040153B 38D1 CMP CL,DL
0040153D 75 1A JNZ SHORT SplishSp.00401559 //不等则死
0040153F 40 INC EAX
00401540 43 INC EBX
00401541 ^ EB EF JMP SHORT SplishSp.00401532
00401543 6A 00 PUSH 0
00401545 68 56304000 PUSH SplishSp.00403056 ; hardcoded
0040154A 68 D2304000 PUSH SplishSp.004030D2 ; yes, you got a correct combination
0040154F FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401552 E8 05010000 CALL <JMP.&user32.MessageBoxA>
00401557 EB 14 JMP SHORT SplishSp.0040156D
00401559 6A 00 PUSH 0
0040155B 68 56304000 PUSH SplishSp.00403056 ; hardcoded
00401560 68 F5304000 PUSH SplishSp.004030F5 ; this combination is shit!
00401565 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401568 E8 EF000000 CALL <JMP.&user32.MessageBoxA>
3.总结
1.name和serial的长度必须都为16个字符
2.F(name)=serial,逆序处理name的每位,与变量ebx异或
此crackme还有两个任务,去掉NAG窗口,找出hardcode,都比较简单。就不赘述了。
【注册机】
因为要求不能用控制台,用的vc,关键代码如下
void CKeygenDlg::OnSerial()
{
// TODO: Add your control notification handler code here
char username[16],serial[16],code=0,b=0;
int num;
num=::GetDlgItemText(m_hWnd,IDC_USERNAME,username,31);
if(num==16)
{
// 逆序取name的每一位
for(int i=16;i>0;i--)
{
code=username[i-1];
do
{
b++;
code=code^b;
} while (code<0x44 || code>0x4d);
code-=0x14;
serial[i-1]=code;
}
serial[16]='\0';
CString str;
str.Format("%s",serial);
AfxMessageBox("注册码为:\n"+str);
}
else
{
AfxMessageBox("name长度为16个字符!");
}
}
此Crackme算法简单,适合新手练兵(比如我),贴上全文,高手莫笑!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!