工具:sice4.05,tc2
环境:win98
对象:冷雨飘心的第二个crackme
下载地址:http://person.longcity.net/home3/feeling/crack/files/crkme2.zip
下断点getdlgitemtexta:
0167:0040115C PUSH 32
0167:0040115E PUSH 00403026
0167:00401163 PUSH 000003ED
0167:00401168 PUSH DWORD PTR [EBP+08]
0167:0040116B CALL USER32!GetDlgItemTextA
//取得name,放在00403026
0167:00401170 MOV [00403270],EAX
//EAX内是name的字符数
0167:00401175 CMP EAX,00
//看name是否为空
0167:00401178 JZ 00401389
//是就报错
0167:0040117E LEA ESI,[00403026]
0167:00401184 CALL 004014B0
//对输入的name加工。加工结果放在004030DB
0167:00401189 MOV EAX,[004030DB]
0167:0040118E MOV EDX,[004030DF]
0167:00401194 PUSH 004031BB
0167:00401199 PUSH 32
0167:0040119B PUSH 0D
0167:0040119D PUSH DWORD PTR [00403494]
0167:004011A3 CALL USER32!SendMessageA
//取得serial,放在004031bb
0167:004011A8 OR EAX,EAX
//看serial是否为空
0167:004011AA JZ 00401389
//是就报错
0167:004011B0 LEA ESI,[004031BB]
0167:004011B6 MOV DWORD PTR [ESI+EAX],00000000
0167:004011BD PUSH ESI
0167:004011BE POP EDI
0167:004011BF MOV AL,10
0167:004011C1 ADD AL,1D
0167:004011C3 MOV ECX,EAX
0167:004011C5 REPNZ SCASB
//看serial内是否有"-"
0167:004011C7 JNZ 0040129
//没有就说serial格式不对
0167:004011CD MOV EAX,[ESI]
//取serial前4个字节
0167:004011CF XOR EAX,4743435F
//看是否为"_CCG"。"_CCG"的ASCII码为5F434347
0167:004011D4 JNZ 004012A4
//不是就报错
0167:004011DA LEA ESI,[004031BB]
0167:004011E0 ADD ESI,05
//取serial第5个字节以后的数据
0167:004011E3 CALL 0040172F
//检查serial是否符合要求。必须有8个字节,
//内容只能是0-9和A-F,转换为16进制字符串。
//比如我输入的是_CCG-00000001-00000002,
//转换成0x00000001
0167:004011E8 XOR EAX,-01
//输入的还不能全为0否则也报错
0167:004011EB JZ 004012A4
0167:004011F1 XOR EAX,-01
0167:004011F4 MOV [004030E3],EAX
0167:004011F9 LEA ESI,[004031BB]
0167:004011FF ADD ESI,0E
//同上,检查00000002
0167:00401202 CALL 0040172F
0167:00401207 XOR EAX,-01
0167:0040120A JZ 004012A4
0167:00401210 XOR EAX,-01
0167:00401213 MOV [004030E7],EAX
0167:00401218 MOV EAX,[004030E3]
0167:0040121D MOV EDX,[004030E7]
0167:00401223 CALL 00401636
//关键部分:通过00000001和00000002混合运算得到两16进制数
//为中间结果
0167:00401228 MOV EAX,[004030EB]
//00000001的放在EAX里
0167:0040122D MOV EDX,[004030EF]
//00000002的放在EDX里
0167:00401233 XOR EAX,[004030DB]
//检查0000001的中间结果是否为[004030DB],即name加工的结果
0167:00401239 JNZ 004012A4
//不是就报错
0167:0040123B XOR EDX,[004030DF]
//检查0000002的中间结果是否为0x656d7568
0167:00401241 JNZ 004012A4
//不是就报错
0167:00401243 JMP 004012BD
//注册成功画面
下面是序列号生成程序,在TC2下调试通过。
#include <stdio.h>
#include <dos.h>
unsigned long ESI[] = {
0x6d797468,
0x6d797468,
0x6d797468,
0x6c6f7665,
0x6c6f7665,
0x6c6f7665,
0x6c6f7665,
0x43525950,
0x43525950,
0x43525950,
0x43525950,
0x68656865,
0x68656865,
0x68656865,
0x68656865,
0x476f6f64};
unsigned long ror(unsigned long a, unsigned long b)
{
for(; b > 0; b --)
{
if((a & 0x00000001) == 0x00000001)
{
a = a >> 1;
a = a + 0x80000000;
}
else
a = a >> 1;
}
return a;
}
unsigned long rol(unsigned long a, unsigned long b)
{
for(; b > 0; b --)
{
if((a & 0x80000000) == 0x80000000)
{
a = a << 1;
a = a + 0x00000001;
}
else
a = a << 1;
}
return a;
}
void main()
{
unsigned char name[32], name_length;
unsigned long t = 0, ans = 0;
unsigned char a, b, l;
unsigned long ecx = 0, edi = 0;
int i;
unsigned long eax =
0x00000000;
unsigned long edx =
0x656d7568;
for(i = 0; i < 32; i ++) name[i] = 0;
printf("\nPlease input your name:");
gets(name);
name_length = strlen(name);
if(name_length >= 20)
{
ans = name_length;
ans = ans << 16;
t = 0;
for(i = 1; i < 32; i ++)
t = t + name[i] * i;
t = t ^ 0xffffffff;
t = t & 0x0000ffff;
ans = ans + t;
}
else
{
l = name_length;
for(i = strlen(name) - 1; i < 32; i
++)
{
a = name[i];
b = a;
a = a / l;
b = b * l;
a = a + b;
name[l]= (char)a;
l ++;
}
a = 0;
for(i = 0; i < name_length; i ++)
a = a + name[i];
ans = ans + a;
ans = ror(ans, 8);
ans = ans + 0x200000;
t = 0;
for(i = 1; i < 32; i ++) t
= t + name[i] * i;
t = t ^ 0xffffffff;
t = t & 0x0000ffff;
ans = ans + t;
}
eax = ans + 0x20434347;
edx = edx + 0x26424347;
i = 15;
for(edi = 1; edi <= 8; edi ++)
{
ecx = edx;
eax = eax ^ edx;
ecx = ecx & 0x0000001f;
eax = rol(eax, ecx);
eax = eax + ESI[i];
i --;
ecx = eax;
edx = edx ^ eax;
ecx = ecx & 0x0000001f;
edx = rol(edx, ecx);
edx = edx + ESI[i];
i --;
}
printf("\n下面是您的序列号:");
printf("\n_CCG-%08lx-%08lx\n", eax, edx);
printf("里面的字母应该为大写,请自己修正。");
}
请大家指正,谢谢!
shengzan@263.net
- 标 题:冷雨飘心的第二个crackme的破解方法,大家看看对不对! (5千字)
- 作 者:赞盛
- 时 间:2001-10-18 21:19:43
- 链 接:http://bbs.pediy.com