• 标 题:某文件切割工具
  • 作 者:txm123
  • 时 间:2003年11月08日 08:27
  • 链 接:http://bbs.pediy.com

一个重启验证软件的破解思路

    破解作者
            yzez[DFCG][BCG][FCG]
    破解工具
            PEID、OLLYDBG1.09、脱壳工具Pe-scan
    破解目的
            不为破解而破解,只为交流技术而破解
    破解过程

    这两天在看雪论坛上有网友提到关于重启验证软件的破解如何破的问题,刚刚手头有一个前天下的
软件也是重启验证的,所以就破一破,讲一讲大致思路。为保护国产软件隐去软件相关信息,这是一个文件
切割的软件。未注册有功能限制,非明码比较,所以要看懂注册算法思路。对于重启验证的软件,一般的
方法是:使用FILEMON或者REGMON等软件,监测软件输入注册信息后,会把注册信息保存到何处,如果是保存
在注册表中我们一般下:REGCREATEKEYA等断点,如果是保存到某个文件当中,我们就要反汇编找到软件在
什么地主对这个文件进行读写操作,然后有针对性地设下断点,当然方法很多,这只不过是一个一般的思路
和过程,视具体情况而论,不要死守陈规,这个软件监测后发现把注册信息保存到注册表中,先下REGCREATEKEYA
断点,按了N次F8,不太正常,不知道是我机子的问题还是什么问题,不耐烦退出OD,重新打开程序还是注册
窗口,突然想到程序验证以后,注册不正确还是会弹出这个要求注册的窗口,那么我们就可以用别的断点
方法找到比对的关键处,所以这个软件的重启验证我们可以用另一种断点方法来破,下面看过程。
1、用PEID检测是PECompact 1.68 - 1.84 -> Jeremy Collake的壳,于是用Pe-scan自动脱壳,脱完壳后,
先运行脱壳后的程序,输入注册信息:用户名yzez,EMAIL:yzez@163.com,试验码:123456789987654321,
为什么要输入这么多位数的试验码?请看下面的说明。输入注册信息后,软件要求重启来验证注册正确与
否,点确定程序退出,用OD载入脱壳后的程序,在命令栏内输入:bpx Messageboxa就是设下断点,然后
按ENTER键,出现一个信息框,在这个框里的所有CALL上都设下断点,按F9运行程序,连续按F9,如果跳不
过,按F2去掉这个断点,这时你要留心四个窗口,等到出现你所输入的注册信息后,这时就要停止F9,改按
F8,因为已经快到关键处了,下面看代码:

00404D7F   CALL    <JMP.&oleaut32.SysAllocStringLen>****在这个CALL出现了我输入的试验码:123456789987654321,
******************我们已经快到关键处,记下这个地址,如果一次调试不出,以后就要直接在这个CALL设下断点!
00404D84   TEST    EAXEAX**************按F8往下走!
00404D86   JE      123.00404C58
00404D8C   POP     EDX                              
00404D8D   PUSH    DWORD PTR DS:[EDX]
00404D8F   MOV     DWORD PTR DS:[EDX], EAX
00404D91   CALL    <JMP.&oleaut32.SysFreeString>
00404D96   RETN***********返回指令!不要管,按F8继续往下走,中间还有一个,对我们无用,省略,直到下面处:
===========================================================================================

0042F2B0  MOV     EAX, [LOCAL.2] ****直到这个地方,我们要慢慢走了,按F8往下!                 
0042F2B3  MOV     ECXEDI                      
0042F2B5  MOV     EDXESI                      
0042F2B7  CALL    123.00404E84                   
0042F2BC  MOV     EDX, [LOCAL.1]
0042F2BF  MOV     EAX, [ARG.1]
0042F2C2  CALL    123.004047DC
0042F2C7  XOR     EAXEAX
0042F2C9  POP     EDX                             
0042F2CA  POP     ECX                            
0042F2CB  POP     ECX                             
0042F2CC  MOV     DWORD PTR FS:[EAX], EDX
0042F2CF  PUSH    123.0042F2E9
0042F2D4  LEA     EAX, [LOCAL.2]
0042F2D7  MOV     EDX, 2******************把常数2赋EDX,干吗用?原来是取试验码的值,这里指取试验码的第2位:2
0042F2DC  CALL    123.00404CA0************此CALL取出试验码的第2位:2,有兴趣自己去跟。
0042F2E1  RETN****************************返回指令,继续往下。
========================================================================================

