Revival 的演算法跟蹤

看雪資料發表於2015-11-15

標 題:Revival 的演算法跟蹤

發信人:fxyang 

時 間:2003/03/02 00:02am

詳細資訊: 



Revival 的演算法跟蹤, yqmjch兄弟的一個題目


軟體名稱:   revive3.1
下載地址:  ftp://www.newhua.com/revive31.zip
軟體大小:  1079 KB
軟體語言:  國外軟體
軟體類別:  國外軟體 / 共享版 /
應用平臺:  Win9x/NT/2000/XP
破解工具:   olldbg-cn v1.09
【作者宣告】:初學Crack,只是感興趣,沒有其它目的。可能我的描述有不到之處,請大家指正

 程式是vc++編的,沒有殼.在0lldbg中下getwindowtexta中斷就能到核心.前面部分就不寫了.

 載入後使用者名稱和單位名軟體填好了,就填試驗碼 789456123012 .執行中斷後不久就到:

****************************************************************

004032A0  SUB     ESP, 24
004032A3  PUSH    EBX
004032A4  PUSH    ESI
004032A5  MOV     ESI, DWORD PTR SS:[ESP+30]    ;  ESI<== 0093292C,(ASCII "789456123012")      
004032A9  PUSH    EDI
004032AA  MOVSX   EAX, BYTE PTR DS:[ESI]        ;  EAX <==DS:[0093292C]=37 ('7')
004032AD  PUSH    EAX
004032AE  CALL    Revival.0041F880              ;  這個CALL把hex值-20
004032B3  ADD     ESP, 4
004032B6  CMP     EAX, 52                       ;  比較第一位是不是52+20=72 ('r')
004032B9  JNZ     Revival.0040340F              ;  註冊碼的第二個條件:註冊碼的第一位是('r'), 把第一位改為r再試
004032BF  MOVSX   EAX, BYTE PTR DS:[ESI+1]      ;  EAX <== DS:[0093292D] = 61 ('a')
004032C3  PUSH    EAX
004032C4  CALL    Revival.0041F880              ;  這個CALL把hex值-20
004032C9  ADD     ESP, 4
004032CC  CMP     EAX, 56                       ;  註冊碼的第3個條件:註冊碼的第一位是56+20=76 ('v'), 把第2位改為v再試
004032CF  JNZ     Revival.0040340F
----------------------
CALL    Revival.0041F880
|
|
0041F880  CMP     DWORD PTR DS:[45DC20], 0
0041F887  PUSH    ESI
0041F888  PUSH    EDI
0041F889  JNZ     SHORT Revival.0041F89F
0041F88B  MOV     EAX, DWORD PTR SS:[ESP+C]    ;  這一段是比較註冊碼第一位的取值範圍hex=61-7A (小寫字母)
0041F88F  CMP     EAX, 61                      ;  註冊碼的第一個條件(把試驗碼改為asdfghjklzxcvbnm後繼續)
0041F892  JL      SHORT Revival.0041F8EB
0041F894  CMP     EAX, 7A
0041F897  JG      SHORT Revival.0041F8EB
0041F899  SUB     EAX, 20                      ;  EAX =61-20=41  
0041F89C  POP     EDI
0041F89D  POP     ESI                          ;  ESI <== 0093266C,(ASCII"asdfghjklzxcvbnm")
0041F89E  RETN
*********************************************
下面繼續分析:

