• 标 题:Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~ (12千字)
  • 作 者:Sam.com
  • 时 间:2002-3-3 14:24:48
  • 链 接:http://bbs.pediy.com

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