按F8走,我们又会来到这里:
00477615  PUSH    [LOCAL.2]***************我们来到这里
00477618  EAX, [LOCAL.3]
0047761B  PUSH    EAX
0047761C  MOV     ECX, 1******************赋ECX的值1,即取一位
00477621  MOV     EDX, 6******************取试验码的第6位!
00477626  MOV     EAXDWORD PTR DS:[EBX]*试验码:123456789987654321移入EAX中
00477628  CALL    123.0042F284************取试验码的第6位:6
0047762D  PUSH    [LOCAL.3]
00477630  LEA     EAX, [LOCAL.4]
00477633  PUSH    EAX
00477634  MOV     ECX, 1*****************赋ECX的值1,取1位试验码
00477639  MOV     EDX, 0A****************赋EDX的值:A(十进制值是10),取第10位试验码
0047763E  MOV     EAXDWORD PTR DS:[EBX]*试验码:123456789987654321移入EAX中
00477640  CALL    123.0042F284************取出试验码的第10位:9
00477645  PUSH    [LOCAL.4]
00477648  LEA     EAX, [LOCAL.5]
0047764B  PUSH    EAX
0047764C  MOV     ECX, 1
00477651  MOV     EDX, 0E*****************取试验码的0E位,即第14位
00477656  MOV     EAXDWORD PTR DS:[EBX]
00477658  CALL    123.0042F284************取出试验码的第14位:5
0047765D  PUSH    [LOCAL.5]
00477660  LEA     EAX, [LOCAL.6]
00477663  PUSH    EAX
00477664  MOV     ECX, 1
00477669  MOV     EDX, 4******************取试验码的第4位
0047766E  MOV     EAXDWORD PTR DS:[EBX]
00477670  CALL    123.0042F284
00477675  PUSH    [LOCAL.6]
00477678  LEA     EAX, [LOCAL.7]
0047767B  PUSH    EAX
0047767C  MOV     ECX, 1
00477681  MOV     EDX, 8******************取试验码的第8位
00477686  MOV     EAXDWORD PTR DS:[EBX]
00477688  CALL    123.0042F284************取出试验码的第8位:8
0047768D  PUSH    [LOCAL.7]
00477690  LEA     EAX, [LOCAL.8]
00477693  PUSH    EAX
00477694  MOV     ECX, 1
00477699  MOV     EDX, 0C*****************取试验码的0C位即第12位
0047769E  MOV     EAXDWORD PTR DS:[EBX]
004776A0  CALL    123.0042F284************取出试验码的第12位:7
004776A5  PUSH    [LOCAL.8]
004776A8  LEA     ECX, [LOCAL.9]
004776AB  MOV     EDX, 1******************取试验码的第1位
004776B0  MOV     EAXDWORD PTR DS:[EBX]
004776B2  CALL    123.0042F200************取出试验码的第1位:1
004776B7  PUSH    [LOCAL.9]
004776BA  LEA     EAX, [LOCAL.1]
004776BD  MOV     EDX, 8******************赋EDX的值8,8位取完了吗?
004776C2  CALL    123.004048D4************取出的8位数值连接起来组成一组新值:26954871
004776C7  MOV     EAX, [LOCAL.1]**********把这组新值移到EAX
004776CA  PUSH    EAX
004776CB  MOV     EAXDWORD PTR DS:[47DC68]
004776D0  PUSH    EAX*********************内置的字串:软件名XXXXXX入栈
004776D1  LEA     ECX, [LOCAL.11]
004776D4  MOV     EDX, 1
004776D9  MOV     EAXDWORD PTR DS:[47DC6C]
004776DE  CALL    123.0042F190
004776E3  EAX, [LOCAL.11]
004776E6  PUSH    EAX
004776E7  LEA     EAX, [LOCAL.10]
004776EA  PUSH    EAX
004776EB  MOV     ECX, 123.00477740**********移入固定的字串"Xenotrix"
004776F0  MOV     EDXDWORD PTR DS:[47DC78]*把输入的EMAIL:yzez@163.com移入EDX
004776F6  MOV     EAXDWORD PTR DS:[47DC74]
004776FB  CALL    123.004773A8***************再取用户名:yzez,把上述内容全部连接起来,组成一个长
*****字符串:yzezyzez@163.comXenotrixiSplit4Ii`w,这个字符串就是在这个CALL中而得到,我不贴代码了,
*****要不然这篇文章真的成了垃圾文章!但这个CALL我们一定要进!因为关键值在这个CALL里计算得到!关键CALL。
00477700  MOV     EDX, [LOCAL.10]************把上面运算的结果:150DDFC1,大写字母转换成小写:150ddfc1
00477703  POP     EAX                            
00477704  CALL    123.00404960***************比较CALL,比较上述运算的值:150ddfc1与取出的8位试验码:
************************************26954871是否相等!
00477709  SETE    AL*************************相等则置AL的值为1,这是成功标志位,软件重启验证这个标志位!
0047770C  MOV     EBXEAX
0047770E  XOR     EAXEAX
00477710  POP     EDX                           
00477711  POP     ECX                           
00477712  POP     ECX                         
00477713  MOV     DWORD PTR FS:[EAX], EDX
00477736  C3            RETN

======================================================================================
关键CALL跟进后我们在这里:

004773A8  PUSH    EBP
004773A9  MOV     EBPESP
*******************************省略部分代码!***********************************
004773FD  MOV     EDX, [ARG.1]
00477400  MOV     EAX, [LOCAL.1]****把得到的值:yzezyzez@163.comXenotrixiSplit4Ii`w入EAX
00477403  CALL    123.00477308******算法CALL跟进,按F7
00477408  XOR     EAXEAX
0047740A  POP     EDX                             
0047740B  POP     ECX                            
0047740C  POP     ECX                             
0047740D  MOV     DWORD PTR FS:[EAX], EDX
00477410  PUSH    123.0047742A
00477415  LEA     EAX, [LOCAL.2]
00477418  MOV     EDX, 2
0047741D  CALL    123.00404578
00477422  RETN
 
