-
-
[原创]happytown的“我的第7个CrackMe”算法分析
-
发表于:
2005-11-2 13:13
8227
-
[原创]happytown的“我的第7个CrackMe”算法分析
我是个刚学破解一个月左右的菜鸟,还是第一次发表破文,前面shooooo大侠早就破解出来了,我就介绍一下算法吧,请各位多指教。
本地下载:http://bbs.pediy.com/upload/2005/37/files/crackme_0007.rar
用PEID检查,没加壳,用Ollydbg打开,随便输入用户名和试练码,下断点于GetDlgItemTextA。
以下没指明时的位数是指输入的试练码位数,由于篇幅,F7步进的部分就没有写出来了,除了GetDlgItemTextA,以下绝大部分有备注处的Call都需要用F7进入。
0040150F call <jmp.&user32.GetDlgItemT>
; 断点GetDlgItemTextA
00401514 lea ecx,dword ptr ds:[403020]
; 用户名长度区域80(128.)
0040151A mov dword ptr ds:[4030A0],ecx
00401520 mov dword ptr ds:[4030A4],eax
; 用户输入的用户名长度
00401525 cmp dword ptr ds:[4030A4],4
; 用户名长度不小于4位,否则over
0040152C jnb short CrackMe.00401532
0040152E leave
0040152F retn 10
00401532 push 100
00401537 push CrackMe.004030AC ; |Buffer = CrackMe.004030AC
0040153C push 3ED ; |ControlID = 3ED (1005.)
00401541 push dword ptr ss:[ebp+8] ; |hWnd
00401544 call <jmp.&user32.GetDlgItemT>; \GetDlgItemTextA
00401549 mov dword ptr ds:[4030A8],eax
; 用户输入的注册码长度
0040154E cmp eax,10
; 注册码长度长度为16,否则over
00401551 je short CrackMe.00401557
00401553 leave
00401554 retn 10
00401557 lea ecx,dword ptr ds:[4030AC]
0040155D mov dword ptr ds:[4031AC],ecx
00401563 call CrackMe.00401068
; 第1位要等于H
00401568 xor eax,eax
0040156A call CrackMe.0040109D
; 第2位要等于T
0040156F or eax,edx
00401571 call CrackMe.004010D2
; 第3位要等于-
00401576 test eax,eax
00401578 call CrackMe.00401107
; 第4位要等于7
0040157D xor ecx,eax
0040157F call CrackMe.0040113C
; 5、7位相加 = 10、11位相加,且要是偶数
00401584 not ecx
00401586 push dword ptr ds:[4030A4]
0040158C push dword ptr ds:[4031AC]
00401592 call CrackMe.0040120E
; 用户名各位相加除用户名长度应等于注册码第6位
00401597 add ecx,dword ptr ds:[4030A4]
0040159D call CrackMe.004011A1
; 注册码8、9位相加=用户名第2位、倒数第2位相加
004015A2 xchg eax,ecx
004015A3 shl eax,1
004015A5 mov edx,eax
004015A7 call CrackMe.00401252
004015AC mov eax,12345678
004015B1 call CrackMe.004012A3
004015B6 add eax,ecx
004015B8 call CrackMe.004012EF
; 注册码13位+6位要是奇数
004015BD xor ecx,ecx
004015BF push dword ptr ds:[4030A0]
004015C5 call CrackMe.0040102D
004015CA call CrackMe.00401340
; 注册码13~15位相加+用户名长度=10A
004015CF add ecx,ebx
004015D1 push 100
004015D6 push CrackMe.004030AC
004015DB push 3ED
004015E0 push dword ptr ss:[ebp+8]
004015E3 call <jmp.&user32.GetDlgItemT>
004015E8 mov ecx,eax
004015EA rol ecx,5
004015ED mov eax,ecx
004015EF call CrackMe.004013A0
; 如果前面都正确,这里就能得到FFF
004015F4 sub eax,ecx
004015F6 cmp dword ptr ds:[4031B0],0FF>
; 对比结果是否等于0FFF
00401600 jnz short CrackMe.00401616
; 这里相等就成功了
00401602 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401604 push CrackMe.004020D0 ; |Title = "Congratulations"
00401609 push CrackMe.004020C1 ; |Text = "GOOD JOB, MAN!"
0040160E push dword ptr ss:[ebp+8] ; |hOwner
; 这里成功后会有对话框"GOOD JOB, MAN!"
*******************************************************************
算法总结:
1. 用户名长度要在4位以上,注册码是16位;
2. 注册码前4位为HT-7,我猜测是H(appy)T(own Crackme)-7;
3. 注册码5、7位的和=10、11位的和, 而且相加的和要是偶数;
4. 用户名各位相加,除用户名长度,等于注册码第6位;
5. 注册码8、9位的和 = 用户名2、倒数第2位的和
6. 注册码13位和第6位相加的和要是奇数
7. 而且(13、14、15位相加) + 名长 = 10A;
8. 16位=用户名倒数第2位
9. 注册码第12位没什么要求,填个数字1吧。
以下是在Win-TC里用C语言写的注册机:
/******************************************************************
happytown crackme 7 C语言注册机- By hud, November 2, 2005
******************************************************************/
#include <stdio.h>
void main()
{
char name[20], sn[17] = "HT-7"; /*前4位是HT-7:h(appy)t(own crackme)7 */
int i, len, x = 0;
printf("Input name(>=4):\n");
scanf("%s", name);
len = strlen(name);
if (len<4) /*用户名要4位以上 */
{
printf("Name at least 4 character!\n");
return;
}
for (i=0; i<len; ++i) /*用户名各位相加 */
x += name[i];
x /= len; /*用户名各位相加和除用户名长度 */
sn[5] = x; /*商即是第6位sn[5](C语言数组以0为基数) */
sn[4] = sn[9] = '5'; /*注册码5、7位和=10、11位和,且为偶数 */
sn[6] = sn[10] = '7';
sn[7] = name[1]; /*注册码8、9位和=用户名第2位和倒数2位相加 */
sn[8] = name[len-2];
x = (0x10A - len)/3; /*注册码13~15位的和减用户名长度要等于10A */
if ((sn[5] + x)%2) /*而且注册码13位和第6位相加为奇数 */
{
sn[12] = x;
sn[13] = x - 1;
}
else
{
sn[12] = x - 1;
sn[13] = x;
}
sn[14] = 0x10A - x*2 + 1 - len; /*这几步求13~15位和减用户名长=10A */
sn[15] = name[len-2]; /*注册码第16位要等于用户名倒数第2位 */
sn[11] = '1'; /*第12位好像没要求 */
sn[16] = '\0';
printf("SN is: %s\n", sn);
getch();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)