• 标 题: File Protector 2001 v2.05
  • 作 者:BitRanger
  • 时 间:2002.1.9
  • 链 接:http://bbs.pediy.com

本文部分代码的HTML文件格式不太好,你也可以查看文本格式:点击查看.

一、前言
  好久没有写破解心得了,前不久在完善了自己的两个软件后(重写了核心代码),终于想找一个软件来练练了,在一张最新D版光盘上找到了这个 File Protector 2000,版本旧了点,于是去作者的主页下了一个最新版本2001 v2.05,用了一下,感觉挺不错的,于是就将它CRACK了,另外也为了丰富一下我的网站, 于是就写下了这篇详细的破解过程。总的来说,这个软件还是很好破的,首先它没有压缩,更没用ASprotect之类的反CRACK加密,所以拿到手就可动手去Tracking,说了这些,那就让我们切入正题,Let's goooooooo~!
  对了,别忘了去我的主页看看,那里有精彩的软件破解心得,软件汉化,以及本人自己写的实用软件呦!

二、TRACK工具
  这次用到了TRW2000 v1.23,还有W32DASM、HIEW。

三、破解实录
  每次我们在拿到一个软件之前,首先用FS、FI、GT2000之类的分析工具去分析一下该软件是被什么压缩软件压缩的,(本人最喜欢用的PEiDentifier,目前版本为0.7B,用它大都数经压缩软件压缩的都能查到),这次也不例外,经用PEiD分析后,发现这个软件是VC++写的,没有用压缩软件压缩。
  没有压缩就好办,免得我们还要将它剥壳(麻烦)。
  启动File Protector 2001(以下简称FP),弹出注册窗口,发现有注册名称,公司名称,以及注册序列号三项。胡乱填一下,Name:BitRanger,Commpany:BitRanger(Bit巡逻兵),Serial:123456789,注册,弹出“Registration failed !”,(好办,不像有点软件,注册序列号填入后,是在启动时验证,而不给出任何的错误提示信息),既然这个软件有错误信息框弹出,那我们就先用W32DASM打开它。

(1)  用W32DASM破获 --==>>假破
  用W32DASM打开后,“串式参考”,查找到"Registration failed !",看以下代码:

:0040D2D4 85C0                    test eaxeax
:0040D2D6 751E                    jne 0040D2F6
:0040D2D8 50                      push eax

* Possible StringData Ref from Data Obj ->"Error"
:0040D2D9 686C964100              push 0041966C
* Possible StringData Ref from Data Obj ->"Registration failed !" <=-

  向上看,有一句判断语句:
  test eax,eax ,jne ...,  

  if ( eax == 0 )
     弹出错误
  else
     跳转正确执行 --=>> 即弹出"Registration sucessfully!"注册成功

  好吧,那就让我们改 jne 为 je ,借助HIEW 的F3,F2可直接修改ASM语句。
  继续返回软件注册窗口,注册,弹出"Registration sucessfully!",好高兴呀,难道就这样给破了吗?;-)嘻,也太...

  别高兴的太早了,进入程序主界面后,发现还有Unregisted!字样,;-(怎样,不是显示已注册了吗?进入“关于”,发现软件还是没有被注册!:(

  怒发冲冠(有冠吗?)!立即操起倚天剑TRW,砍它!!!

(2)   用TRW2000破 --==>>彻底搞定
  打开TRW2000,Browse找到这个FP,Load,OK,进入TRW2000窗口了吧,F4,返回进入FP的注册窗口。
  按照常理,我们填入Name:BitRanger,Commpanny:BitRanger(Bit巡逻兵),Serial:123456789。
  Ctrl+N,进入TRW,下 bpx hmemcpy (内存复制) ,F4,返回软件注册窗口,“注册”啦,OK,被TRW正常拦截。
  bd 1  别忘了;),别告诉我不知道他的意思;-)
  F12 9次,F10几次吧,我们来到这个地址(为什么要到这个地址,你从这个地址往下再F10几次看看):

