APP资源网_中文资源在线官网_А天堂中文官网_中文在线APP资源下载网

and

Revival 的算法跟踪 算法分析

人气:0引自:中文在线APP资源下载网

 

Revival 的算法跟踪, yqmjch兄弟的一个题目

软件名称:   revive3.1 软件大小:  1079 KB软件语言:  国外软件软件类别:  国外软件 / 共享版 /应用平台:  Win9x/NT/2000/XP破解工具:   olldbg-cn v1.09【作者声明】:初学Crack,只是感兴趣,没有其它目的。可能我的描述有不到之处,请大家指正

 程序是vc++编的,没有壳.在0lldbg中下getwindowtexta中断就能到核心.前面部分就不写了.

 加载后用户名和单位名软件填好了,就填试验码 789456123012 .运行中断后不久就到:

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

004032A0  SUB     ESP, 24004032A3  PUSH    EBX004032A4  PUSH    ESI004032A5  MOV     ESI, DWORD PTR SS:[ESP+30]    ;  ESI<== 0093292C,(ASCII "789456123012")       004032A9  PUSH    EDI004032AA  MOVSX   EAX, BYTE PTR DS:[ESI]        ;  EAX <==DS:[0093292C]=37 ('7')004032AD  PUSH    EAX004032AE  CALL    Revival.0041F880              ;  这个CALL把hex值-20004032B3  ADD     ESP, 4004032B6  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    EAX004032C4  CALL    Revival.0041F880              ;  这个CALL把hex值-20004032C9  ADD     ESP, 4004032CC  CMP     EAX, 56                       ;  注册码的第3个条件:注册码的第一位是56+20=76 ('v'), 把第2位改为v再试004032CF  JNZ     Revival.0040340F----------------------CALL    Revival.0041F880||0041F880  CMP     DWORD PTR DS:[45DC20], 00041F887  PUSH    ESI0041F888  PUSH    EDI0041F889  JNZ     SHORT Revival.0041F89F0041F88B  MOV     EAX, DWORD PTR SS:[ESP+C]    ;  这一段是比较注册码第一位的取值范围hex=61-7A (小写字母)0041F88F  CMP     EAX, 61                      ;  注册码的第一个条件(把试验码改为asdfghjklzxcvbnm后继续)0041F892  JL      SHORT Revival.0041F8EB0041F894  CMP     EAX, 7A0041F897  JG      SHORT Revival.0041F8EB0041F899  SUB     EAX, 20                      ;  EAX =61-20=41  0041F89C  POP     EDI0041F89D  POP     ESI                          ;  ESI <== 0093266C,(ASCII"asdfghjklzxcvbnm")0041F89E  RETN*********************************************下面继续分析:

004032D5  CMP     BYTE PTR DS:[ESI+7], 2D       ;  注册码的第4个条件:注册码的第8位2d ('-a'), 把第8位改为-再试004032D9  JNZ     Revival.0040340F004032DF  PUSH    ESI                           ; /ESI = 0093266C,(ASCII "rvasdfg-jklzxcv")004032E0  CALL    DWORD PTR DS:[<&kernel32.lstr>; \lstrlenA004032E6  CMP     EAX, 0F                       ;  EAX = 0F (注册码的长度=15位),条件5004032E9  JNZ     Revival.0040340F004032EF  MOV     EDI, 2                        ;  EDI=2 (下面从第三位计算起)004032F4  /MOVSX   EAX, BYTE PTR DS:[ESI+EDI]   ;  EAX <== DS:[0093266E]=61 ('a')004032F8  |PUSH    EAX004032F9  |CALL    Revival.0041F810             ;  比较条件CALL004032FE  |ADD     ESP, 400403301  |TEST    EAX, EAX00403303  |JE      Revival.004033F400403309  |INC     EDI0040330A  |CMP     EDI, 70040330D  \JL      SHORT Revival.004032F40040330F   MOV     EDI, 800403314  /MOVSX   EAX, BYTE PTR DS:[ESI+EDI]00403318  |PUSH    EAX00403319  |CALL    Revival.0041F8100040331E  |ADD     ESP, 400403321  |TEST    EAX, EAX00403323  |JE      Revival.004033FD00403329  |INC     EDI0040332A  |CMP     EDI, 0F0040332D  \JL      SHORT Revival.00403314

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

CALL    Revival.0041F810 ||

0041F810  CMP     DWORD PTR DS:[45D9DC], 10041F817  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, EAX0041F831  MOV     ECX, DWORD PTR SS:[ESP+4]     ;  ECX <== SS:[0012F500]=61 ('a')0041F835  MOV     AX, WORD PTR DS:[EDX+ECX*2]   ;  用ECX的值做指针,来寻址.计算方法=基址+各位hex*20041F839  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 不等于00045D840  84 00 84 00 84 00 84 00  ????       //84的偏移量=45D83A-45D7DA=60H++2 ==>6AH0045D848  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], 000403341  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              ;  计算的CALL0041F80A  ADD     ESP, 40041F80D  RETN-----------------------CALL    Revival.0041F750||0041F750  PUSH    EBX0041F751  PUSH    ESI0041F752  MOV     ESI, DWORD PTR SS:[ESP+C]     ;  ESI =0012F514,(ASCII "01") 第三 四位0041F756  PUSH    EDI0041F757  PUSH    EBP0041F758  MOV     EDI, 1                        ;  EDI=10041F75D  /CMP     DWORD PTR DS:[45D9DC], EDI0041F763  |JLE     SHORT Revival.0041F7760041F765  |PUSH    80041F767  |XOR     EAX, EAX0041F769  |MOV     AL, BYTE PTR DS:[ESI]0041F76B  |PUSH    EAX0041F76C  |CALL    Revival.004236100041F771  |ADD     ESP, 80041F774  |JMP     SHORT Revival.0041F7890041F776  |XOR     EDX, EDX0041F778  |MOV     ECX, DWORD PTR DS:[45D7D0]   ;  ECX <== DS:[0045D7D0] (参数的基地址)0041F77E  |MOV     DL, BYTE PTR DS:[ESI]        ;  DL <== DS:[0012F514]=30 ('0')0041F780  |XOR     EAX, EAX0041F782  |MOV     AX, WORD PTR DS:[ECX+EDX*2]  ;  用DL值做寻值的指针,偏移量=DL*20041F786  |AND     EAX, 8                       ;  计算方法0041F789  |TEST    EAX, EAX                     ;  注册码的判断条件,即DL*2偏移处的值AND 8 不能等于00041F78B  |JE      SHORT Revival.0041F790       ;  条件不成立就跳0041F78D  |INC     ESI0041F78E  \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, EBX0041F792  MOV     BL, BYTE PTR DS:[ESI]          ;  BL <== DS:[0012F514]=30 ('0') || =33 ||=370041F794  INC     ESI                            ;  ESI ++0041F795  MOV     EDI, EBX                       ;  EDI <== 300041F797  CMP     EBX, 2D0041F79A  JE      SHORT Revival.0041F7A10041F79C  CMP     EBX, 2B0041F79F  JNZ     SHORT Revival.0041F7A60041F7A1  XOR     EBX, EBX0041F7A3  MOV     BL, BYTE PTR DS:[ESI]0041F7A5  INC     ESI0041F7A6  XOR     EBP, EBP0041F7A8  /CMP     DWORD PTR DS:[45D9DC], 1      ;  DS:[45D9DC]=010041F7AF  |JLE     SHORT Revival.0041F7BE0041F7B1  |PUSH    40041F7B3  |PUSH    EBX0041F7B4  |CALL    Revival.004236100041F7B9  |ADD     ESP, 80041F7BC  |JMP     SHORT Revival.0041F7CD0041F7BE  |MOV     ECX, DWORD PTR DS:[45D7D0]    ;  如果上面的条件都不成立,就跳到这里 ECX <== DS:[00457D0] (基地址)0041F7C4  |XOR     EAX, EAX0041F7C6  |MOV     AX, WORD PTR DS:[ECX+EBX*2]   ;  EBX =30 还是用第三位的hex值来做指针寻址0041F7CA  |AND     EAX, 4                        ;  计算方法0041F7CD  |TEST    EAX, EAX                      ;  注册码的判断条件,即DL*2偏移处的值AND 4 不能等于00041F7CF  |JE      SHORT Revival.0041F7E10041F7D1  |LEA     EAX, DWORD PTR SS:[EBP+EBP*4] ; EBP=0 ,第二次它就是把试验码*5==>EAX中,这个值有用0041F7D5  |INC     ESI                           ;  //EAX =0 ;EAX =HEX*50041F7D6  |LEA     EBP, DWORD PTR DS:[EBX+EAX*2->;  EBP <== 01 |<==03  这个计算是把十六进制转化为ASCII值,因为EAX=0||第二次计算的时候0041F7DA  |XOR     EBX, EBX                      ;  //就是把后一位的hex+前一位值*A-300041F7DC  |MOV     BL, BYTE PTR DS:[ESI-1]       ;  BL <== DS:[0012F515]=31 ('1')0041F7DF  \JMP     SHORT Revival.0041F7A80041F7E1  MOV     EAX, EBP                       ;  EAX <==EBP (经过上面计算的值) ||(78901) =13435|||(56)=380041F7E3  CMP     EDI, 2D0041F7E6  JNZ     SHORT Revival.0041F7EF0041F7E8  NEG     EAX0041F7EA  POP     EBP0041F7EB  POP     EDI0041F7EC  POP     ESI0041F7ED  POP     EBX0041F7EE  RETN-----------------这一段要分析一下: 下面要的四个关键值的计算1.第一次用试验码的第三位,第四位进行如下计算:后一位值+前一位值*A  例如:(01)==>1+0*A=012.第二次用试验码的第六位,第七位进行相同计算:后一位值+前一位值*A  例如:(34)==>4+3*A=223.第三次用试验码的最后五位进行如下计算:前一位值*A+后一位值 ,然后把前面的值*A+后一位的值例如(78901)==>1+(0+(9+(8+7*a)*a)*a)*a=134354.第四次用试验码的第九位,第十位进行如下计算:前一位值*A+后一位值  例如:(56)==>6+5*A=38

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

00403347   MOV     CX, WORD PTR DS:[ESI+5]        ;  CX = 3433 ("34")0040334B   ADD     ESP, 40040334E   MOV     WORD PTR SS:[ESP+10], CX       ;  CX ==>SS:[0012F514]00403353   SUB     AL, 13                         ;  AL =01 SUB 13=EE  |这里把第一组值-1300403355   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], 000403362   PUSH    ECX00403363   CALL    Revival.0041F800               *********第二次调用00403368   LEA     EDX, DWORD PTR SS:[ESP+14]     ;  EDX <== 0012F514,(ASCII "34")0040336C   ADD     ESP, 40040336F   LEA     EBX, DWORD PTR DS:[EAX-25]     ;  EBX <== EAX(上面CALL计算的值)-25=FFFFFFFD  |第二组计算的值-2500403372   LEA     ECX, DWORD PTR DS:[ESI+A]      ;  ECX <== DS:[ESI+A]=00932676,(ASCII "78901"). 试验码的后五位00403375   PUSH    EDX                            ;  EDX =3400403376   MOV     EAX, DWORD PTR DS:[ECX]        ;  EAX <== DS:[00932676]=3039383700403378   MOV     DWORD PTR DS:[EDX], EAX        ;  DS:[0012F514] <== 033938370040337A   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], 000403385   CALL    Revival.0041F800               *********第三次调用0040338A   ADD     ESP, 40040338D   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], AX0040339D   LEA     EAX, DWORD PTR SS:[ESP+10]     ;  EAX <== SS:[ESP+10]=0012F514,(ASCII "56901")004033A1   MOV     BYTE PTR SS:[ESP+12], 0004033A6   MOVZX   EDI, DI                        ;  EDI<==605D004033A9   PUSH    EAX004033AA   CALL    Revival.0041F800               *********第四次调用004033AF   MOV     BYTE PTR SS:[ESP+14], AL       ;  SS:[0012F514]=38  ,第四次的值004033B3   ADD     ESP, 4004033B6   XOR     EAX, EAX004033B8   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   CDQ004033C9   IDIV    ECX                            ;  ECX = 64  IDIV  EAX = 615D ==>EAX =F9 EDX=19004033CB   MOV     CL, DL                         ;  CL <== 19004033CD   XOR     EAX, EAX004033CF   MOV     AL, BYTE PTR SS:[ESP+C]        ;  AL <== SS:[0012F510]=EE ,第一次的值004033D3   LEA     EAX, DWORD PTR DS:[EAX+EDI+3]  ;  EAX =EE+605D+3= 614E004033D7   CDQ004033D8   IDIV    EBX                            ;  EAX =614E IDIV EBX=A ==>EAX=9BB EDX=000004033DA   SUB     DL, BYTE PTR DS:[ESI+4]        ;  DL =DL-32 ('2') ,试验码的第五位004033DD   CMP     DL, 0D0                        ;  DL =CE004033E0   JNZ     SHORT Revival.00403406         ;  注册码的正确条件7004033E2   CMP     CL, BYTE PTR SS:[ESP+10]       ;  CL = 19    SS:[ESP+10] =SS:[0012F514]=38004033E6   JNZ     SHORT Revival.00403406         ;  注册码的正确条件8004033E8   MOV     EAX, 1004033ED   POP     EDI004033EE   POP     ESI004033EF   POP     EBX004033F0   ADD     ESP, 24004033F3   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

专题文集:破解文章 windows
引用标题:《and》
来源地址:https://www.xjanfang.cn/news/tpart-21155.html