一个重启验证软件的破解思路
破解作者
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 EAX, EAX**************按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 ECX, EDI
0042F2B5 MOV EDX, ESI
0042F2B7 CALL 123.00404E84
0042F2BC MOV EDX, [LOCAL.1]
0042F2BF MOV EAX, [ARG.1]
0042F2C2 CALL 123.004047DC
0042F2C7 XOR EAX, EAX
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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD 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 EAX, DWORD PTR DS:[47DC68]
004776D0 PUSH EAX*********************内置的字串:软件名XXXXXX入栈
004776D1 LEA ECX, [LOCAL.11]
004776D4 MOV EDX, 1
004776D9 MOV EAX, DWORD 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 EDX, DWORD PTR DS:[47DC78]*把输入的EMAIL:yzez@163.com移入EDX
004776F6 MOV EAX, DWORD 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 EBX, EAX
0047770E XOR EAX, EAX
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 EBP, ESP
*******************************省略部分代码!***********************************
004773FD MOV EDX, [ARG.1]
00477400 MOV EAX, [LOCAL.1]****把得到的值:yzezyzez@163.comXenotrixiSplit4Ii`w入EAX
00477403 CALL 123.00477308******算法CALL跟进,按F7
00477408 XOR EAX, EAX
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 EBP, ESP
0047730B ADD ESP, -8
0047730E PUSH EBX
0047730F PUSH ESI
00477310 PUSH EDI
00477311 XOR ECX, ECX
00477313 MOV [LOCAL.2], ECX
00477316 MOV [LOCAL.1], EDX
00477319 MOV EDI, EAX
0047731B XOR EAX, EAX
0047731D PUSH EBP
0047731E PUSH 123.0047739A
00477323 PUSH DWORD PTR FS:[EAX]
00477326 MOV DWORD PTR FS:[EAX], ESP
00477329 XOR EBX, EBX
0047732B MOV EAX, EDI
0047732D CALL 123.00404814
00477332 TEST EAX, EAX
00477334 JLE SHORT 123.0047735F
00477336 MOV ESI, 1***********************赋ESI的值1,ESI做计数器!
0047733B MOV DL, BYTE PTR DS:[EDI+ESI-1]**取出第一个字串:y(ASCII码值是:79)
0047733F XOR DL, BL***********************DL ^ BL=79,BL的初始值是:0
00477341 AND EDX, 0FF*********************与0FF=79
00477347 MOV EDX, DWORD PTR DS:[EDX*4+47C094>**把地址:EDX*4+47C094存放的值:29D9C998入EDX
0047734E SHR EBX, 8***********************EBC右移8位!
00477351 AND EBX, 0FFFFFF*****************与运算!
00477357 XOR EDX, EBX*********************EDX XOR EBX=29D9C998
00477359 MOV EBX, EDX*********************把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 EAX, EBX*********************把150DDFC1由EBX移入EAX中
00477368 XOR EDX, EDX
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 EAX, EAX
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位有规定,其它的位数可以任意!最近工作太忙,个人也有点懒,
所以算法不完全,主要代码太多,循环也多,用到了除,所以也不想再更多的分析了.好在我在前面就声明,这是关于
软件重启验证的一种破解方法,我想这个过程省略也无所谓了.