004032D5  CMP     BYTE PTR DS:[ESI+7], 2D       ;  註冊碼的第4個條件:註冊碼的第8位2d ('-a'), 把第8位改為-再試
004032D9  JNZ     Revival.0040340F
004032DF  PUSH    ESI                           ; /ESI = 0093266C,(ASCII "rvasdfg-jklzxcv")
004032E0  CALL    DWORD PTR DS:[<&KERNEL32.lstr>; \lstrlenA
004032E6  CMP     EAX, 0F                       ;  EAX = 0F (註冊碼的長度=15位),條件5
004032E9  JNZ     Revival.0040340F
004032EF  MOV     EDI, 2                        ;  EDI=2 (下面從第三位計算起)
004032F4  /MOVSX   EAX, BYTE PTR DS:[ESI+EDI]   ;  EAX <== DS:[0093266E]=61 ('a')
004032F8  |PUSH    EAX
004032F9  |CALL    Revival.0041F810             ;  比較條件CALL
004032FE  |ADD     ESP, 4
00403301  |TEST    EAX, EAX
00403303  |JE      Revival.004033F4
00403309  |INC     EDI
0040330A  |CMP     EDI, 7
0040330D  \JL      SHORT Revival.004032F4
0040330F   MOV     EDI, 8
00403314  /MOVSX   EAX, BYTE PTR DS:[ESI+EDI]
00403318  |PUSH    EAX
00403319  |CALL    Revival.0041F810
0040331E  |ADD     ESP, 4
00403321  |TEST    EAX, EAX
00403323  |JE      Revival.004033FD
00403329  |INC     EDI
0040332A  |CMP     EDI, 0F
0040332D  \JL      SHORT Revival.00403314

-----------------------------------------------------

CALL    Revival.0041F810
|
|

0041F810  CMP     DWORD PTR DS:[45D9DC], 1
0041F817  JLE     SHORT Revival.0041F829        ;這裡一定跳
0041F819  MOV     ECX, DWORD PTR SS:[ESP+4]          |
0041F81D  PUSH    4                                  |
0041F81F  PUSH    ECX                                |
0041F820  CALL    Revival.00423610                   |
0041F825  ADD     ESP, 8                            \|/
0041F828  RETN                                       .
0041F829  MOV     EDX, DWORD PTR DS:[45D7D0]    ;  Revival.0045D7DA (定址的基址)
0041F82F  XOR     EAX, EAX
0041F831  MOV     ECX, DWORD PTR SS:[ESP+4]     ;  ECX <== SS:[0012F500]=61 ('a')
0041F835  MOV     AX, WORD PTR DS:[EDX+ECX*2]   ;  用ECX的值做指標,來定址.計算方法=基址+各位hex*2
0041F839  AND     EAX, 4                        ;  EAX =EAX AND 4  定址得到的值再計算
0041F83C  RETN                                  ;  條件6--EAX AND 4 不等於0 ,就正確.

++++++++++++++++++++++++++++++++++++++++++++++++++++++
這是記憶體中陣列的值:

  0045D7DA ==> 20 00 20 00 20 00  .. . . .
0045D7E0  20 00 20 00 20 00 20 00   . . . .
0045D7E8  20 00 20 00 28 00 28 00   . .(.(.                        
0045D7F0  28 00 28 00 28 00 20 00  (.(.(. .
0045D7F8  20 00 20 00 20 00 20 00   . . . .
0045D800  20 00 20 00 20 00 20 00   . . . .
0045D808  20 00 20 00 20 00 20 00   . . . .
0045D810  20 00 20 00 20 00 20 00   . . . .
0045D818  20 00 48 00 10 00 10 00   .H...
0045D820  10 00 10 00 10 00 10 00  ....
0045D828  10 00 10 00 10 00 10 00  ....
0045D830  10 00 10 00 10 00 10 00  ....
0045D838  10 00 84 00 84 00 84 00  .???      ;經過分析發現記憶體中的值只有84 AND 4 不等於0
0045D840  84 00 84 00 84 00 84 00  ????       //84的偏移量=45D83A-45D7DA=60H++2 ==>6AH
0045D848  84 00 84 00 84 00 10 00  ???.      //那麼第三位值應該=60/2=30 ('0')++ ==>39 ('9')
0045D850  10 00 10 00 10 00 10 00  ....   ;上面的計算告訴我們從第三位開始取值的範圍(0-9)
0045D858  10 00 10 00 81 00 81 00  ..??      //把試驗碼改為:rv01234-5678901 後繼續
0045D860  81 00 81 00 81 00 81 00  ????
0045D868  01 00 01 00 01 00 01 00  ....
0045D870  01 00 01 00 01 00 01 00  ....
0045D878  01 00 01 00 01 00 01 00  ....
0045D880  01 00 01 00 01 00 01 00  ....
0045D888  01 00 01 00 01 00 01 00  ....
0045D890  10 00 10 00 10 00 10 00  ....
0045D898  10 00 10 00 82 00 82 00  ..??
0045D8A0  82 00 82 00 82 00 82 00  ????
0045D8A8  02 00 02 00 02 00 02 00  ....
0045D8B0  02 00 02 00 02 00 02 00  ....
0045D8B8  02 00 02 00 02 00 02 00  ....
0045D8C0  02 00 02 00 02 00 02 00  ....
0045D8C8  02 00 02 00 02 00 02 00  ....
0045D8D0  10 00 10 00 10 00 10 00  ....

=======================================================================================

下面繼續我們的

0040332F  MOV     AX, WORD PTR DS:[ESI+2]       ;  AX <==DS:[ESI+2](取二位)=DS:[0093266E]=3130 ('01')
00403333  MOV     WORD PTR SS:[ESP+10], AX      ;  AX ==>SS:[0012F514]
00403338  LEA     EAX, DWORD PTR SS:[ESP+10]
0040333C  MOV     BYTE PTR SS:[ESP+12], 0
00403341  PUSH    EAX                           ;  EAX =0012F514,(ASCII "01") 第三 四位
00403342  CALL    Revival.0041F800             *********第一次呼叫


------------------------
CALL    Revival.0041F800
|
|

0041F800  MOV     EAX, DWORD PTR SS:[ESP+4]
0041F804  PUSH    EAX                           ;  EAX =0012F514,(ASCII "01") 第三 四位
0041F805  CALL    Revival.0041F750              ;  計算的CALL
0041F80A  ADD     ESP, 4
0041F80D  RETN
-----------------------
CALL    Revival.0041F750
|
|
0041F750  PUSH    EBX
0041F751  PUSH    ESI
0041F752  MOV     ESI, DWORD PTR SS:[ESP+C]     ;  ESI =0012F514,(ASCII "01") 第三 四位
0041F756  PUSH    EDI
0041F757  PUSH    EBP
0041F758  MOV     EDI, 1                        ;  EDI=1
0041F75D  /CMP     DWORD PTR DS:[45D9DC], EDI
0041F763  |JLE     SHORT Revival.0041F776
0041F765  |PUSH    8
0041F767  |XOR     EAX, EAX
0041F769  |MOV     AL, BYTE PTR DS:[ESI]
0041F76B  |PUSH    EAX
0041F76C  |CALL    Revival.00423610
0041F771  |ADD     ESP, 8
0041F774  |JMP     SHORT Revival.0041F789
0041F776  |XOR     EDX, EDX
0041F778  |MOV     ECX, DWORD PTR DS:[45D7D0]   ;  ECX <== DS:[0045D7D0] (引數的基地址)
0041F77E  |MOV     DL, BYTE PTR DS:[ESI]        ;  DL <== DS:[0012F514]=30 ('0')
0041F780  |XOR     EAX, EAX
0041F782  |MOV     AX, WORD PTR DS:[ECX+EDX*2]  ;  用DL值做尋值的指標,偏移量=DL*2
0041F786  |AND     EAX, 8                       ;  計算方法
0041F789  |TEST    EAX, EAX                     ;  註冊碼的判斷條件,即DL*2偏移處的值AND 8 不能等於0
0041F78B  |JE      SHORT Revival.0041F790       ;  條件不成立就跳
0041F78D  |INC     ESI
0041F78E  \JMP     SHORT Revival.0041F75D

++++++++++++++++++++++++++++++++++++++++++++++++++++++
這是記憶體中陣列的值:

0045D7D0  DA D7 45 00 DA D7 45 00  謐E.謐E.
0045D7D8  00 00 20 00 20 00 20 00  .. . . .
0045D7E0  20 00 20 00 20 00 20 00   . . . .
0045D7E8  20 00 20 00 28 00 28 00   . .(.(.
0045D7F0  28 00 28 00 28 00 20 00  (.(.(. .
0045D7F8  20 00 20 00 20 00 20 00   . . . .
0045D800  20 00 20 00 20 00 20 00   . . . .
0045D808  20 00 20 00 20 00 20 00   . . . .
0045D810  20 00 20 00 20 00 20 00   . . . .
0045D818  20 00 48 00 10 00 10 00   .H...
0045D820  10 00 10 00 10 00 10 00  ....
0045D828  10 00 10 00 10 00 10 00  ....
0045D830  10 00 10 00 10 00 10 00  ....
0045D838  10 00 84 00 84 00 84 00  .???           ;由於偏移量最小是從45D83A開始的.
0045D840  84 00 84 00 84 00 84 00  ????            ;分析下面的各個值沒有符合條件的.
0045D848  84 00 84 00 84 00 10 00  ???.
0045D850  10 00 10 00 10 00 10 00  ....
0045D858  10 00 10 00 81 00 81 00  ..??
0045D860  81 00 81 00 81 00 81 00  ????
0045D868  01 00 01 00 01 00 01 00  ....
0045D870  01 00 01 00 01 00 01 00  ....
0045D878  01 00 01 00 01 00 01 00  ....
0045D880  01 00 01 00 01 00 01 00  ....
0045D888  01 00 01 00 01 00 01 00  ....
0045D890  10 00 10 00 10 00 10 00  ....
0045D898  10 00 10 00 82 00 82 00  ..??
0045D8A0  82 00 82 00 82 00 82 00  ????
0045D8A8  02 00 02 00 02 00 02 00  ....
0045D8B0  02 00 02 00 02 00 02 00  ....
0045D8B8  02 00 02 00 02 00 02 00  ....
0045D8C0  02 00 02 00 02 00 02 00  ....
0045D8C8  02 00 02 00 02 00 02 00  ....
0045D8D0  10 00 10 00 10 00 10 00  ....
0045D8D8  20 00 00 00 00 00 00 00   .......
--------------
這一段只是為下面服務的

==============================================
繼續:
-----
|
|
0041F790  XOR     EBX, EBX
0041F792  MOV     BL, BYTE PTR DS:[ESI]          ;  BL <== DS:[0012F514]=30 ('0') || =33 ||=37
0041F794  INC     ESI                            ;  ESI ++
0041F795  MOV     EDI, EBX                       ;  EDI <== 30
0041F797  CMP     EBX, 2D
0041F79A  JE      SHORT Revival.0041F7A1
0041F79C  CMP     EBX, 2B
0041F79F  JNZ     SHORT Revival.0041F7A6
0041F7A1  XOR     EBX, EBX
0041F7A3  MOV     BL, BYTE PTR DS:[ESI]
0041F7A5  INC     ESI
0041F7A6  XOR     EBP, EBP
0041F7A8  /CMP     DWORD PTR DS:[45D9DC], 1      ;  DS:[45D9DC]=01
0041F7AF  |JLE     SHORT Revival.0041F7BE
0041F7B1  |PUSH    4
0041F7B3  |PUSH    EBX
0041F7B4  |CALL    Revival.00423610
0041F7B9  |ADD     ESP, 8
0041F7BC  |JMP     SHORT Revival.0041F7CD
0041F7BE  |MOV     ECX, DWORD PTR DS:[45D7D0]    ;  如果上面的條件都不成立,就跳到這裡 ECX <== DS:[00457D0] (基地址)
0041F7C4  |XOR     EAX, EAX
0041F7C6  |MOV     AX, WORD PTR DS:[ECX+EBX*2]   ;  EBX =30 還是用第三位的hex值來做指標定址
0041F7CA  |AND     EAX, 4                        ;  計算方法
0041F7CD  |TEST    EAX, EAX                      ;  註冊碼的判斷條件,即DL*2偏移處的值AND 4 不能等於0
0041F7CF  |JE      SHORT Revival.0041F7E1
0041F7D1  |LEA     EAX, DWORD PTR SS:[EBP+EBP*4] ; EBP=0 ,第二次它就是把試驗碼*5==>EAX中,這個值有用
0041F7D5  |INC     ESI                           ;  //EAX =0 ;EAX =HEX*5
0041F7D6  |LEA     EBP, DWORD PTR DS:[EBX+EAX*2->;  EBP <== 01 |<==03  這個計算是把十六進位制轉化為ASCII值,因為EAX=0||第二次計算的時候
0041F7DA  |XOR     EBX, EBX                      ;  //就是把後一位的hex+前一位值*A-30
0041F7DC  |MOV     BL, BYTE PTR DS:[ESI-1]       ;  BL <== DS:[0012F515]=31 ('1')
0041F7DF  \JMP     SHORT Revival.0041F7A8
0041F7E1  MOV     EAX, EBP                       ;  EAX <==EBP (經過上面計算的值) ||(78901) =13435|||(56)=38
0041F7E3  CMP     EDI, 2D
0041F7E6  JNZ     SHORT Revival.0041F7EF
0041F7E8  NEG     EAX
0041F7EA  POP     EBP
0041F7EB  POP     EDI
0041F7EC  POP     ESI
0041F7ED  POP     EBX
0041F7EE  RETN
-----------------
這一段要分析一下: 下面要的四個關鍵值的計算
1.第一次用試驗碼的第三位,第四位進行如下計算:後一位值+前一位值*A  例如:(01)==>1+0*A=01
2.第二次用試驗碼的第六位,第七位進行相同計算:後一位值+前一位值*A  例如:(34)==>4+3*A=22
3.第三次用試驗碼的最後五位進行如下計算:前一位值*A+後一位值 ,然後把前面的值*A+後一位的值
例如(78901)==>1+(0+(9+(8+7*a)*a)*a)*a=13435
4.第四次用試驗碼的第九位,第十位進行如下計算:前一位值*A+後一位值  例如:(56)==>6+5*A=38

======================================================================================

00403347   MOV     CX, WORD PTR DS:[ESI+5]        ;  CX = 3433 ("34")
0040334B   ADD     ESP, 4
0040334E   MOV     WORD PTR SS:[ESP+10], CX       ;  CX ==>SS:[0012F514]
00403353   SUB     AL, 13                         ;  AL =01 SUB 13=EE  |這裡把第一組值-13
00403355   LEA     ECX, DWORD PTR SS:[ESP+10]     ;  ECX <==0012F514, (ASCII "34")
00403359   MOV     BYTE PTR SS:[ESP+C], AL        ;  AL =EE  ==>SS:[0012F510]  |第一組的值儲存在這裡
0040335D   MOV     BYTE PTR SS:[ESP+12], 0
00403362   PUSH    ECX
00403363   CALL    Revival.0041F800               *********第二次呼叫
00403368   LEA     EDX, DWORD PTR SS:[ESP+14]     ;  EDX <== 0012F514,(ASCII "34")
0040336C   ADD     ESP, 4
0040336F   LEA     EBX, DWORD PTR DS:[EAX-25]     ;  EBX <== EAX(上面CALL計算的值)-25=FFFFFFFD  |第二組計算的值-25
00403372   LEA     ECX, DWORD PTR DS:[ESI+A]      ;  ECX <== DS:[ESI+A]=00932676,(ASCII "78901"). 試驗碼的後五位
00403375   PUSH    EDX                            ;  EDX =34
00403376   MOV     EAX, DWORD PTR DS:[ECX]        ;  EAX <== DS:[00932676]=30393837
00403378   MOV     DWORD PTR DS:[EDX], EAX        ;  DS:[0012F514] <== 03393837
0040337A   MOV     CL, BYTE PTR DS:[ECX+4]        ;  CL <== DS:[ECX+4]=31 ('1') 試驗碼的最後一位
0040337D   MOV     BYTE PTR DS:[EDX+4], CL        ;  第五位也轉移過來
00403380   MOV     BYTE PTR SS:[ESP+19], 0
00403385   CALL    Revival.0041F800               *********第三次呼叫
0040338A   ADD     ESP, 4
0040338D   MOV     EDI, EAX                       ;  EDI <==13435 (後五位經過上面計算的值)
0040338F   XOR     DI, 5468                       ;  DI=3435 XOR 5468=605D  (只取這個值的後四位計算)
00403394   MOV     AX, WORD PTR DS:[ESI+8]        ;  AX <== DS:[00932674]=3635 ("56") ,試驗碼的第九第十位
00403398   MOV     WORD PTR SS:[ESP+10], AX
0040339D   LEA     EAX, DWORD PTR SS:[ESP+10]     ;  EAX <== SS:[ESP+10]=0012F514,(ASCII "56901")
004033A1   MOV     BYTE PTR SS:[ESP+12], 0
004033A6   MOVZX   EDI, DI                        ;  EDI<==605D
004033A9   PUSH    EAX
004033AA   CALL    Revival.0041F800               *********第四次呼叫
004033AF   MOV     BYTE PTR SS:[ESP+14], AL       ;  SS:[0012F514]=38  ,第四次的值
004033B3   ADD     ESP, 4
004033B6   XOR     EAX, EAX
004033B8   MOV     ECX, 64                        ;  ECX =64    <--引數
004033BD   MOV     AL, BL                         ;  AL =FD     ,第二次的值
004033BF   MOV     EBX, 0A                        ;  EBX <=0A   <--引數
004033C4   LEA     EAX, DWORD PTR DS:[EAX+EDI+3]  ;  EAX <==FD+6150D+3 ,第三次的值
004033C8   CDQ
004033C9   IDIV    ECX                            ;  ECX = 64  IDIV  EAX = 615D ==>EAX =F9 EDX=19
004033CB   MOV     CL, DL                         ;  CL <== 19
004033CD   XOR     EAX, EAX
004033CF   MOV     AL, BYTE PTR SS:[ESP+C]        ;  AL <== SS:[0012F510]=EE ,第一次的值
004033D3   LEA     EAX, DWORD PTR DS:[EAX+EDI+3]  ;  EAX =EE+605D+3= 614E
004033D7   CDQ
004033D8   IDIV    EBX                            ;  EAX =614E IDIV EBX=A ==>EAX=9BB EDX=000
004033DA   SUB     DL, BYTE PTR DS:[ESI+4]        ;  DL =DL-32 ('2') ,試驗碼的第五位
004033DD   CMP     DL, 0D0                        ;  DL =CE
004033E0   JNZ     SHORT Revival.00403406         ;  註冊碼的正確條件7
004033E2   CMP     CL, BYTE PTR SS:[ESP+10]       ;  CL = 19    SS:[ESP+10] =SS:[0012F514]=38
004033E6   JNZ     SHORT Revival.00403406         ;  註冊碼的正確條件8
004033E8   MOV     EAX, 1
004033ED   POP     EDI
004033EE   POP     ESI
004033EF   POP     EBX
004033F0   ADD     ESP, 24
004033F3   RETN

#####################################################################################
以上演算法分析已經完成,下面來總結註冊碼的計算方法: 註冊碼的長度=15位

  1.首先看註冊碼的前二位比較容易固定值rv
  2.註冊碼的第八位是 2D('-')
  3.註冊碼的其他幾位必須是數字
  4.其他幾位正確的條件:設第一次計算的值為M ,第二次的值為N ,第三次值的後四位為J ,第四次計算的值為K

          1).(M+(J XOR 5468)+3) MOD A + D0 = 註冊碼的第五位
          2).(N+(J XOR 5468)+3) MOD 64 = k

  5.假如我們知道M N J K

    這樣註冊碼的這幾位可以知道假設了: rv01?34-??78901

  6.為了使上式成立,我們做如下分析:

  從 K 分析: 設K=19 ,第九位為T1 ,第十位為T2
               則:T2=19-T1*A >=0 ; T1 的取值範圍只能是 2  那麼 T2 =19-2*A=5
  這樣把註冊碼設成:rv01???-2578901
  現在來分析一下它對第一個條件能不能成立:
          1).(M+(J XOR 5468)+3) MOD A = 註冊碼的第五位  
             上式改為註冊碼的第五位=6145 MOD A =0

  把註冊碼改為:rv01034-2578901
 
幾點說明:  
  1.這個軟體的註冊碼如果不進行假設的話,可能很難知道結果.
  2.SUB     DL, BYTE PTR DS:[ESI+4]        ;  DL =DL-32 ('2') ,試驗碼的第五位
    (M+(J XOR 5468)+3) MOD A = 註冊碼的第五位,這個我是怎麼知道的
    原來 MOD A 得到的值是<A -30以上的值是負數,我無法用計算器計算,只好用sice的計算功能才
   知道0-30=D0 ,因此上面式子就是:
    SUB     DL, BYTE PTR DS:[ESI+4]  
    CMP     DL, 0D0  
    JNZ     SHORT Revival.00403406   <== 不能跳
   成立的描述.
 3.以上演算法得到的註冊碼,能註冊成功,但是重新啟動時不能透過,請老師們斧正


                                                              fxyang

                                                            2003.3.1

相關文章