015F:0040D2C6  LEA      ECX,[ESP+18]
015F:0040D2CA  PUSH     ECX
015F:0040D2CB  LEA      ECX,[ESP+10]  
015F:0040D2CF  CALL     0040F290  <<==-- 解密算法
015F:0040D2D4  TEST     EAX,EAX    <<==-- 比较EAX
015F:0040D2D6  JNZ      0040D2F6  <<==-- 不等,跳,否则出错

  Ok, 在 0040D2CF 处,我们F8直接进入,下面,让我们进入神奇的bit世界吧~!去领略BILL构筑的天堂,去感悟人们智慧的结晶!
  以下代码,我直接写了一些注释,具体算法分析附在代码之后。
  还需要清楚一点的是,以下分析中,* 号代替 30 < * < 46 ,至于为什么,以下分析中我会讲到,还有序列号,我以具体位数代替,譬如第1位序列号,我以0代替,第10位,我以A代替,类推。

015F:0040F290  MOV      ECX,[ESP+04]  <<=-- ECX 密码存放地址
015F:0040F294  SUB      ESP,BYTE +08
015F:0040F297  MOV      AL,2D    <<=-- AL = 2D = '-'
015F:0040F299  MOV      DL,[ECX+04]  <<=-- DL = 4 = 第4位序列号
015F:0040F29C  PUSH     EBX
015F:0040F29D  CMP      DL,AL    <<=-- 4 = '-' ?
015F:0040F29F  JNZ      NEAR 0040F54F  <<=-- 不等错
015F:0040F2A5  CMP      [ECX+07],AL  <<=-- 7 = '-' ?
015F:0040F2A8  JNZ      NEAR 0040F54F  
015F:0040F2AE  CMP      [ECX+0B],AL  <<=-- B = '-' ?
015F:0040F2B1  JNZ      NEAR 0040F54F
015F:0040F2B7  CMP      [ECX+0D],AL  <<=-- D = '-' ?
015F:0040F2BA  JNZ      NEAR 0040F54F
015F:0040F2C0  CMP      [ECX+1C],AL  <<=-- 1C = '-' ?
015F:0040F2C3  JNZ      NEAR 0040F54F  
------------------------------==============>>>>>>^^^由以上已看出:
          序列号的4,7,B,D,1C位必须为'-'
          继续...
015F:0040F2C9  MOV      AL,[ECX+0F]  <<=-- AL = 0F 
015F:0040F2CC  CMP      AL,30    <<=-- OF < 30 ?
015F:0040F2CE  JL       NEAR 0040F54F
015F:0040F2D4  CMP      AL,46
015F:0040F2D6  JG       NEAR 0040F54F  <<=-- OF > 46 ?
-------------------------------===========>>>>>>>>^^^^现在知道了吧,我          为什么为 * 号代替 30 < * < 46了
          继续...
          所以序列号0F为 * 
015F:0040F2DC  MOV      AL,[ECX+10]
015F:0040F2DF  CMP      AL,30
015F:0040F2E1  JL       NEAR 0040F54F
015F:0040F2E7  CMP      AL,46
015F:0040F2E9  JG       NEAR 0040F54F  <<=-- 10 = *
015F:0040F2EF  MOV      AL,[ECX+11]
015F:0040F2F2  CMP      AL,30
015F:0040F2F4  JL       NEAR 0040F54F
015F:0040F2FA  CMP      AL,46
015F:0040F2FC  JG       NEAR 0040F54F  <<=-- 11 = * 
015F:0040F302  MOV      AL,[ECX+12]
015F:0040F305  CMP      AL,30
015F:0040F307  JL       NEAR 0040F54F
015F:0040F30D  CMP      AL,46
015F:0040F30F  JG       NEAR 0040F54F  <<=-- 12 = *
015F:0040F315  MOV      AL,[ECX+15]
015F:0040F318  CMP      AL,30
015F:0040F31A  JL       NEAR 0040F54F
015F:0040F320  CMP      AL,46
015F:0040F322  JG       NEAR 0040F54F  <<=-- 15 = *
015F:0040F328  MOV      AL,[ECX+16]
015F:0040F32B  CMP      AL,30
015F:0040F32D  JL       NEAR 0040F54F
015F:0040F333  CMP      AL,46
015F:0040F335  JG       NEAR 0040F54F  <<=-- 16 = *
015F:0040F33B  MOV      AL,[ECX+17]
015F:0040F33E  CMP      AL,30
015F:0040F340  JL       NEAR 0040F54F
015F:0040F346  CMP      AL,46
015F:0040F348  JG       NEAR 0040F54F  <<=-- 17 = *
015F:0040F34E  MOV      AL,[ECX+19]
015F:0040F351  CMP      AL,30
015F:0040F353  JL       NEAR 0040F54F
015F:0040F359  CMP      AL,46
015F:0040F35B  JG       NEAR 0040F54F  <<=-- 19 = *
015F:0040F361  CMP      BYTE [ECX],46  <<=-- 序列号第 0 位 ?= 46
015F:0040F364  JNZ      NEAR 0040F54F
015F:0040F36A  CMP      BYTE [ECX+01],50<<=-- 1 ?= 50
015F:0040F36E  JNZ      NEAR 0040F54F
015F:0040F374  CMP      BYTE [ECX+02],31<<=-- 2 ?= 31
015F:0040F378  JNZ      NEAR 0040F54F
015F:0040F37E  CMP      BYTE [ECX+03],38<<=-- 3 ?= 38
015F:0040F382  JNZ      NEAR 0040F54F
-----------------------------------==========>>>>>>>>>^^OK,序列号第        1,2,3,4位必须为 46,50,31,38,对应的ASCII码为: FP18
        继续...

