【文章作者】: bxm
【作者邮箱】: bxm78@163.com
【保护方式】: name,company,serial
【编写语言】: Borland Delphi 4.0 - 5.0
【使用工具】: peid,od,计算器
【操作平台】: xinxp
【作者声明】: 只是感兴趣,失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
首先用peid查壳,无壳。运行,收集足够的信息,用OD载入,通过字符串“good , this number come from your keygen ?”找到地址004444C7,向上查找,在地址0044438A处下断,成功断下:
0044438A . 8B45 E4 mov eax, [ebp-1C] ; [ebp-1c]存放serial
0044438D . E8 CEF7FBFF call 00403B60 ; 返回serial长度
00444392 . 48 dec eax
00444393 . 0F8C 4C010000 jl 004444E5 ; serial长度为0,失败
00444399 . 8D55 E8 lea edx, [ebp-18]
0044439C . 8B83 D8020000 mov eax, [ebx+2D8]
004443A2 . E8 75F9FDFF call 00423D1C
004443A7 . 8D55 F0 lea edx, [ebp-10]
004443AA . 8B83 D0020000 mov eax, [ebx+2D0]
004443B0 . E8 67F9FDFF call 00423D1C
004443B5 . 8D55 EC lea edx, [ebp-14]
004443B8 . 8B83 D4020000 mov eax, [ebx+2D4]
004443BE . E8 59F9FDFF call 00423D1C ; 得到company长度
004443C3 . 8B45 F0 mov eax, [ebp-10] ; name送eax
004443C6 . E8 95F7FBFF call 00403B60 ; 此函数功能:测试EAX中字符串的长度,放在EAX中返回
004443CB . 83F8 04 cmp eax, 4 ; name长度<4 ?
004443CE . 0F8C 11010000 jl 004444E5 ; 是,失败
004443D4 . 8B45 EC mov eax, [ebp-14] ; company送eax
004443D7 . E8 84F7FBFF call 00403B60
004443DC . 83F8 03 cmp eax, 3 ; company长度<3 ?
004443DF . 0F8C 00010000 jl 004444E5 ; 是,失败
004443E5 . 8B45 F0 mov eax, [ebp-10]
004443E8 . 0FB600 movzx eax, byte ptr [eax] ; name第0个字符入EAX
004443EB . 0FB680 DF5944>movzx eax, byte ptr [eax+4459DF] ; 我得到字符"a"
004443F2 . 8945 F4 mov [ebp-C], eax ; 第1次存入[ebp-c]
004443F5 . 8B45 F0 mov eax, [ebp-10]
004443F8 . 0FB640 02 movzx eax, byte ptr [eax+2] ; name第2个字符入EAX
004443FC . 0FB6B0 DF5944>movzx esi, byte ptr [eax+4459DF] ; 我得到字符"+"
00444403 . 8B45 EC mov eax, [ebp-14]
00444406 . E8 55F7FBFF call 00403B60
0044440B . 8B55 EC mov edx, [ebp-14]
0044440E . 0FB64402 FE movzx eax, byte ptr [edx+eax-2] ; company倒数第2个字符入EAX
00444413 . 0FB6B8 DF5944>movzx edi, byte ptr [eax+4459DF] ; 我得到字符"3"
0044441A . 8B45 EC mov eax, [ebp-14]
0044441D . E8 3EF7FBFF call 00403B60
00444422 . 8B55 EC mov edx, [ebp-14]
00444425 . 0FB64402 FF movzx eax, byte ptr [edx+eax-1] ; company倒数第1个字符入EAX
0044442A . 0FB680 DF5944>movzx eax, byte ptr [eax+4459DF] ; 我得到字符"3"
00444431 . 8B55 F0 mov edx, [ebp-10]
00444434 . 0FB652 03 movzx edx, byte ptr [edx+3] ; name第3个字符入EDX
00444438 . 0FB692 DF5944>movzx edx, byte ptr [edx+4459DF] ; 我得到ASCII码“00”
0044443F . 8B4D EC mov ecx, [ebp-14]
00444442 . 0FB649 02 movzx ecx, byte ptr [ecx+2] ; company第2个字符入ECX
00444446 . 0FB689 DF5944>movzx ecx, byte ptr [ecx+4459DF] ; 我得到字符"#"
0044444D . 0FAFD1 imul edx, ecx
00444450 . 8955 F8 mov [ebp-8], edx ; 第2次结果存入[ebp-8]
00444453 . 8B55 F4 mov edx, [ebp-C] ; 第1次存入结果入EDX
00444456 . 0FAFD6 imul edx, esi
00444459 . 0FAFD7 imul edx, edi
0044445C . 0FAFD0 imul edx, eax
0044445F . 0355 F8 add edx, [ebp-8] ; EDX+第2次存入结果
00444462 . 8955 FC mov [ebp-4], edx ; 第3次结果存入[ebp-4]
00444465 . 8B45 FC mov eax, [ebp-4]
00444468 . 35 D8280000 xor eax, 28D8
0044446D . 05 7D4A8D28 add eax, 288D4A7D
00444472 . 8945 FC mov [ebp-4], eax ; 运算后结果还是存入[ebp-4]
00444475 . 8B45 FC mov eax, [ebp-4]
00444478 . B9 39300000 mov ecx, 3039
0044447D . C1C1 06 rol ecx, 6 ; ECX循环左移6位
00444480 . 35 14970000 xor eax, 9714
00444485 . C1C8 02 ror eax, 2 ; EAX循环右移2位
00444488 . C1F8 03 sar eax, 3 ; EAX算术右移3位
0044448B . 01C8 add eax, ecx
0044448D . 0345 F8 add eax, [ebp-8] ; EAX+第2次存入结果
00444490 . 40 inc eax
00444491 . 66:F7D0 not ax
00444494 . 09C1 or ecx, eax ; 此句多余
00444496 . 05 9A020000 add eax, 29A
0044449B . 8945 FC mov [ebp-4], eax ; 最终运算后结果存入[ebp-4]
0044449E . 33C0 xor eax, eax
004444A0 . 55 push ebp
004444A1 . 68 DB444400 push 004444DB
004444A6 . 64:FF30 push dword ptr fs:[eax]
004444A9 . 64:8920 mov fs:[eax], esp
004444AC . 8D55 E0 lea edx, [ebp-20]
004444AF . 8B83 D8020000 mov eax, [ebx+2D8]
004444B5 . E8 62F8FDFF call 00423D1C
004444BA . 8B45 E0 mov eax, [ebp-20]
004444BD . E8 4E36FCFF call 00407B10 ; 此函数功能:测试有无0~9以外的字符,如有,失败,否则,检查其值是否大于0CCCCCCC,是,失败。如符合要求,把serial转换成十六进制的数
004444C2 . 3B45 FC cmp eax, [ebp-4] ; 比较最终运算结果与serial转换结果
004444C5 . 75 0A jnz short 004444D1 ; 爆破点
004444C7 . B8 24454400 mov eax, 00444524 ; good , this number come from your keygen ?
004444CC . E8 A3FAFFFF call 00443F74
算法小结:
1、name长度必须大于>=4,company长度必须>=3。
2、通过name第0个字符查表,结果记为A。
3、通过name第3个字符查表得到的结果与company第2个字符查表得到的结果相乘,结果记为B。
4、A*name第2个字符查表的结果*company倒数第2个字符查表的结果*company倒数第1个字符查表的结果+B,结果记为C。
5、C与28D8异或,再加上288D4A7D,然后再与9714异或,结果记为D。
6、D循环右移2位,再算术右移3位,然后加上C0E40,再加上B+1,结果记为E。
7、E的低16位求反后再加上29A。把结果转成十进制即成serial.
可用的一组注册码:
naem:bxm78
company:wuchengxx
serial:22372486
注意:有时name和company算不出serial.
附注册机源码,费了好大力气才调试成功。
#include<string.h>
main()
{
short int namelen,companylen;
unsigned long temp,temp1,temp2,temp3;
char name[50],company[50];
char table[127]={
'\x00','\x10','\x39','\x44','\x00','\x24','\x39','\x44','\x00','\x0C','\xAF','\x40','\x00','\x14','\xAF','\x40',
'\x00','\x1C','\xAF','\x40','\x00','\x24','\xAF','\x40','\x00','\x34','\xAF','\x40','\x00','\x3C','\xAF','\x40',
'\x00','\x44','\xAF','\x40','\x00','\x4C','\xAF','\x40','\x00','\x54','\xAF','\x40','\x00','\x5C','\xAF','\x40',
'\x00','\x2C','\xAF','\x40','\x00','\x06','\x00','\x00','\x00','\x07','\x00','\x00','\x00','\x01','\x00','\x00',
'\x00','\x02','\x00','\x00','\x00','\x03','\x00','\x00','\x00','\x04','\x00','\x00','\x00','\x05','\x00','\x00',
'\x00','\x08','\x00','\x00','\x00','\x09','\x00','\x00','\x00','\x0A','\x00','\x00','\x00','\x00','\x00','\x00',
'\x00','\x2C','\x61','\x23','\x47','\x0E','\x26','\x61','\x20','\x31','\x49','\x36','\x24','\x2B','\x42','\x31',
'\x63','\x0E','\x29','\x5E','\x30','\x4B','\x38','\x2A','\x33','\x44','\x3D','\x8B','\xC0','\xAC','\x6B' };
printf("please input name:");
scanf("%s",&name);
namelen=strlen(name);
if(namelen<4)
{ printf("name too short!");
return;
}
printf("'\nplease input company:");
scanf("%s",&company);
companylen=strlen(company);
if(companylen<3)
{ printf("company too short!");
return;
}
temp1=table[name[0]];
temp2=table[name[3]]*table[company[2]];
temp3=temp1*table[name[2]]*table[company[companylen-2]]*table[company[companylen-1]]+temp2;
temp3^=0x28D8u;
temp3+=0x288D4A7Dlu;
temp3^=0x9714u;
temp=(temp3<<30);
temp3>>=2;
temp3|=temp;
temp=temp3>>3;
if(temp3>=0x80000000) temp3=temp|80000000;
else temp3=temp;
temp3+=0xC0E40u;
temp3+=temp2;
temp3+=1;
temp=temp3&0xFFFF0000u;
temp3=(temp3&0x0000FFFFu);
temp3=~(temp3|0xFFFF0000u);
temp3|=temp;
if(temp3>0x0CCCCCCCu)
{ printf("name and company are not up to the mustard.");
return;
}
temp3+=0x29Au;
printf("\nserial is %lu",temp3);
}
如有错误,请各位大侠指教。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年07月10日 上午 02:03:51
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!