• 标 题:《新剑侠情缘》光盘版变硬盘版  
  • 作 者:laoqian
  • 时 间:2002/01/09 03:39pm 
  • 链 接:http://bbs.pediy.com

前天去买了一张单张光盘的《新剑侠情缘》(正版要几张不知道),安装时看见上面只有500多MB安装文件,心想可能是硬盘版,正在暗暗高兴俺的光驱可以不受罪啦!,安装完毕,取出光盘,马上启动游戏,咚!!!!“请插入《新剑侠情缘》的第一号光盘,再重新运行本程序。”!!我X,D盘也,嗨,只得自己想办法!
   读取光盘信息的软件(此类软件多为游戏软件)一般要调用"GetDriveTypeA(判断一个驱动器的类型)"以及"GetVolumeInformationA(返回卷标信息)等相关API函数,所以只要反编译成功后有针对性的分析这些函数所在位置的代码,并细心注意关键跳跃指令,往往起到事半功倍的效果。有时这些函数可能出现多个,也许单独出现,也许混合出现,但80%以上都是对光盘进行校验。
  这就动手!
  找到可执行文件NewSword.exe,一看只有280多k,有点怀疑,就用fi检查没有加壳(可能让D版者给脱了?!)。运行 W32dsm89 打开NewSword.exe,反编译成功后,单击“Imports”查看程序调用的相关函数,找到“KERNEL32.GetDriveTypeA”后双击将其打开,我们可看到如下代码:


* Reference To: KERNEL32.SetErrorMode, Ord:0264h
                                 |
:0040A507 8B2D20B04300            mov ebp, dword ptr [0043B020]

* Reference To: KERNEL32.GetVolumeInformationA, Ord:0177h  0177h    <<----这里是重点!!!!GetVolumeInformationA函数是获得盘符卷标的,看看第一张光盘的卷标是什么。
                                 |
:0040A50D 8B1D24B04300            mov ebx, dword ptr [0043B024]
:0040A513 C744241000000000        mov [esp+10], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A5A6(C)
|
:0040A51B 8D4C243C                lea ecx, dword ptr [esp+3C]
:0040A51F 51                      push ecx

* Reference To: KERNEL32.GetDriveTypeA, Ord:0104h     <<-----API函数标志,判断一个驱动器的类型
                                 |
:0040A520 FF1538B04300            Call dword ptr [0043B038]
:0040A526 83F805                  cmp eax, 00000005    <<-----这是什么!!!5代表是光驱,3代表是硬盘,
:0040A529 7565                    jne 0040A590         <<-----不等于5就跳,关键的一跳,盘符检查,跳几次就玩完
:0040A52B 6A01                    push 00000001
:0040A52D FFD5                    call ebp
:0040A52F 8BF0                    mov esi, eax
:0040A531 6A00                    push 00000000
:0040A533 8D542418                lea edx, dword ptr [esp+18]
:0040A537 6A00                    push 00000000
:0040A539 8D442420                lea eax, dword ptr [esp+20]
:0040A53D 52                      push edx
:0040A53E 50                      push eax
:0040A53F 6A00                    push 00000000
:0040A541 8D4C2430                lea ecx, dword ptr [esp+30]
:0040A545 6A20                    push 00000020
:0040A547 8D542454                lea edx, dword ptr [esp+54]
:0040A54B 51                      push ecx
:0040A54C 52                      push edx
:0040A54D FFD3                    call ebx
:0040A54F 56                      push esi
:0040A550 8BF8                    mov edi, eax
:0040A552 FFD5                    call ebp
:0040A554 85FF                    test edi, edi
:0040A556 7438                    je 0040A590          <----关键的地方,卷标检查,跳几次就玩完! 此处以后会有用
:0040A558 8BB42490000000          mov esi, dword ptr [esp+00000090]
:0040A55F 8D44241C                lea eax, dword ptr [esp+1C]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A581(C)
|
:0040A563 8A10                    mov dl, byte ptr [eax]
:0040A565 8ACA                    mov cl, dl
:0040A567 3A16                    cmp dl, byte ptr [esi]
:0040A569 751C                    jne 0040A587
:0040A56B 84C9                    test cl, cl
:0040A56D 7414                    je 0040A583              <----关键的一跳,必须跳
:0040A56F 8A5001                  mov dl, byte ptr [eax+01]
:0040A572 8ACA                    mov cl, dl
:0040A574 3A5601                  cmp dl, byte ptr [esi+01]
:0040A577 750E                    jne 0040A587
:0040A579 83C002                  add eax, 00000002
:0040A57C 83C602                  add esi, 00000002
:0040A57F 84C9                    test cl, cl
:0040A581 75E0                    jne 0040A563

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A56D(C)
|
:0040A583 33C0                    xor eax, eax
:0040A585 EB05                    jmp 0040A58C              <----无条件跳,跳向游戏可以运行的地方!

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A569(C), :0040A577(C)
|
:0040A587 1BC0                    sbb eax, eax
:0040A589 83D8FF                  sbb eax, FFFFFFFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A585(U)
|
:0040A58C 85C0                    test eax, eax
:0040A58E 7436                    je 0040A5C6          <----关键的必须跳,跳向游戏可以运行的地方!

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A529(C), :0040A556(C)
:0040A590 8A44243C                mov al, byte ptr [esp+3C]     <<----关键的的地方!
:0040A594 FEC0                    inc al
:0040A596 8844243C                mov byte ptr [esp+3C], al
:0040A59A 8B442410                mov eax, dword ptr [esp+10]
:0040A59E 40                      inc eax
:0040A59F 83F818                  cmp eax, 00000018      <-----将对24个英文字母(盘符)清扫一遍
:0040A5A2 89442410                mov dword ptr [esp+10], eax
:0040A5A6 0F8C6FFFFFFF            jl 0040A51B            <----又跳回,再来!跳几次就玩完

