【破文作者】 rdsnow[BCG][PYG][D.4s]
【作者主页】 http://rdsnow.ys168.com
【 E-mail 】 rdsnow@163.com
【 作者QQ 】 83757177
【文章题目】 轻松班主任的调试笔记[keyfile]
【软件名称】 轻松班主任V4.4[个人版]
----------------------------------------------------------------------------------------------
【加密方式】 keyfile
【破解工具】 ODbyDYK v1.10[05.09]
【软件限制】 功能限制
【破解平台】 MicroSoft Windows XP SP2
----------------------------------------------------------------------------------------------
【文章简介】
最近被外壳的ANTI搞的头大,找个简单的调整一下,这是一个典型的Keyfile保护的共享软件,因为keyfile文件较短,难度不大,高手就忽略了,只是用来练手,通过这个程序了解一下破解kyefile的一般过程。
----------------------------------------------------------------------------------------------
【破解过程】
先脱掉程序的壳,Aspack 2.12的压缩壳很容易搞定。
打开程序的时候,同时打开FileMon监视,显示zuce.dat:File Not Found。从名字上猜想这就是注册文件了,
于是在安装目录下伪造一个keyfile。取名为zuce.dat。跟踪程序对该文件的读取动作。
00779961 |. 50 PUSH EAX
00779962 |. 8D45 F4 LEA EAX,[LOCAL.3]
00779965 |. B9 189A7700 MOV ECX,qsbzr.00779A18 ; ASCII "zuce.dat"
0077996A |. 8B15 64DC7800 MOV EDX,DWORD PTR DS:[78DC64]
00779970 |. E8 37B4C8FF CALL qsbzr.00404DAC ; 打开keyfile
00779975 |. 8B45 F4 MOV EAX,[LOCAL.3]
00779978 |. B9 2C9A7700 MOV ECX,qsbzr.00779A2C ; ASCII "name"
0077997D |. BA 3C9A7700 MOV EDX,qsbzr.00779A3C
00779982 |. E8 59FDFFFF CALL qsbzr.007796E0 ; 读取用户名
00779987 |. 8B45 F8 MOV EAX,[LOCAL.2]
0077998A |. 8D55 FC LEA EDX,[LOCAL.1]
0077998D |. E8 46FCFFFF CALL qsbzr.007795D8 ; 算法Call,跟进
00779992 |. 8B45 FC MOV EAX,[LOCAL.1]
00779995 |. 50 PUSH EAX
00779996 |. 68 4C9A7700 PUSH qsbzr.00779A4C ; ASCII "123"
0077999B |. 8D45 F0 LEA EAX,[LOCAL.4]
0077999E |. 50 PUSH EAX
0077999F |. 8D45 EC LEA EAX,[LOCAL.5]
007799A2 |. B9 189A7700 MOV ECX,qsbzr.00779A18 ; ASCII "zuce.dat"
007799A7 |. 8B15 64DC7800 MOV EDX,DWORD PTR DS:[78DC64]
007799AD |. E8 FAB3C8FF CALL qsbzr.00404DAC ; 再次打开keyfile
007799B2 |. 8B45 EC MOV EAX,[LOCAL.5]
007799B5 |. B9 589A7700 MOV ECX,qsbzr.00779A58 ; ASCII "code"
007799BA |. BA 689A7700 MOV EDX,qsbzr.00779A68
007799BF |. E8 1CFDFFFF CALL qsbzr.007796E0 ; 读出keyfile中的假码
007799C4 |. 8B55 F0 MOV EDX,[LOCAL.4]
007799C7 |. 58 POP EAX
007799C8 |. E8 DFB4C8FF CALL qsbzr.00404EAC ; 真假注册比较
007799CD |. 75 04 JNZ SHORT qsbzr.007799D3 ; 爆破点
007799CF |. B3 01 MOV BL,1 ; 返回值=1
007799D1 |. EB 02 JMP SHORT qsbzr.007799D5
007799D3 |> 33DB XOR EBX,EBX ; 返回值=0
007799D5 |> 33C0 XOR EAX,EAX
原来的keyfile读取数据不成功,这个keyfile不需要用WinHex生成,直接用记事本输入一个txt文档,将扩展名改为dat,根据读取数据的参数,结果常见的ini文件的格式,加上猜想,在记事本内输入:
[班主任]
name=rdsnow[BCG][PYG][D.4s]
[注册]
code=98765432-87654321-abcdefgh-hijklmno
这个格式我也是试了很多次才成功的。注册码的格式可以从0077998D处的CALL qsbzr.007795D8的返回结果可以看到。那里返回的就是真码。
----------------------------------------------------------------------------------------------
要知道注册码是怎样得到的,跟进0077998D处的CALL qsbzr.007795D8:
007795D8 /$ 55 PUSH EBP
007795D9 |. 8BEC MOV EBP,ESP
007795DB |. B9 05000000 MOV ECX,5
007795E0 |> 6A 00 /PUSH 0
007795E2 |. 6A 00 |PUSH 0
007795E4 |. 49 |DEC ECX
007795E5 |.^ 75 F9 \JNZ SHORT qsbzr.007795E0
007795E7 |. 51 PUSH ECX
007795E8 |. 53 PUSH EBX
007795E9 |. 8BDA MOV EBX,EDX
007795EB |. 8945 FC MOV [LOCAL.1],EAX
007795EE |. 8B45 FC MOV EAX,[LOCAL.1]
007795F1 |. E8 5AB9C8FF CALL qsbzr.00404F50
007795F6 |. 33C0 XOR EAX,EAX
007795F8 |. 55 PUSH EBP
007795F9 |. 68 C7967700 PUSH qsbzr.007796C7
007795FE |. 64:FF30 PUSH DWORD PTR FS:[EAX]
00779601 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
00779604 |. 8D55 D4 LEA EDX,[LOCAL.11]
00779607 |. 8B45 FC MOV EAX,[LOCAL.1]
0077960A |. E8 2D04C9FF CALL qsbzr.00409A3C ; 对注册码进行格式校验
0077960F |. 8B45 D4 MOV EAX,[LOCAL.11]
00779612 |. 8D55 D8 LEA EDX,[LOCAL.10]
00779615 |. E8 56BED3FF CALL qsbzr.004B5470 ; 算法,看输出格式,应该使用了MD5算法,跟进
0077961A |. 8D45 D8 LEA EAX,[LOCAL.10]
0077961D |. 8D55 F8 LEA EDX,[LOCAL.2]
00779620 |. E8 17BFD3FF CALL qsbzr.004B553C ; 将MD5输出128位信息转为32个字符
00779625 |. 8D45 F4 LEA EAX,[LOCAL.3]
00779628 |. 50 PUSH EAX
00779629 |. B9 08000000 MOV ECX,8
0077962E |. BA 01000000 MOV EDX,1
00779633 |. 8B45 F8 MOV EAX,[LOCAL.2]
00779636 |. E8 85B9C8FF CALL qsbzr.00404FC0 ; 取前8个字符
0077963B |. 8D45 F0 LEA EAX,[LOCAL.4]
0077963E |. 50 PUSH EAX
0077963F |. B9 08000000 MOV ECX,8
00779644 |. BA 09000000 MOV EDX,9
00779649 |. 8B45 F8 MOV EAX,[LOCAL.2]
0077964C |. E8 6FB9C8FF CALL qsbzr.00404FC0 ; 取第9到16个字符
00779651 |. 8D45 EC LEA EAX,[LOCAL.5]
00779654 |. 50 PUSH EAX
00779655 |. B9 08000000 MOV ECX,8
0077965A |. BA 11000000 MOV EDX,11
0077965F |. 8B45 F8 MOV EAX,[LOCAL.2]
00779662 |. E8 59B9C8FF CALL qsbzr.00404FC0 ; 取第17到24个字符
00779667 |. 8D45 E8 LEA EAX,[LOCAL.6]
0077966A |. 50 PUSH EAX
0077966B |. B9 08000000 MOV ECX,8
00779670 |. BA 19000000 MOV EDX,19
00779675 |. 8B45 F8 MOV EAX,[LOCAL.2]
00779678 |. E8 43B9C8FF CALL qsbzr.00404FC0 ; 取第25到32个字符
0077967D |. FF75 F4 PUSH [LOCAL.3]
00779680 |. 68 DC967700 PUSH qsbzr.007796DC
00779685 |. FF75 F0 PUSH [LOCAL.4]
00779688 |. 68 DC967700 PUSH qsbzr.007796DC
0077968D |. FF75 EC PUSH [LOCAL.5]
00779690 |. 68 DC967700 PUSH qsbzr.007796DC
00779695 |. FF75 E8 PUSH [LOCAL.6]
00779698 |. 8BC3 MOV EAX,EBX
0077969A |. BA 07000000 MOV EDX,7
0077969F |. E8 7CB7C8FF CALL qsbzr.00404E20 ; 用"-"连接得到注册码
007796A4 |. 33C0 XOR EAX,EAX
007796A6 |. 5A POP EDX
007796A7 |. 59 POP ECX
007796A8 |. 59 POP ECX
007796A9 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
007796AC |. 68 CE967700 PUSH qsbzr.007796CE
007796B1 |> 8D45 D4 LEA EAX,[LOCAL.11]
007796B4 |. E8 E7B3C8FF CALL qsbzr.00404AA0
007796B9 |. 8D45 E8 LEA EAX,[LOCAL.6]
007796BC |. BA 06000000 MOV EDX,6
007796C1 |. E8 FEB3C8FF CALL qsbzr.00404AC4
007796C6 \. C3 RETN
----------------------------------------------------------------------------------------------
跟进00779615处的CALL qsbzr.004B5470
004B5470 /$ 55 PUSH EBP
004B5471 |. 8BEC MOV EBP,ESP
004B5473 |. 83C4 9C ADD ESP,-64
004B5476 |. 53 PUSH EBX
004B5477 |. 33C9 XOR ECX,ECX
004B5479 |. 894D 9C MOV [LOCAL.25],ECX
004B547C |. 894D A0 MOV [LOCAL.24],ECX
004B547F |. 8BDA MOV EBX,EDX
004B5481 |. 8945 FC MOV [LOCAL.1],EAX
004B5484 |. 8B45 FC MOV EAX,[LOCAL.1]
004B5487 |. E8 C4FAF4FF CALL qsbzr.00404F50
004B548C |. 33C0 XOR EAX,EAX
004B548E |. 55 PUSH EBP
004B548F |. 68 0B554B00 PUSH qsbzr.004B550B
004B5494 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
004B5497 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
004B549A |. 8D45 A4 LEA EAX,[LOCAL.23]
004B549D |. E8 A6FEFFFF CALL qsbzr.004B5348 ; MD5初始化,进出可以看到MD5的四个常数
004B54A2 |. 8D45 A0 LEA EAX,[LOCAL.24]
004B54A5 |. B9 20554B00 MOV ECX,qsbzr.004B5520 ; ASCII "jltxgl"
004B54AA |. 8B55 FC MOV EDX,[LOCAL.1]
004B54AD |. E8 FAF8F4FF CALL qsbzr.00404DAC ; 用户名后接字符串"jltxgl"得到S1
004B54B2 |. 8B45 A0 MOV EAX,[LOCAL.24]
004B54B5 |. E8 A6F8F4FF CALL qsbzr.00404D60 ; S1的长度
004B54BA |. 50 PUSH EAX
004B54BB |. 8D45 9C LEA EAX,[LOCAL.25]
004B54BE |. B9 30554B00 MOV ECX,qsbzr.004B5530
004B54C3 |. 8B55 FC MOV EDX,[LOCAL.1]
004B54C6 |. E8 E1F8F4FF CALL qsbzr.00404DAC ; 用户名后接字符串"江龙工作室"得S2
004B54CB |. 8B45 9C MOV EAX,[LOCAL.25]
004B54CE |. E8 8DFAF4FF CALL qsbzr.00404F60
004B54D3 |. 8BD0 MOV EDX,EAX
004B54D5 |. 8D45 A4 LEA EAX,[LOCAL.23] ; MD5的四个常数
004B54D8 |. 59 POP ECX ; S1的长度
004B54D9 |. E8 9EFEFFFF CALL qsbzr.004B537C ; 对S2进行MD5运算,参数却是S1的长度
004B54DE |. 8BD3 MOV EDX,EBX ; 上面可以简单成实际只在用户名后接了"江龙工"
004B54E0 |. 8D45 A4 LEA EAX,[LOCAL.23]
004B54E3 |. E8 14FFFFFF CALL qsbzr.004B53FC ; 标准MD5核心运算,没有必要跟进了
004B54E8 |. 33C0 XOR EAX,EAX
004B54EA |. 5A POP EDX
004B54EB |. 59 POP ECX
004B54EC |. 59 POP ECX
004B54ED |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
004B54F0 |. 68 12554B00 PUSH qsbzr.004B5512
004B54F5 |> 8D45 9C LEA EAX,[LOCAL.25]
004B54F8 |. BA 02000000 MOV EDX,2
004B54FD |. E8 C2F5F4FF CALL qsbzr.00404AC4
004B5502 |. 8D45 FC LEA EAX,[LOCAL.1]
004B5505 |. E8 96F5F4FF CALL qsbzr.00404AA0
004B550A \. C3 RETN
----------------------------------------------------------------------------------------------
【破解心得】
从破解过程来看,对用keyfile保护的文件有下面一些建议。
1、keyfile的文件名不要使用zhuce、reg、key等敏感的文件名或扩展名,现在有一些作者将keyfile伪装成DLL、exe、com等就是一个很好的做法。
2、keyfile的内容不要过于简单,内容越多越好,并将关键信息分开保存在keyfile的各个不同地方。干扰调试者伪造。或者生成几个不同的keyfile保存在不同的地方。
3、keyfile内保存的内容不要直接是明码,文字,这样会给调试者不少提示信息。最好用户名、机器码、注册码等信息要经过加密,让调试者看到的是乱码。
4、程序内分不同的地方不同的时刻对keyfile的不同的部分进行验证,不要使用同一个验证Call,比如开机时验证keyfile的一部分,进入程序后再验证其他部分。增加暴力修改点。
5、keyfile的位置也要隐蔽,不要总是放在程序安装目录内。
6、最后尽可能采取一些反跟踪的手段组织程序被调试。
----------------------------------------------------------------------------------------------
【注册机源码】
Microsoft Visual C++ 6.0写的MFC程序,使用网上下载MD5类,下载的类不同,用法也不大一样。
void CMyDlg::OnOK()
{
// TODO: Add extra validation here
//CDialog::OnOK();
unsigned char inbuff[512],outbuff[16];
int i,n;
CString temp,MD5En;
FILE *keyfile;
//检查输入
UpdateData(true);
n=m_Edit1.GetLength ();
if(n==0){
MessageBox("★★★请输入你的用户名★★★","提示",MB_OK);
return;
}
//MD5编码,结果赋给MD5EN
n+=6;
memcpy(inbuff,m_Edit1+"江龙工",n);
MD5_CTX context;
context.MD5Update (inbuff,n);
context.MD5Final (outbuff);
for(i=0;i<16;i++){
temp.Format ("%02x",outbuff[i]);
MD5En += temp;
}
//插入'-'形成注册码
MD5En.Insert (8,'-');
MD5En.Insert (17,'-');
MD5En.Insert (26,'-');
//输出注册文件
keyfile=fopen("zuce.dat","w+t");
if(keyfile){
fwrite("[班主任]\nname=",1,14,keyfile);
fwrite(m_Edit1,1,n-6,keyfile);
fwrite("\n[注册]\ncode=",1,13,keyfile);
fwrite(MD5En,1,35,keyfile);
fclose(keyfile);
MessageBox(" ★注册文件zuce.dat已经生成★\n\n★将该文件拷贝到软件安装目录完成注册★","成功",MB_OK);
}
else MessageBox("注册文件zuce.dat生成不成功,请重试一下","错误",MB_OK);
}
----------------------------------------------------------------------------------------------
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
----------------------------------------------------------------------------------------------
文章写于2005-9-12 12:42:43