015F:0040F388  MOV      DL,[ECX+05]  <<=-- 注意:从此处开始算法
015F:0040F38B  MOV      BL,[ECX+08]  <<=-- 具体算法附后,就不注释了
015F:0040F38E  MOV      [ESP+10],DL
015F:0040F392  MOV      DL,[ECX+17]
015F:0040F395  ADD      AL,DL
015F:0040F397  MOV      DL,[ECX+16]
015F:0040F39A  ADD      AL,DL
015F:0040F39C  MOV      DL,[ECX+15]
015F:0040F39F  ADD      AL,DL
015F:0040F3A1  MOV      DL,[ECX+12]
015F:0040F3A4  ADD      AL,DL
015F:0040F3A6  MOV      DL,[ECX+11]
015F:0040F3A9  ADD      AL,DL
015F:0040F3AB  MOV      DL,[ECX+10]
015F:0040F3AE  ADD      AL,DL
015F:0040F3B0  MOV      DL,[ECX+0F]
015F:0040F3B3  ADD      AL,DL
015F:0040F3B5  MOV      DL,[ESP+10]
015F:0040F3B9  XOR      AL,DL
015F:0040F3BB  MOV      DL,[ECX+0C]
015F:0040F3BE  XOR      AL,BL
015F:0040F3C0  XOR      AL,DL
015F:0040F3C2  XOR      AL,23
015F:0040F3C4  MOV      DL,AL
015F:0040F3C6  SHR      DL,04
015F:0040F3C9  ADD      DL,30
015F:0040F3CC  CMP      DL,39
015F:0040F3CF  MOV      [ESP+04],DL
015F:0040F3D3  JNA      0040F3DC
015F:0040F3D5  ADD      DL,07
015F:0040F3D8  MOV      [ESP+04],DL
015F:0040F3DC  AND      AL,0F
015F:0040F3DE  ADD      AL,30
015F:0040F3E0  CMP      AL,39
015F:0040F3E2  MOV      [ESP+08],AL
015F:0040F3E6  JNA      0040F3EE
015F:0040F3E8  ADD      AL,07
015F:0040F3EA  MOV      [ESP+08],AL
015F:0040F3EE  MOVSX    EAX,BYTE [ECX+13] <<=-- 此处注意
015F:0040F3F2  MOV      EDX,[ESP+04]    
015F:0040F3F6  AND      EDX,FF
015F:0040F3FC  CMP      EAX,EDX      <<=-- 13 = [ESP+04] and FF
015F:0040F3FE  JNZ      NEAR 0040F54F
015F:0040F404  MOV      DL,[ECX+14]    <<=-- 
015F:0040F407  PUSH     ESI
015F:0040F408  MOV      ESI,[ESP+0C]
015F:0040F40C  MOVSX    EAX,DL
015F:0040F40F  AND      ESI,FF
015F:0040F415  CMP      EAX,ESI      <<=-- 14 = [ESP+0C] and FF
015F:0040F417  POP      ESI
015F:0040F418  JNZ      NEAR 0040F54F
015F:0040F41E  MOV      AL,[ECX+0A]
015F:0040F421  ADD      AL,46
015F:0040F423  XOR      AL,[ECX+09]
015F:0040F426  XOR      AL,DL
015F:0040F428  MOV      DL,[ECX+13]
015F:0040F42B  XOR      AL,DL
015F:0040F42D  XOR      AL,BL
015F:0040F42F  XOR      AL,41
015F:0040F431  MOV      DL,AL
015F:0040F433  SHR      DL,04
015F:0040F436  ADD      DL,30
015F:0040F439  CMP      DL,39
015F:0040F43C  MOV      [ESP+04],DL
015F:0040F440  JNA      0040F449
015F:0040F442  ADD      DL,07
015F:0040F445  MOV      [ESP+04],DL
015F:0040F449  AND      AL,0F
015F:0040F44B  ADD      AL,30
015F:0040F44D  CMP      AL,39
015F:0040F44F  MOV      [ESP+08],AL
015F:0040F453  JNA      0040F45B
015F:0040F455  ADD      AL,07
015F:0040F457  MOV      [ESP+08],AL
015F:0040F45B  MOVSX    EDX,BYTE [ECX+1A]   <<=-- 
015F:0040F45F  MOV      EAX,[ESP+04]
015F:0040F463  AND      EAX,FF
015F:0040F468  CMP      EDX,EAX        <<=-- 1A = [ESP+4] and FF
015F:0040F46A  JNZ      NEAR 0040F54F
015F:0040F470  MOV      BL,[ECX+1B]      <<=--
015F:0040F473  MOV      EAX,[ESP+08]
015F:0040F477  MOVSX    EDX,BL
015F:0040F47A  AND      EAX,FF
015F:0040F47F  CMP      EDX,EAX        <<=-- 1B = [ESP+08] and FF
015F:0040F481  JNZ      NEAR 0040F54F
015F:0040F487  MOV      AL,[ECX+06]
015F:0040F48A  MOV      DL,[ECX+14]
015F:0040F48D  XOR      AL,DL
015F:0040F48F  MOV      DL,[ECX+13]
015F:0040F492  XOR      AL,DL
015F:0040F494  MOV      DL,[ESP+10]
015F:0040F498  XOR      AL,DL
015F:0040F49A  XOR      AL,AB
015F:0040F49C  MOV      DL,AL
015F:0040F49E  SHR      DL,04
015F:0040F4A1  ADD      DL,30
015F:0040F4A4  CMP      DL,39
015F:0040F4A7  MOV      [ESP+04],DL
015F:0040F4AB  JNA      0040F4B4
015F:0040F4AD  ADD      DL,07
015F:0040F4B0  MOV      [ESP+04],DL
015F:0040F4B4  AND      AL,0F
015F:0040F4B6  ADD      AL,30
015F:0040F4B8  CMP      AL,39
015F:0040F4BA  MOV      [ESP+08],AL
015F:0040F4BE  JNA      0040F4C6
015F:0040F4C0  ADD      AL,07
015F:0040F4C2  MOV      [ESP+08],AL
015F:0040F4C6  MOVSX    EDX,BYTE [ECX+0E]   <<=--
015F:0040F4CA  MOV      EAX,[ESP+04]
015F:0040F4CE  AND      EAX,FF
015F:0040F4D3  CMP      EDX,EAX             <<=-- 0E = [ESP+04] and FF
015F:0040F4D5  JNZ      0040F54F
015F:0040F4D7  MOVSX    EDX,BYTE [ECX+18]   <<=--
015F:0040F4DB  MOV      EAX,[ESP+08]
015F:0040F4DF  AND      EAX,FF
015F:0040F4E4  CMP      EDX,EAX        <<=-- 18 = [ESP+08] and FF
015F:0040F4E6  JNZ      0040F54F
015F:0040F4E8  MOV      AL,[ECX+1A]
015F:0040F4EB  MOV      DL,[ECX+0C]
015F:0040F4EE  XOR      BL,AL
015F:0040F4F0  XOR      BL,DL
015F:0040F4F2  XOR      BL,63
015F:0040F4F5  MOV      DL,BL
015F:0040F4F7  MOV      AL,DL
015F:0040F4F9  SHR      AL,04
015F:0040F4FC  ADD      AL,30
015F:0040F4FE  CMP      AL,39
015F:0040F500  MOV      [ESP+04],AL
015F:0040F504  JNA      0040F50C
015F:0040F506  ADD      AL,07
015F:0040F508  MOV      [ESP+04],AL
015F:0040F50C  AND      DL,0F
015F:0040F50F  ADD      DL,30
015F:0040F512  CMP      DL,39
015F:0040F515  MOV      [ESP+08],DL
015F:0040F519  JNA      0040F522
015F:0040F51B  ADD      DL,07
015F:0040F51E  MOV      [ESP+08],DL
015F:0040F522  MOVSX    EDX,BYTE [ECX+1D]  <<=-- 
015F:0040F526  MOV      EAX,[ESP+04]
015F:0040F52A  AND      EAX,FF
015F:0040F52F  CMP      EDX,EAX       <<=-- 1D = EAX
015F:0040F531  JNZ      0040F54F
015F:0040F533  MOVSX    ECX,BYTE [ECX+1E]  <<=-- 注意,快结束啦
015F:0040F537  MOV      EDX,[ESP+08]
015F:0040F53B  XOR      EAX,EAX       <<=-- EAX = 0 
015F:0040F53D  AND      EDX,FF
015F:0040F543  POP      EBX
015F:0040F544  CMP      ECX,EDX       <<=-- 根据比较的值,设置EAX
015F:0040F546  SETZ     AL       <<=-- 相等,则 EAX = 1  
015F:0040F549  ADD      ESP,BYTE +08
015F:0040F54C  RET      04
015F:0040F54F  XOR      EAX,EAX       <<=-- 错误,返回模块
015F:0040F551  POP      EBX
015F:0040F552  ADD      ESP,BYTE +08
015F:0040F555  RET      04