========================================================================================
算法CALL跟进后,来到这里:
00477308  PUSH    EBP
00477309  MOV     EBPESP
0047730B  ADD     ESP, -8
0047730E  PUSH    EBX
0047730F  PUSH    ESI
00477310  PUSH    EDI                            
00477311  XOR     ECXECX
00477313  MOV     [LOCAL.2], ECX
00477316  MOV     [LOCAL.1], EDX
00477319  MOV     EDIEAX
0047731B  XOR     EAXEAX
0047731D  PUSH    EBP
0047731E  PUSH    123.0047739A
00477323  PUSH    DWORD PTR FS:[EAX]
00477326  MOV     DWORD PTR FS:[EAX], ESP
00477329  XOR     EBXEBX
0047732B  MOV     EAXEDI                        
0047732D  CALL    123.00404814
00477332  TEST    EAXEAX
00477334  JLE     SHORT 123.0047735F
00477336  MOV     ESI, 1***********************赋ESI的值1,ESI做计数器!
0047733B  MOV     DLBYTE PTR DS:[EDI+ESI-1]**取出第一个字串:y(ASCII码值是:79)
0047733F  XOR     DLBL***********************DL ^ BL=79,BL的初始值是:0
00477341  AND     EDX, 0FF*********************与0FF=79
00477347  MOV     EDXDWORD PTR DS:[EDX*4+47C094>**把地址:EDX*4+47C094存放的值:29D9C998入EDX
0047734E  SHR     EBX, 8***********************EBC右移8位!
00477351  AND     EBX, 0FFFFFF*****************与运算!
00477357  XOR     EDXEBX*********************EDX XOR EBX=29D9C998
00477359  MOV     EBXEDX*********************把29D9C998移入EBX中,参与下一步运算!
0047735B  INC     ESI**************************ESI加1
0047735C  DEC     EAX**************************EAX减1,EAX存放上述值的位数是:23
0047735D  JNZ     SHORT 123.0047733B***********跳回循环,一共循环23(35)次,得到最后的值:150DDFC1
0047735F  PUSH    32                              
00477361  CALL    <JMP.&kernel32.Sleep>        
00477366  MOV     EAXEBX*********************把150DDFC1由EBX移入EAX中
00477368  XOR     EDXEDX
0047736A  PUSH    EDX                           
0047736B  PUSH    EAX                             ASCII "yzezyzez@163.comXenotrixiSplit4Ii`w"
0047736C  LEA     EDX, [LOCAL.2]                   ; |
0047736F  MOV     EAX, 8                           ; |
00477374  CALL    123.004089D8                     ; 123.004089D8
00477379  MOV     EAX, [LOCAL.2]
0047737C  MOV     EDX, [LOCAL.1]
0047737F  CALL    123.00408588
00477384  XOR     EAXEAX
00477386  POP     EDX                              ;  123.00477408
00477387  POP     ECX                              ;  123.00477408
00477388  POP     ECX                              ;  123.00477408
00477389  MOV     DWORD PTR FS:[EAX], EDX
0047738C  PUSH    123.004773A1
00477391  LEA     EAX, [LOCAL.2]
00477394  CALL    123.00404554
00477399  RETN*******************************返回到前面我们再看!

  简单结论:
  这个软件是从注册码中取出8位值,分别是:第2、6、10、14、4、8、12、1位,依次取,得到一组值,
然后再把这个值与:用户名,邮箱与软件内置的字符串运算后得到的一组值比较,相等就注册成功!
  一个可用的注册码:用户名yzez
                    EMAIL:yzez@163.com
                    注册码:113d557f908c6d4321
 主要是注册码的第2、6、10、14、4、8、12、1位有规定,其它的位数可以任意!最近工作太忙,个人也有点懒,
所以算法不完全,主要代码太多,循环也多,用到了除,所以也不想再更多的分析了.好在我在前面就声明,这是关于
软件重启验证的一种破解方法,我想这个过程省略也无所谓了.