* Possible StringData Ref from Data Obj ->"请插入《新剑侠情缘》的第一号光盘,再重新运行本"
                                       ->"程序。"
                                 |
:0040A5AC 689C0A4400              push 00440A9C

* Reference To: Sword.?g_MessageBox@@YAXPADZZ, Ord:0308h
                                 |
:0040A5B1 FF1558B14300            Call dword ptr [0043B158]
:0040A5B7 83C404                  add esp, 00000004
:0040A5BA 33C0                    xor eax, eax
:0040A5BC 5F                      pop edi
:0040A5BD 5E                      pop esi
:0040A5BE 5D                      pop ebp
:0040A5BF 5B                      pop ebx
:0040A5C0 83C47C                  add esp, 0000007C
:0040A5C3 C20400                  ret 0004



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A58E(C)
|
:0040A5C6 5F                      pop edi      <<----游戏可以运行的地方!
:0040A5C7 5E                      pop esi
:0040A5C8 5D                      pop ebp
:0040A5C9 B801000000              mov eax, 00000001
:0040A5CE 5B                      pop ebx
:0040A5CF 83C47C                  add esp, 0000007C
:0040A5D2 C20400                  ret 0004


:0040A5D5 90                      nop
:0040A5D6 90                      nop
:0040A5D7 90                      nop
:0040A5D8 90                      nop
:0040A5D9 90                      nop
:0040A5DA 90                      nop
:0040A5DB 90                      nop
:0040A5DC 90                      nop
:0040A5DD 90                      nop
:0040A5DE 90                      nop
:0040A5DF 90                      nop

* Referenced by a CALL at Address:
|:0040A449  
|
:0040A5E0 56                      push esi
:0040A5E1 57                      push edi
:0040A5E2 8BF9                    mov edi, ecx

    好了,让这个游戏不读光盘的方法有很多。
⑴ 把“0040A526  cmp eax, 00000005”改为“cmp eax, 00000003”,
  用UltraEdit打开NewSword.EXE文件,
    找到:83 F8 05 75 65
    改为:83 F8 03 75 65  存盘,搞定!
或:找到:83 F8 05 75 65
    改为:83 F8 05 74 65  存盘,搞定!
 再把C:盘的卷标改成《新剑侠情缘》第一张光盘的卷标,
这个游戏软件不需要读光盘上的某个文件,只要卷标检查通过就行。

⑵ 直接修改关键跳转指令,直接绕过卷标检查
 仔细观察,跳向“0040A5C6 ”,可以直接绕过卷标检查,游戏可以运行。
 改什么地方呢??
 这里,跳向“0040A590”的地方,共有两处
    :0040A529 7565                    jne 0040A590
  ②  :0040A556 7438                    je 0040A590
 把“0040A590”改为“0040A5C6”,用jumpgen算一下,①不行,②正好,运气!!!
改0040A556 7438                    je 0040A590
为0040A556 746E                    je 0040A5C6
用UltraEdit打开NewSword.EXE文件,
   找到:85 FF 74 38
   改为:85 FF 74 6E  存盘,搞定!,只需改一个字节就可以了。。。哈哈哈哈
不过,我有一疑问,只改以上跳转指令直接绕过卷标检查,就可以进入游戏,那么以下
  :0040A526 83F805                  cmp eax, 00000005    <<-----5代表是光驱,3代表是硬盘,
  :0040A529 7565                    jne 0040A590         <<-----不等于5就跳
又有何用?请高手赐教!

  后记
  我写这,是第一次,当然破解光盘游戏也是第一次,真诚感谢看雪及他的《论坛精华Ⅲ》和《加密与解密--软件保护技术与解决方案》一书,是他带我上路。其实论起来,我还是看雪(段钢)的师兄,而且我们曾同在一个校园待过(我1991年毕业于同济大学,他1994年),我很以有此师弟为荣。