(3)  算法分析
      (注:1,2,3...1A,1B...指的是序列号的位数,而a,b,...是我用的变量)
  [1], 19 + 17 = a 
  [2], a + 16 = b
  [3], b + 15 = c
  [4], c + 12 = d
  [5], d + 11 = e
  [6], e + 10 = f
  [7], f + OF = g 
  =================  <<==---重置
  [8], g xor 5 = a
  [9], a xor 8 = b 
  [10], b xor 0c = c 
  [11], c xor 23 = d   ----------
  [12], d SHR 4        |
  [13], d + 30 = e      |
  [14], if e<= 39        |
    [esp+04] = e + 7    |
        else        |
    [esp+04] = e      |
  =================  <<==-- 重置    |
  [15],  a = d                   <--|
  [16], a and 0F = b 
  [17], b + 30 = c 
  [18], if c <= 39
     [esp+08] = c + 7
        else
     [esp+08] = c
  =====================<<==--重置
  [19], [esp+04] and OFF = a
  [20], 13 = a        <<==-- 第13位序列号
  =====================<<==--重置
  [21], [esp+0c] and oFF = a
  [22], 14 = a        <<==-- 第14位序列号
  ==================   <<==-- 重置
  [23], 0A and 46 = a 
  [24], a xor 9 = b 
  [25], b xor 14 = c
  [26], c xor 13 = d
  [27], d xor 8 = e
  [28], e xor 41 = f  ---------
  [29], f shr 4       |
  [30], f +30 = g       |
  [31], if g <= 39     |
    [esp+04] = g + 07   |
        else       |
    [esp+04] = g     |
  =================  <<==-- 重置   |
  [32], a = f       <--------|
  [33], a and 0F = b
  [34], b + 30 = c
  [35], if c <= 39
    [esp+08] = c + 07
        else
    [esp+08] = c
  =================  <<==-- 重置
  [36], a = [esp+04]
  [37], a and 0FF = b
  [38], 1A = b      <<==-- 第1A位序列号
  =================  <<==-- 重置
  [39], a = [esp+08]
  [40], a and 0FF = b
  [41], 1B = b      <<==-- 第1B位序列号
  ================   <<==-- 重置
  [42], 6 xor 14 = a
  [43], a xor 13 = b
  [44], b xor 5 = c
  [45], c xor AB = d  -----------
  ===============    <<==-- 重置     |
  [46], a = d          |
  [47], a shr 4         |
  [48], a + 30 = b       |
  [49], if b <= 39       |
     [esp+04] = b+07     |
        else         |
     [esp+04] = b       |
  ===============     <<==-- 重置     |
  [50], a = d      <-----------------|
  [51], a and 0F = b
  [52], if c <= 39
     [esp+08] = c + 7
        else
     [esp+08] = c
  ==============      <<==-- 重置
  [53], [esp+04] and 0FF = a
  [54], 0E = a       <<==-- 第0E位序列号
  =============       <<==-- 重置
  [55], [esp+08] and 0FF = a
  [56], 18 = a       <<==--- 第18位序列号
  ================    <<==-- 重置
  [57], 1A xor 1B = a
  [58], a xor 0c = b
  [59], b xor 63 = c  -----------
  ================    <<==-- 重置    |
  [60], a = c         |
  [61], a shr 4         |
  [62], a + 30 = b       |
  [63], if b <= 39       |
     [esp+04] = b+07     |
        else         |
     [esp+04] = b       |
  ================     <<==-- 重置   |
  [64], a = c     <---------------|
  [65], a and 0F = b
  [66], b + 30 = c
  [67], if c <= 39
    [esp+08] = c + 07
        else
    [esp+08] = c
  ===============     <<==-- 重置
  [68], [esp+04] and 0FF = a
  [69], 1D = a       <<==-- 第1D位序列号
  ===============     <<==-- 重置
  [70], [esp+08] and 0FF = a
  [71], 1E = a       <<==-- 第1E位序列号

  Ok,写了这么长,手都有点写累了,看上去是不是很复杂呀,其实,自己实际的跟一下,再画一张草图就什么都明白了,CRACK = 毅力 + ...
  以下是我跟的一组数据,大家如果还没有眼花的话就看看吧。

  看时,最好最大化浏览。
 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , A , B , C , D , E , F , 10 , 11 , 12 , 13 , 14 , 15 , 16
