OllyDbg破解系列——WinMatrix XP
Winmatrix XP 2.0
软件介绍:
看过黑客帝国没有? 这个超酷动态桌面Winmatrix xp可模拟电影黑客帝国的“数码瀑布”效果,赶快下载试试哦^_^
------
(1)前言
又来到OllyDbg菜鸟学堂(高手勿进,呵呵),这个软件与前几个不同的是:不使用老土的
F(用户名)= 注册码,最后进行真假注册码比较的验证方法;而是采用F(注册码)的验证手法,
不能再用一直盯住寄存器就能找出真注册码的方法了,而是要看懂算法,方向算法才能搞定哦。
(当然还可以 TNT,呵呵)
好了,不多废话,进入正题——
(2) 寻找切入点:
先打开程序,尝试注册,发现弹出注册码错误提示对话框,哈哈,我想我们的切入点
又是MessageBox了:)
用OllyDbg打开程序,在MessageBoxA上设断,尝试注册——
程序在此处停下:
00412F79 |> FF7424 10 PUSH DWORD PTR SS:[ESP+10]
; /style
00412F7D |. 50 PUSH EAX
; |Title
00412F7E |. FF7424 10 PUSH DWORD PTR SS:[ESP+10]
; |Text
00412F82 |. 51 PUSH ECX
; |hOwner
00412F83 |. FF15 E0B34100 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>;
\MessageBoxA
00412F89 |. 5E POP ESI
00412F8A \. C2 0C00 RETN 0C
察看堆栈,可以看见MessageBox的参数:
0012F914 00000000 |hOwner = NULL
0012F918 004220CC |Text = "Wrong registration code. Perhaps,
you mistype some symbols."
0012F91C 00920EB0 |Title = "WinMatrixXP"
0012F920 00000000 \style = MB_OK|MB_APPLMODAL
跟出上面那个Return语句,来到程序主控代码:
00401293 |. 68 CC204200 PUSH WinMatri.004220CC ; ASCII
"Wrong registration code. Perhaps, you mistype some symbols."
00401298 |. E8 BE1C0100 CALL WinMatri.00412F5B ;这里就是刚才那个调用MessageBox的函数
0040129D |. EB 3B JMP SHORT WinMatri.004012DA
; return 到这里
(3)跟踪——注册码验证算法
对上面那段代码进行分析可以分析出注册码算法了,详细过程请见注释:
00401246 |. B9 06000000
MOV ECX,6
0040124B |. 394D F8 CMP DWORD PTR SS:[EBP-8],ECX
; [EBP-8]->strlen(注册码1)8],
0040124E |. 75 3B JNZ SHORT WinMatri.0040128B
; 注册码1长度==6 ???atri.004
00401250 |. 8B47 60 MOV EAX,DWORD PTR DS:[EDI+60]
00401253 |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX
00401257 |. 8378 F8 04 CMP DWORD PTR DS:[EAX-8],4
; [EAX-8]->strlen(注册码2)8],
0040125B |. 75 2E JNZ SHORT WinMatri.0040128B
; 注册码2长度==4 ???atri.004
0040125D |. 8B77 64 MOV ESI,DWORD PTR DS:[EDI+64]
00401260 |. 394E F8 CMP DWORD PTR DS:[ESI-8],ECX
; [ESI-8]->strlen(注册码3)8],
00401263 |. 75 26 JNZ SHORT WinMatri.0040128B
; 注册码3长度==6 ???atri.004
00401265 |. 32D2 XOR DL,DL
00401267 |. 32C9 XOR CL,CL
00401269 |. 53 PUSH EBX
0040126A |. 33C0 XOR EAX,EAX
0040126C |> 8A1C06 /MOV BL,BYTE
PTR DS:[ESI+EAX] ; BL->注册码3[EAX]TR
0040126F |. 021C28 |ADD BL,BYTE PTR
DS:[EAX+EBP] ; BL+=注册码1[EAX]TR
00401272 |. 02D3 |ADD DL,BL
; DL += BL
00401274 |. 83F8 04 |CMP EAX,4
00401277 |. 7D 07 |JGE SHORT WinMatri.00401280
; EAX >= 4
00401279 |. 8B5C24 14 |MOV EBX,DWORD PTR SS:[ESP+14]
0040127D |. 020C03 |ADD CL,BYTE PTR
DS:[EBX+EAX] ; CL+=注册码2[EAX]TR
00401280 |> 40 |INC
EAX
00401281 |. 83F8 06 |CMP EAX,6
00401284 |.^ 7C E6 \JL SHORT WinMatri.0040126C
00401286 |. 3AD1 CMP DL,CL
;
DL == CL ??? 相当则注册码正确!!!! @龌铉A
00401288 |. 5B POP EBX
00401289 |. 74 14 JE SHORT WinMatri.0040129F
; 关键跳转,哈哈 ^_^Matri.0
0040128B |> 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C]
0040128F |. 6A 00 PUSH 0
00401291 |. 6A 00 PUSH 0
00401293 |. 68 CC204200 PUSH WinMatri.004220CC
; ASCII "Wrong registration code. Perhaps, you
mistype some symbols."
00401298 |. E8 BE1C0100 CALL WinMatri.00412F5B
; 提示用户WinM
0040129D |. EB 3B JMP SHORT WinMatri.004012DA
把上面的注册码验证过程写成C代码为:
char szSn1[16],szSn2[16],szSn3[16]; //用户输入的注册码1,2,3
if(strlen(szSn1) != 6)
{
go to Sn_Error;
}
if(strlen(szSn2) != 4)
{
go to Sn_Error;
}
if(strlen(szSn3) != 6)
{
go to Sn_Error;
}
short CL =0, DL = 0,BL;
for(int i=0;i < 6;i++)
{
BL = szSn1[i] + szSn3[i];
DL += BL;
if(i < 4)
{
CL += szSn2[i];
}
}
if(DL == CL)
{
go to Sn_Right; //正确!!
}
Sn_Wrong: //注册码错误
MessageBox(NULL,"Wrong registration code. Perhaps, you mistype some
symbols.",
"WinMatrixXP",MB_OK|MB_APPLMODAL);
return 0;
Sn_Right: //注册码正确
return 1;
(4)反向——注册码生成算法
可以看出,注册码2的字符Ascii要远大与注册码13的Ascii,这样才能保证最后可以通过。
我们取注册码2的最大Ascii值为122(字符'z'),可以计算出值区间
n13 = [33,40] //注册码1,3的Ascii
n2 = [99,122] //注册码2的Ascii
于是可以写出一个简单的注册码生成算法:
void KeyGen(){
char nStr1[8],nStr2[8],nStr3[8];
short nSum13 =0,nSum2 =0,n1;
srand(time(NULL));
for(int i = 0; i< 4; i++)
{
nStr2[i] = (char)RandomRange(99,122);
nSum2 += (short)nStr2[i];
}
nStr2[4] = '\0';
n1 = nSum2/12;
for(i=0; i< 6; i++)
{
nStr1[i] = (char)n1;
nStr3[i] = (char)n1;
}
nStr1[5] = nSum2 - n1* 11;
nStr1[6] = '\0';
nStr3[6] = '\0';
}
int RandomRange(int nBegin, int nEnd)
{
int nRange = nEnd - nBegin;
return nBegin + rand()*nRange/RAND_MAX;
}
(5)总结
这个软件验证算法不复杂,所以注册码还是比较好算的。而且,这也是一种典型的多段注册码验证
方法(我已经遇到过多次类似情况),初学者可以尝试一下。
欢迎大家和我交流OllyDbg的破解技术,QQ: 85436
WinHack 2003-5-29
属于CCG,OCN,YCG