Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~
下载地址:http://restools.go.163.com/
写此文全靠happy new year贴子提示!
不过happy new year写的算法应该有错,经过我这两天的破解,基本确定算法如下:
注:FreeRes0.94、HexEdit0.20、GetVBRes0.51的基本算法相同(下面四步)
ResScope1.35、FreeRes0.60只用A、B两步就行了
A: Name+HardCode(补成20位)------算法X------>识别Code1(20位)
B: 识别Code1(20位)--------------算法Y------>假RegCode(40位)
C: Input RegCode-----------------Y逆算法----->识别Code2(20位)
D: 识别Code2(20位)-------------X逆算法----->识别Code3(20位)
Code1=Code3 注册成功!
Keygen的算法应该是:
Name+HardCode(补成20位)---算法X---算法X---识别CODE2---算法Y---Ture RegCode
为什么呢?我们从D步往上推:
识别Code3(20位)-------------算法X----->识别Code2(20位)
识别Code2(20位)-------------算法Y----->Input RegCode(40位)
如果我们的Code3是正确的也就是Code3=Code1的话,我们输入的Regcode就是正确RegCode了,那么:
识别Code1(20位)-------------算法X----->识别Code2(20位)
也是成立的,所以我们用Name+HardCode(补成20位)经过两次算法X就可以得到Code2了,Code2再经过算法Y就可以得到真RegCode了!
所以如果你不是想写注册机,先记下Code1,在程序将Name+HardCode补成20位后将它改成Code1,经过算法X,记下Code2,然后重新启动程序再次将它改成Code2,经过算法Y就可以得到真的注册码了:-)
为了免抄40位的注册码,我还是把它们的注册机都做了出来,完全测试通过,不过暂时不会发布出来,在此再次感谢注册机编写器的作者,让我省了不少功夫.
好了,下面以FreeRes 0.94为例说明:
==Step Z=========================================
这一步是将Name+HardCode补成20位,方法是将Name+HardCode后的最后一位放到第一位,将Name+HardCode的长度放到第二位,这两位是的形式是固定这样的,如果长度为19、20位,将最后1位放到第1位,第2位是长度(第2位一定是Name+HardCode的长度),再取Name+HardCode的前18位补上,如果长度小如18位的话,补位方法如下:
Name(Sam.com)+HardCode(1234567B)=Sam.com1234567B(共15位)
补位后:B 15h EDCSam.com1234567B
~~~ ~~~
注意第二位是16进制,也就是Name+HardCode的长度,第3到第5位是补上的,因为18-15=3,方法是用最后一位加1到第5位,加2到第4位,加3到第3位
0187:004BB9E0 MOV EAX,[EBP-04] <---eax指Name+HardCode
0187:004BB9E3 MOV BL,[EAX+ESI-01] <---esi是Name+HardCode的长度,这里取最后一位
0187:004BB9E7 MOV [EBP-0D],BL
0187:004BB9EA CMP ESI,BYTE +12 <---如果长度大于18位的话就跳
0187:004BB9ED JNL 004BBA33
<---如果跳过去的话就是简单的补上第1和第2位了
0187:004BB9EF CMP BL,7F
0187:004BB9F2 JNA 004BB9FD
0187:004BB9F4 MOV DWORD [EBP-14],FFFFFFFF
0187:004BB9FB JMP SHORT 004BBA04
0187:004BB9FD MOV DWORD [EBP-14],01 <---计数器
0187:004BBA04 MOV EAX,ESI
0187:004BBA06 MOV DL,12
0187:004BBA08 SUB DL,AL
<---算出还差多少位
0187:004BBA0A TEST DL,DL
0187:004BBA0C JNA 004BBA33
0187:004BBA0E MOV [EBP-15],DL
<---相差的位数做计数器
0187:004BBA11 ADD BL,[EBP-14]
<---这里我们"B"加上1了
0187:004BBA14 LEA EAX,[EBP-20]
0187:004BBA17 MOV EDX,EBX
0187:004BBA19 CALL 00403E34
0187:004BBA1E MOV EAX,[EBP-20]
0187:004BBA21 LEA EDX,[EBP-04]
0187:004BBA24 MOV ECX,01
0187:004BBA29 CALL 0040419C <---记住这两个Call不用进去,只是进行补位
0187:004BBA2E DEC BYTE [EBP-15]
0187:004BBA31 JNZ 004BBA11
<---我这里会循环3次
0187:004BBA33 LEA EAX,[EBP-24]
0187:004BBA36 MOV DL,[EBP-0D]
0187:004BBA39 CALL 00403E34
0187:004BBA3E MOV EAX,[EBP-24]
0187:004BBA41 LEA EDX,[EBP-04]
==Step X============================================
算法X不算难
0187:004BB4CE MOV [EBP-09],AL
<---AL是计数器,循环20次
0187:004BB4D1 MOV BL,01
<---指针
0187:004BB4D3 LEA EAX,[EBP-10]
0187:004BB4D6 XOR EDX,EDX
0187:004BB4D8 MOV DL,BL
0187:004BB4DA MOV ECX,[EBP-04]
0187:004BB4DD MOV DL,[ECX+EDX-01] <---补位后的数据第一位
0187:004BB4E1 MOV ECX,ESI
<---esi=3D6 这个是重要的数据
0187:004BB4E3 SHR ECX,08
0187:004BB4E6 XOR DL,CL
<---DL就是Code1的第一位了
0187:004BB4E8 CALL 00403E34
0187:004BB4ED MOV EDX,[EBP-10]
0187:004BB4F0 MOV EAX,EDI
0187:004BB4F2 CALL 00403F14 <---还记得这两个Call吗,只是保存数据而已
0187:004BB4F7 XOR EAX,EAX
0187:004BB4F9 MOV AL,BL
0187:004BB4FB MOV EDX,[EDI]
0187:004BB4FD MOVZX EAX,BYTE [EDX+EAX-01] <---Code1的第一位
X逆算法很简单,只是上面这一句指向的地址不同,如果是逆算法的话上面就不是Code1的第一位,而是补位后的数据第一位,其它的都一样.
0187:004BB502 ADD ESI,EAX
<---加上esi(3D6)
0187:004BB504 IMUL ESI,[EBP-08] <---[EBP-08]=3138
重要数据
0187:004BB508 ADD ESI,[EBP+0C] <---[EBP+0C]=8C34
重要数据
0187:004BB50B INC EBX
0187:004BB50C DEC BYTE [EBP-09]
0187:004BB50F JNZ 004BB4D3
<---注意第一次往上跳后004BB4E1处的esi就不是3D6了
==Step Y==========================================
算法Y有点复杂,它循环20次,按3种情况每次生成两个字符,所以最后的注册码是40位的
0187:004BB7E1 MOV [EBP-08],AL
<---AL是计数器,循环20次
0187:004BB7E4 MOV BYTE [EBP-05],01 <---指针
0187:004BB7E8 MOVZX EDI,BYTE [EBP-05]
0187:004BB7EC MOV EAX,[EBP-04] <---指向Code1
0187:004BB7EF MOV BL,[EAX+EDI-01] <---第一位
0187:004BB7F3 CMP BL,7E
0187:004BB7F6 JNA 004BB852
<---如果是可见字符就跳
0187:004BB7F8 MOV EAX,EBX
0187:004BB7FA CALL 004BB780 <---如果是大于7E(~)的字符就...请看Call
1
--Call 1------------------------------------------
0187:004BB780 XOR EDX,EDX
0187:004BB782 INC EDX
<---计数
0187:004BB783 AND EAX,FF
0187:004BB788 SHR EAX,1
<---将它变为小于7E的数
0187:004BB78A CMP AL,7F
0187:004BB78C JNC 004BB782
0187:004BB78E MOV EAX,EDX
0187:004BB790 RET
-------------------------------------------------
0187:004BB7FF CMP AL,02
0187:004BB801 JNZ 004BB809
0187:004BB803 MOV BYTE [EBP-07],03
0187:004BB807 JMP SHORT 004BB80C
0187:004BB809 MOV [EBP-07],AL
0187:004BB80C MOV DL,[EBP-07]
0187:004BB80F AND DL,BL
<---计数器和Code1第一位AND
0187:004BB811 SHL EDX,04
0187:004BB814 MOV CL,43
0187:004BB816 SUB CL,AL
0187:004BB818 OR DL,CL
0187:004BB81A MOV [EBP-06],DL
<---DL即是假注册码的偶数位
0187:004BB81D MOV ECX,EAX
0187:004BB81F XOR EAX,EAX
0187:004BB821 MOV AL,BL
0187:004BB823 SHR EAX,CL
0187:004BB825 MOV EBX,EAX
<---BL即是假注册码的奇数位
0187:004BB827 LEA EAX,[EBP-0C]
0187:004BB82A MOV EDX,EBX
0187:004BB82C CALL 00403E34
0187:004BB831 MOV EDX,[EBP-0C]
0187:004BB834 MOV EAX,ESI
0187:004BB836 CALL 00403F14
0187:004BB83B LEA EAX,[EBP-10]
0187:004BB83E MOV DL,[EBP-06]
0187:004BB841 CALL 00403E34
0187:004BB846 MOV EDX,[EBP-10]
0187:004BB849 MOV EAX,ESI
0187:004BB84B CALL 00403F14 <---不用管这些Call
0187:004BB850 JMP SHORT 004BB8C4 <---跳到最后再循环
0187:004BB852 CMP BL,21
<---如果数据是小于7E的就跳到这里
0187:004BB855 JNC 004BB89F
<---如果大于21的话就跳到后面保存注册码了
0187:004BB857 TEST BL,BL
0187:004BB859 JNZ 004BB863
0187:004BB85B MOV BL,3F
0187:004BB85D MOV BYTE [EBP-06],3F
0187:004BB861 JMP SHORT 004BB874
0187:004BB863 MOV EAX,EBX
0187:004BB865 CALL 004BB794 <---如果数据小于21就会到这
--Call 2------------------------------------------
0187:004BB794 XOR EDX,EDX
0187:004BB796 INC EDX
<---计数
0187:004BB797 ADD EAX,EAX
<---将它变为大于20的数
0187:004BB799 CMP AL,20
0187:004BB79B JNA 004BB796
0187:004BB79D MOV EAX,EDX
0187:004BB79F RET
--------------------------------------------------
0187:004BB86A LEA EDX,[EAX+43] <---计数器加上43
0187:004BB86D MOV [EBP-06],DL <---假注册码的偶数位
0187:004BB870 MOV ECX,EAX
0187:004BB872 SHL BL,CL
<---假注册码的奇数位
0187:004BB874 LEA EAX,[EBP-14]
0187:004BB877 MOV EDX,EBX
0187:004BB879 CALL 00403E34
0187:004BB87E MOV EDX,[EBP-14]
0187:004BB881 MOV EAX,ESI
0187:004BB883 CALL 00403F14
0187:004BB888 LEA EAX,[EBP-18]
0187:004BB88B MOV DL,[EBP-06]
0187:004BB88E CALL 00403E34
0187:004BB893 MOV EDX,[EBP-18]
0187:004BB896 MOV EAX,ESI
0187:004BB898 CALL 00403F14
0187:004BB89D JMP SHORT 004BB8C4 <---保存注册码后跳到后面再循环
如果Code1的数据是小于7E而且大于21,也就是可见的字符串的话就会跳到这里来,这时BL就是假注册码的奇数位了,看看下面的Call都是保存注册码的,那这时假注册码的偶数位在哪呢?请看4BB8BA处
0187:004BB89F LEA EAX,[EBP-1C]
0187:004BB8A2 MOV EDX,[EBP-04]
0187:004BB8A5 MOV DL,[EDX+EDI-01]
0187:004BB8A9 CALL 00403E34
0187:004BB8AE MOV EDX,[EBP-1C]
0187:004BB8B1 MOV EAX,ESI
0187:004BB8B3 CALL 00403F14
0187:004BB8B8 MOV EAX,ESI
0187:004BB8BA MOV EDX,004BB90C <---试试D
4BB90C,是否看到字符"C",偶数位就是它了,不用怀疑,因为这个"C"是在程序的数据段里的,而且整个系列的都是如此
0187:004BB8BF CALL 00403F14
0187:004BB8C4 INC BYTE [EBP-05]
0187:004BB8C7 DEC BYTE [EBP-08]
0187:004BB8CA JNZ NEAR 004BB7E8
0187:004BB8D0 XOR EAX,EAX
0187:004BB8D2 POP EDX
0187:004BB8D3 POP ECX
0187:004BB8D4 POP ECX
0187:004BB8D5 MOV [FS:EAX],EDX
0187:004BB8D8 PUSH DWORD 004BB8FA
0187:004BB8DD LEA EAX,[EBP-1C]
0187:004BB8E0 MOV EDX,05
0187:004BB8E5 CALL 00403CB0
0187:004BB8EA LEA EAX,[EBP-04]
0187:004BB8ED CALL 00403C8C
0187:004BB8F2 RET
OK~~~~~~~~我们的任务算是完成了,至于Y逆算法我就不贴出来了,有兴趣的就自己看看,在4BB63F处开始,因为要写注册机根本就不用两个逆算法.我们现在来讨论一下其它几个程序的不同.
其实FreeRes0.94、HexEdit0.20、GetVBRes0.51的算法都是一样的,HexEdit0.20甚至连机器码都相同,不同在哪里呢?其实区别就是算法X中的3个重要数据
FreeRes0.94中的是(16进制): 3D6、3183、8C34
HexEdit0.20中的是(16进制): 3D7、3184、8C35
GetVBRes0.51中的是(16进制): 3D8、3185、8C36
另外GetVBRes0.51的Name+HardCode的补位有了变化,而FreeRes0.94、HexEdit0.20的注册名不能大于10位,这个我还不能完全肯定.
下面是GetVBRes0.51的补位
============================================
GetVBRes0.51应该没有注册名位数限制,40位也没问题,但最后也是只取20位.如果Name+HardCode的长度小于等于18位或等于19、20位的话,补位和FreeRes一样,如果大于20位的话就要....
0187:0049AA63 CMP ESI,BYTE +12 <----esi是Name+HardCode的长度
0187:0049AA66 JNG 0049AAD4
0187:0049AA68 MOV EAX,[EBP-04]
0187:0049AA6B MOV BL,[EAX+12]
<----取出Name+HardCode的第18位
0187:0049AA6E MOV EAX,ESI
0187:0049AA70 SUB AL,14
<----算出多出多少位
0187:0049AA72 JC 0049AAA5
0187:0049AA74 INC EAX
0187:0049AA75 MOV [EBP-15],AL
<---加1作为计数器
0187:0049AA78 MOV AL,14
0187:0049AA7A XOR EDX,EDX
0187:0049AA7C MOV DL,AL
0187:0049AA7E MOV ECX,[EBP-04]
0187:0049AA81 MOV DL,[ECX+EDX-01] <---取出第20位
0187:0049AA85 CMP BL,DL
0187:0049AA87 JNA 0049AA94
0187:0049AA89 XOR ECX,ECX
0187:0049AA8B MOV CL,AL
0187:0049AA8D MOV EDI,[EBP-04]
0187:0049AA90 SUB BL,DL
0187:0049AA92 JMP SHORT 0049AA9F
0187:0049AA94 XOR ECX,ECX
0187:0049AA96 MOV CL,AL
0187:0049AA98 MOV EDI,[EBP-04]
0187:0049AA9B SUB DL,BL
0187:0049AA9D MOV EBX,EDX
<---用大数减去小数保存在ebx
0187:0049AA9F INC EAX
0187:0049AAA0 DEC BYTE [EBP-15]
0187:0049AAA3 JNZ 0049AA7A
<---当循环完后BL就是Code1的第一位了,然后再取
Name+HardCode的前18位补上
GetVBRes0.51注册后是否有些人看不到自己的注册名,ResTools系列的注册信息保存在
HKEY_LOCAL_MACHINE\SOFTWARE\RESTOOLS下,只要你注册ResFree后就可在GetVBRes看到ResFree的注册名了,注意在GetVBRes中用任意名注册都只会显示HKEY_LOCAL_MACHINE\SOFTWARE\RESTOOLS\freeRes下reguser里的字串,注册不了的可以自己建立一个.
再讲讲ResScope1.35、FreeRes0.60
两个注册算法一样,只用A、B两步,注册名不能大于18位,补位规则同上一样,要注意的是,调试的时候,填好注册名和注册码后按确定,程序并不会比较注册码,只是简单的将名和码写到注册表中,当你再次点击帮助菜单时,程序才会进行运算比较.它们的重要数据:
ResScope1.35中的是(16进制): 3D5、3182、8C33
FreeRes0.60中的是(16进制): 3D6、3183、8C34
-=End=-
_/_/_/
_/ _/_/_/ _/_/_/
_/_/
_/_/ _/ _/ _/ _/
_/
_/ _/ _/ _/
_/ _/
_/_/_/ _/_/_/ _/ _/ _/
Sam.com
6:04 2002-3-3
- 标 题:Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~ (12千字)
- 作 者:Sam.com
- 时 间:2002-3-3 14:24:48
- 链 接:http://bbs.pediy.com