'F' 'P' '1' '8' '-'         '-'             '-'     '-'      *    *    *    *              *    *

 17 , 18 , 19 , 1A , 1B , 1C , 1D , 1E , 1F 
  *         *             '-'

  首先虚拟一组注册序列号,其中的 * 号,我用 9 来代替,你也完全可用其他数据,但要注意: 30 < * < 46 呦!

  FP18-00-000-0-0****00***0*00-000
(1)  FP18-00-000-0-09999009990900-000  --=>> 13 = 44 (D)
  FP18-00-000-0-09999D09990900-000

(2)  FP18-00-000-0-09999D09990900-000  --=>> 14 = 42 (B)
  FP18-00-000-0-09999DB9990900-000

(3)  FP18-00-000-0-09999DB9990900-000  --=>> 1A = 33 (3)
  FP18-00-000-0-09999DB9990930-000

(4)  FP18-00-000-0-09999DB9990930-000  --=>> 1B = 31 (1)
  FP18-00-000-0-09999DB9990931-000

(5)  FP18-00-000-0-09999DB9990931-000  --=>> 0E = 41 (A)
  FP18-00-000-0-A9999DB9990931-000

(6)  FP18-00-000-0-A9999DB9990931-000  --=>> 18 = 44 (D)
  FP18-00-000-0-A9999DB999D931-000

(7)  FP18-00-000-0-A9999DB999D931-000  --=>> 1D = 35 (5)
  FP18-00-000-0-A9999DB999D931-500

(8)  FP18-00-000-0-A9999DB999D931-500  --=>> 1E = 31 (1)

  FP18-00-000-0-A9999DB999D931-510  <<=-- 密码在此,终于搞定 ;-) 

  最后一句:DSQ,你在上海理工大一切还好吗?我爱你!,但天涯海角,终究注定此生无缘!

        BitRanger 小笔于 2002.1.9