【文章标题】: HappyTown的第21个CrackMe分析
【文章作者】: Horst Stein
【作者邮箱】: [email]horststein@hotmail.com[/email]
【软件名称】: HappyTown's CrackMe_0021
【下载地址】:
http://bbs.pediy.com/showthread.php?s=&threadid=32213
【保护方式】: 序列号
【使用工具】: OD,PEiD,Kanal,IDA,W32DSAM,DAMN_HashCalc,OpenSSL库
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
首先感谢HappyTown为我们带来这么好的CrackMe。
用到了OpenSSL库。
一、基本情况分析:
1. 用PEiD分析,发现未加壳;
2. 用Kanal查看得知使用了MD5,用IDA加载openssl的sig文件后,导出MAP文件;
3. 随便输入信息,发现未有出错提示;
4. 但用W32DASM发现了Congratulations。它的前面有个je的跳转,再往前有个call 00401130在00401081处。
二、正式开工:
1. OD载入,用bp 401081下断点,并加载刚才生成的MAP文件;
2. 运行程序,输入假码:
name: HorstStein
sn:9876543210ABCDEF (为什么是16个字符,请看下面)
3. 点击Check被断,进入00401130:
00401130 />sub esp, 3CC
00401136 |>push ebx
00401137 |>push ebp
00401138 |>push esi
00401139 |>push edi
0040113A |>mov ecx, 31
0040113F |>xor eax, eax
00401141 |>lea edi, [esp+165]
00401148 |>mov byte ptr [esp+164], 0
00401150 |>rep stos dword ptr es:[edi]
00401152 |>stos word ptr es:[edi]
00401154 |>stos byte ptr es:[edi]
00401155 |>mov ecx, 31
0040115A |>xor eax, eax
0040115C |>lea edi, [esp+41]
00401160 |>mov byte ptr [esp+40], 0
00401165 |>rep stos dword ptr es:[edi]
00401167 |>stos word ptr es:[edi]
00401169 |>stos byte ptr es:[edi]
0040116A |>mov esi, [esp+3E0]
00401171 |>xor eax, eax
00401173 |>mov edi, [<&USER32.GetDlgItemTextA>] ; USER32.GetDlgItemTextA
00401179 |>mov [esp+29], eax
0040117D |>mov [esp+2D], eax
00401181 |>xor ecx, ecx
00401183 |>lea edx, [esp+164]
0040118A |>mov [esp+31], eax
0040118E |>mov [esp+21], ecx
00401192 |>push 0C9 ; /Count = C9 (201.)
00401197 |>push edx ; |Buffer
00401198 |>mov [esp+3D], ax ; |
0040119D |>mov ebx, 4 ; |
004011A2 |>mov [esp+2D], cx ; |
004011A7 |>push 3E8 ; |ControlID = 3E8 (1000.)
004011AC |>push esi ; |hWnd
004011AD |>mov byte ptr [esp+38], 0 ; |
004011B2 |>mov [esp+47], al ; |
004011B6 |>mov [esp+20], bl ; |//密钥从[esp+20]开始;bl=04
004011BA |>mov byte ptr [esp+21], 0B5 ; |
004011BF |>mov byte ptr [esp+22], 52 ; |
004011C4 |>mov byte ptr [esp+23], 6C ; |
004011C9 |>mov byte ptr [esp+24], 0DC ; |
004011CE |>mov byte ptr [esp+25], 6 ; |
004011D3 |>mov byte ptr [esp+26], 0C4 ; |
004011D8 |>mov byte ptr [esp+27], 0DF ; |
004011DD |>mov byte ptr [esp+28], 87 ; |
004011E2 |>mov byte ptr [esp+29], 0C2 ; |
004011E7 |>mov byte ptr [esp+2A], 0AA ; |
004011EC |>mov byte ptr [esp+2B], 75 ; |
004011F1 |>mov byte ptr [esp+2C], 0DE ; |
004011F6 |>mov byte ptr [esp+2D], 7 ; |
004011FB |>mov [esp+2E], bl ; |bl=04
004011FF |>mov byte ptr [esp+2F], 8 ; |\\密钥到[esp+2F]结束,长度16
00401204 |>mov [esp+30], al ; |
00401208 |>mov [esp+37], cl ; |
0040120C |>call edi ; \GetDlgItemTextA
0040120E |>mov ebp, eax ; len(name)
00401210 |>cmp ebp, ebx ; name长度不小于4
00401212 |>jge short 00401221
00401214 |>pop edi
00401215 |>pop esi
00401216 |>pop ebp
00401217 |>xor eax, eax
00401219 |>pop ebx
0040121A |>add esp, 3CC
00401220 |>retn
00401221 |>lea eax, [esp+40]
00401225 |>push 0C9
0040122A |>push eax
0040122B |>push 3E9
00401230 |>push esi
00401231 |>call edi ; 取输入的sn
00401233 |>cmp eax, 10 ; 注册码长度必须为16
00401236 |>je short 00401245
00401238 |>pop edi
00401239 |>pop esi
0040123A |>pop ebp
0040123B |>xor eax, eax
0040123D |>pop ebx
0040123E |>add esp, 3CC
00401244 |>retn
00401245 |>xor esi, esi
00401247 |>/cmp dword ptr [4082E8], 1 ; // 检查输入的序列号sn是否为16进制数,同时转化为小写
0040124E |>|jle short 00401265
00401250 |>|movsx ecx, byte ptr [esp+esi+40]
00401255 |>|push 80
0040125A |>|push ecx
0040125B |>|call <__isctype>
00401260 |>|add esp, 8
00401263 |>|jmp short 00401277
00401265 |>|movsx edx, byte ptr [esp+esi+40]
0040126A |>|mov eax, [4080DC]
0040126F |>|mov al, [eax+edx*2]
00401272 |>|and eax, 80
00401277 |>|test eax, eax
00401279 |>|je short 00401214
0040127B |>|movsx ecx, byte ptr [esp+esi+40]
00401280 |>|push ecx
00401281 |>|call <_tolower>
00401286 |>|add esp, 4
00401289 |>|mov [esp+esi+40], al
0040128D |>|inc esi
0040128E |>|cmp esi, 10
00401291 |>\jl short 00401247 ; \\
00401293 |>xor edi, edi
00401295 |>lea esi, [esp+41]
00401299 |>/cmp dword ptr [4082E8], 1 ; //把sn转化成对应的十六进制
004012A0 |>|jle short 004012B3
004012A2 |>|movsx edx, byte ptr [esi-1]
004012A6 |>|push 2
004012A8 |>|push edx
004012A9 |>|call <__isctype>
004012AE |>|add esp, 8
004012B1 |>|jmp short 004012C3
004012B3 |>|movsx eax, byte ptr [esi-1]
004012B7 |>|mov ecx, [4080DC] ; CrackMe_.004080E6
004012BD |>|mov al, [ecx+eax*2]
004012C0 |>|and eax, 2
004012C3 |>|mov bl, [esi-1]
004012C6 |>|test eax, eax
004012C8 |>|jnz short 004012CF
004012CA |>|sub bl, 30
004012CD |>|jmp short 004012D2
004012CF |>|sub bl, 57
004012D2 |>|cmp dword ptr [4082E8], 1
004012D9 |>|jle short 004012EB
004012DB |>|movsx edx, byte ptr [esi]
004012DE |>|push 2
004012E0 |>|push edx
004012E1 |>|call <__isctype>
004012E6 |>|add esp, 8
004012E9 |>|jmp short 004012FA
004012EB |>|movsx eax, byte ptr [esi]
004012EE |>|mov ecx, [4080DC] ; CrackMe_.004080E6
004012F4 |>|mov al, [ecx+eax*2]
004012F7 |>|and eax, 2
004012FA |>|test eax, eax
004012FC |>|mov al, [esi]
004012FE |>|jnz short 00401304
00401300 |>|sub al, 30
00401302 |>|jmp short 00401306
00401304 |>|sub al, 57
00401306 |>|shl bl, 4
00401309 |>|or bl, al
0040130B |>|add esi, 2
0040130E |>|mov [esp+edi+20], bl
00401312 |>|inc edi
00401313 |>|cmp edi, 8
00401316 |>\jl short 00401299 ; \\
00401318 |>lea edx, [esp+108]
0040131F |>push edx
00401320 |>call <MD5_Init>
//MD5_Init:
00401B80 >/>mov eax, [esp+4] ; MD5_Init
00401B84 |>xor ecx, ecx
00401B86 |>mov dword ptr [eax], 67452301 ; //MD5的4个常数
00401B8C |>mov dword ptr [eax+4], EFCDAB89
00401B93 |>mov dword ptr [eax+8], 98BADCFE
00401B9A |>mov dword ptr [eax+C], 10325476 ; \\
00401BA1 |>mov [eax+10], ecx
00401BA4 |>mov [eax+14], ecx
00401BA7 |>mov [eax+58], ecx
00401BAA |>mov eax, 1
00401BAF \>retn
\\
00401325 |>lea eax, [esp+168]
0040132C |>push ebp ; len(name)
0040132D |>lea ecx, [esp+110]
00401334 |>push eax ; name
00401335 |>push ecx
00401336 |>call <MD5_Update>
0040133B |>lea edx, [esp+118]
00401342 |>lea eax, [esp+38]
00401346 |>push edx
00401347 |>push eax ; //在这里先d eax
00401348 |>call <MD5_Final>
0040134D |>lea ecx, [esp+244] ; \\看内存区,MD5(HorstStein)=82E0134547E6AF1C4D677811201710E7
00401354 |>lea edx, [esp+28]
00401358 |>push ecx ; 由openssl库idea.h头文件可知此乃IDEA_KEY_SCHEDULE结构,即存放子密钥的地方
00401359 |>push edx ; 用于IDEA的key:04 B5 52 6C...向上翻翻看:D
0040135A |>call <_idea_set_encrypt_key> ; 设置IDEA加密密钥
0040135F |>lea eax, [esp+324]
00401366 |>lea ecx, [esp+24C]
0040136D |>push eax
0040136E |>push ecx
0040136F |>call <idea_set_decrypt_key> ; 设置IDEA解密密钥
00401374 |>lea edx, [esp+32C]
0040137B |>lea eax, [esp+60]
0040137F |>push edx
00401380 |>lea ecx, [esp+4C]
00401384 |>push eax
00401385 |>push ecx ; sn
00401386 |>call <_idea_ecb_encrypt> ; 解密sn(ecb模式)
0040138B |>add esp, 34
0040138E |>mov ecx, 2
00401393 |>lea edi, [esp+28]
00401397 |>lea esi, [esp+38]
0040139B |>xor edx, edx
0040139D |>repe cmps dword ptr es:[edi], dword ptr [esi]
0040139F |>pop edi
004013A0 |>mov eax, edx
004013A2 |>pop esi
004013A3 |>pop ebp
004013A4 |>sete al
004013A7 |>pop ebx
004013A8 |>add esp, 3CC
004013AE \>retn
三、其验证算法:
1. h=MD5(name);
2. x=IDEA(sn,Decrypt);
3. 判断h=x否,相等则成功,不等则失败
两组可用的注册码:
name:HorstStein
sn:03CDCA61C437218C
name:pediy
sn:6A46FF71FCCAAC76
四、注册机算法及其代码:
1. 算法:IDEA(MD5(name),Encrypt)。
2. 代码(用到了OpenSSL库):
int main()
{
int i;
int nLenName; //name长度
char szName[150] = {0}; //存放name
MD5_CTX md5;
unsigned char MD5Name[16] = {0}; //存放MD5(szName)的消息摘要
unsigned char cSerial_test[8] = {0}; //临时存放注册码
unsigned char outEn[8]; //存放IDEA的输出
unsigned char szBuffer[150]={0}; //存放注册码
IDEA_KEY_SCHEDULE key; //存放IDEA加密子密钥
unsigned char k[16] = { 0x04,0xB5,0x52,0x6C,0xDC,0x06,0xC4,0xDF,
0x87,0xC2,0xAA,0x75,0xDE,0x07,0x04,0x08};//IDEA密钥
printf("Enter your name:");
scanf("%s",szName);
//MD5(szName)
MD5_Init( &md5);
MD5_Update( &md5, szName, nLenName);
MD5_Final( MD5Name, &md5);
//设置IDEA加密密钥
idea_set_encrypt_key(k,&key);
for (i=0; i<8; i++)
{
cSerial_test[i] = MD5Name[i];
}
//加密MD5(name)
idea_ecb_encrypt(cSerial_test,outEn,&key);
for (i=0; i<8; i++)
{
wsprintf(&szBuffer[i*2], "%02X", *(byte*)(outEn+i));
}
printf("\nSN:%s\n",szBuffer);
return 0;
}
--------------------------------------------------------------------------------
【经验总结】
这个CrackMe的验证方式和很多使用RSA的CrackMe的验证方式类似,所以,值得我等菜鸟一学。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2005年10月09日 19:28:08
[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!