[原创]D4ph1 - Crackme#1分析
发表于:
2005-11-25 10:47
6188
最近在突然在好几个群里看到要求分析D4ph1 - Crackme#1的BBS,拿来看了一下,觉得比较另类,所以贴了篇文章放这里。
软件下载地址:http://www.crackmes.de/users/d4ph1/d4ph1_crackme1
分析过程:
0040110E 6A 40 push 40
00401110 6A 0D push 0D
00401112 68 EA030000 push 3EA
00401117 FF75 08 push dword ptr ss:[ebp+8]
0040111A E8 8D010000 call <jmp.&user32.SendDlgItemMessag>; 取用户名长度
0040111F A2 0D344000 mov byte ptr ds:[40340D],al 00401124 3C 04 cmp al,4 ; 是否大于4位
00401126 0F86 21010000 jbe D4ph1_-_.0040124D ; 小于则跳到下面的用户名出错信息
0040112C 3C 06 cmp al,6 ; 是否等于6位
0040112E 75 07 jnz short D4ph1_-_.00401137 ; 不等就跳到401137处
00401130 C605 0C344000 0>mov byte ptr ds:[40340C],1
00401137 8BD0 mov edx,eax ; 用户名长度放入EDX中
00401139 33DB xor ebx,ebx ; EBX清0
0040113B 33F6 xor esi,esi ; ESI清零
0040113D 8A86 4C334000 mov al,byte ptr ds:[esi+40334C] ; 逐个取用户名的十六进制码(开始循环)
00401143 3086 80324000 xor byte ptr ds:[esi+403280],al ;
00401149 33DB xor ebx,ebx ; EBX清零
0040114B 03D8 add ebx,eax ; EBX=EBX+EAX(EAX中放着用户名的十六进制码)
0040114D 33DA xor ebx,edx ; EDX=用户名位数,EBX做异或运算0040114F 899E 8C334000 mov dword ptr ds:[esi+40338C],ebx ; 结果放入ESI+40338C中保存
00401155 46 inc esi ; 取用户名下一位
00401156 4A dec edx ; edx=edx-1,用户名位数减1,直到取完
00401157 ^ 75 E4 jnz short D4ph1_-_.0040113D ; 没有取完则继续循环
00401159 C686 8C334000 2>mov byte ptr ds:[esi+40338C],2D ; ESI+40338C中存放着最终的用户名计算结果
00401160 68 CC334000 push D4ph1_-_.004033CC
00401165 6A 41 push 41
00401167 6A 0D push 0D
00401169 68 EB030000 push 3EB
0040116E FF75 08 push dword ptr ss:[ebp+8]
00401171 E8 36010000 call <jmp.&user32.SendDlgItemMessag>; 取注册码
00401176 33D2 xor edx,edx ; EDX清零
00401178 0FBEBA CC334000 movsx edi,byte ptr ds:[edx+4033CC] ; 逐个取注册码码的十六进制码放入EDI
0040117F 0FBE9A 8C334000 movsx ebx,byte ptr ds:[edx+40338C] ; 看上面,40338C中放的是用户名的计算结果,放回EDX
00401186 42 inc edx ; EDX=EDX+1,计数器,逐个取
00401187 3BFB cmp edi,ebx ; 用户名的计算结果与注册码的十六进制码逐个对比(关键)
00401189 ^ 74 ED je short D4ph1_-_.00401178 ; 相等就跳到401178继续循环。(不等难道不行?往下看)
0040118B 4A dec edx ; 注册码字符长度减1
0040118C 83F2 45 xor edx,45 ; 注册码长度与45做异或运算,放入EDX
0040118F 83F6 45 xor esi,45 ; ESI放的是用户名长度,与45做异或运算,放入ESI
00401192 2BD6 sub edx,esi ; EDX=EDX-ESI
00401194 75 6A jnz short D4ph1_-_.00401200 ; 不等就跳到401200处还有秘密的NAG----爆破点1,改为JE
00401196 E8 97FEFFFF call D4ph1_-_.00401032 ; 这个CALL很有意思,是We need his first-name的提示
0040119B 803D 0C344000 0>cmp byte ptr ds:[40340C],1
004011A2 75 47 jnz short D4ph1_-_.004011EB
004011A4 BB 47000000 mov ebx,47 ; EBX赋值47
004011A9 0FBEBA CC334000 movsx edi,byte ptr ds:[edx+4033CC] ; 注册码的十六进制码放入EDI
004011B0 0FBEB2 3B334000 movsx esi,byte ptr ds:[edx+40333B] ; 逐个放入ESI
004011B7 03DE add ebx,esi ; EBX=EBX+ESI
004011B9 3BFB cmp edi,ebx ; EBX的值与EDI对比(注册码的十六进制码与计算结果比较一定要相等,也就是说注册码的第一位必须为47=G,其它的按照上面的规律算)
004011BB 75 2E jnz short D4ph1_-_.004011EB ; 不等就跳到4011EB处----爆破点2,NOP掉
004011BD 42 inc edx ; 相等的话继续取下一个
004011BE 83FA 05 cmp edx,5 ; 取剩的位数与5比较
004011C1 ^ 76 E6 jbe short D4ph1_-_.004011A9 ; 小于等于就循环
004011C3 6A 00 push 0
004011C5 68 00304000 push D4ph1_-_.00403000 ; ASCII "Crackme#1 By D4ph1"
004011CA 68 80324000 push D4ph1_-_.00403280
004011CF 6A 00 push 0
004011D1 E8 CA000000 call <jmp.&user32.MessageBoxA> ; 爆破点3--NOP掉去NAG
004011D6 6A 00 push 0
004011D8 68 00304000 push D4ph1_-_.00403000 ; ASCII "Crackme#1 By D4ph1"
004011DD 68 13304000 push D4ph1_-_.00403013 ; ASCII "Great work mate!You passed all the tests!:)" 算法总结:用户名取六位,与注册码长度相等,用户名的十六进制码与该注册码的倒数位置做异或运算,得出的结果要与注册码的十六进制码相等,程序对注册码做了规定,前六位必须为Giffpu,相应的用户名为Albert。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)