• 标 题:Winmatrix XP 2.0
  • 作 者:windcbf
  • 时 间:2003/05/29 09:50pm
  • 链 接:http://bbs.pediy.com

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