Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~ (12千字)

看雪資料發表於2002-03-03

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

相關文章