游戏吧+ 关注 关注:2 帖子:338

  

如何制作免CD补丁?免CD补丁制作攻略

  • 枫之精英

    制作免CD补丁,需要汇编知识和加密算法的知识,Softice、Trw等工具的使用

    理论上是把从CD读取映象更改到硬盘里

    一般作免cd补丁,都要改游戏在硬盘上的主程序。
    大约是要拦截GetDriveTypeA或者FindFirstFlieA之类的API。然后找出程序以什么为依据,认为光碟在光驱里。

    当然也有简单的解决方法,一般比较傻的游戏作者,怕判断不出游戏光碟到底是哪个盘符,会在硬盘上标记光碟的路径。

    一般在注册表相关键值下,或者在游戏安装目录里。然后,只要拷贝对应文件到硬盘,再改标记就可以了。

    而且,如果这样,也不必拷贝所有文件,你开着filemon,设置好过滤条件,运行游戏,玩一下,再退出。你就能从filemon的日志中看出哪些文件是需要的,剩下的可能只是安装文件或者摆设。

    制作纯EXE的免CD补丁的话,首先,你要反编译程序,用C++最好啦,找出与读取CD的一些关键代码,然后顺藤摸瓜的找出一些与读取CD的相关文件,接着你要看一下有没有一些反跟踪代码,你就都改了,最后就是测试

    免CD补丁制作实例
    首先,拿一款叫做《抗日:血战上海滩》的游戏做示例

    这款游戏需要插游戏光盘才可以玩。那么,我们准备对其进行破解

    先用PEid看看有没有加壳:
    "Microsoft Visual C++ 6.0 [Debug]"
    很好,没有加那些猛壳,可以直接调试了.打开Ollydbg--伟大的Win32调试器(我的是:ODbyDYK v1.10 汉化修改版),下断点:
    "bpx GetDriveType"
    这是个kernel32.dll的导出函数,作用是判断分区的类型,是硬盘,是软盘,还是光盘等等.然后按下F9让程序运行吧,马上就断在调用的地方,下面贴出代码:
    0040619E |. 894424 14 mov dword ptr ss:[esp+14],eax
    004061A2 |. 33FF xor edi,edi
    004061A4 |> 856C24 14 /test dword ptr ss:[esp+14],ebp ;可以看到,从这里到004061F4不断的循环,是为了枚举各个分区
    004061A8 |. 74 42 |je short shanghai.004061EC
    004061AA |. 0FBECB |movsx ecx,bl
    004061AD |. 33C0 |xor eax,eax
    004061AF |. 51 |push ecx ; /<%c>
    004061B0 |. 8D5424 14 |lea edx,dword ptr ss:[esp+14] ; |
    004061B4 |. 66:894424 14 |mov word ptr ss:[esp+14],ax ; |
    004061B9 |. 68 8C7E5B00 |push shanghai.005B7E8C ; |format = "%c:"
    004061BE |. 52 |push edx ; |s
    004061BF |. 884424 1E |mov byte ptr ss:[esp+1E],al ; |
    004061C3 |. FF15 C0B25800 |call dword ptr ds:[<&MSVCRT.sprintf>] ; \sprintf
    004061C9 |. 83C4 0C |add esp,0C
    004061CC |. 8D4424 10 |lea eax,dword ptr ss:[esp+10]
    004061D0 |. 50 |push eax ; /RootPathName,GetDriveType函数的参数是一个指向字符串的指针,为盘的根目录名
    004061D1 |. FF15 4CB15800 |call dword ptr ds:[<&KERNEL32.GetDriveT>; \GetDriveTypeA,看,这个call就调用了GetDriveType函数
    004061D7 |. 83F8 05 |cmp eax,5
    004061DA |. 75 10 |jnz short shanghai.004061EC
    004061DC |. 8B4C24 1C |mov ecx,dword ptr ss:[esp+1C]
    004061E0 |. 8B4424 20 |mov eax,dword ptr ss:[esp+20]
    004061E4 |. 881C0E |mov byte ptr ds:[esi+ecx],bl
    004061E7 |. 46 |inc esi
    004061E8 |. 3BF0 |cmp esi,eax
    004061EA |. 7D 0A |jge short shanghai.004061F6
    004061EC |> D1E5 |shl ebp,1
    004061EE |. FEC3 |inc bl
    004061F0 |. 47 |inc edi
    004061F1 |. 83FF 20 |cmp edi,20
    004061F4 |.^ 72 AE \jb short shanghai.004061A4
    004061F6 |> 8BC6 mov eax,esi ;循环很麻烦的,于是在出循环后--就是这个地方按下F2下断点,
    004061F8 |. 5F pop edi ;然后取消004061D1处的断点,它再运行一出循环就会断在这里了.
    004061F9 |. 5E pop esi
    004061FA |. 5D pop ebp
    004061FB |. 5B pop ebx
    004061FC |. 83C4 08 add esp,8
    004061FF \. C3 retn

    循环很麻烦的,于是在出循环后--就是004061F6这个地方按下F2下断点,然后取消004061D1处的断点,它再运行一出循环就会断在004061F6了.继续F8跟踪,离开这个call,来到这儿:
    0040622E |> \8B8C24 40010000 mov ecx,dword ptr ss:[esp+140]
    00406235 |. 85C9 test ecx,ecx
    00406237 |. 7F 0B jg short shanghai.00406244
    00406239 |. C78424 40010000 800000>mov dword ptr ss:[esp+140],80
    00406244 |> 8B8C24 40010000 mov ecx,dword ptr ss:[esp+140]
    0040624B |. C74424 10 00000000 mov dword ptr ss:[esp+10],0
    00406253 |. 85C9 test ecx,ecx
    00406255 |. 7E 76 jle short shanghai.004062CD
    00406257 |. 8BBC24 44010000 mov edi,dword ptr ss:[esp+144]
    0040625E |. 8B2D C0B25800 mov ebp,dword ptr ds:[<&MSVCRT.sprintf>] ; MSVCRT.sprintf
    00406264 |. EB 04 jmp short shanghai.0040626A
    00406266 |> 8B4424 14 /mov eax,dword ptr ss:[esp+14]
    0040626A |> 833F 00 cmp dword ptr ds:[edi],0
    0040626D |. 74 5E |je short shanghai.004062CD
    0040626F |. 32DB |xor bl,bl
    00406271 |. 33F6 |xor esi,esi
    00406273 |. 85C0 |test eax,eax
    00406275 |.^ 7E AA |jle short shanghai.00406221
    00406277 |> 84DB |/test bl,bl
    00406279 |. 75 3B ||jnz short shanghai.004062B6
    0040627B |. 0FBE5434 18 ||movsx edx,byte ptr ss:[esp+esi+18]
    00406280 |. 8B0F ||mov ecx,dword ptr ds:[edi]
    00406282 |. 8D4424 38 ||lea eax,dword ptr ss:[esp+38]
    00406286 |. 51 ||push ecx
    00406287 |. 52 ||push edx
    00406288 |. 68 907E5B00 ||push shanghai.005B7E90 ; ASCII "%c:/%s"
    0040628D |. 50 ||push eax
    0040628E |. FFD5 ||call ebp
    00406290 |. 8D4C24 48 ||lea ecx,dword ptr ss:[esp+48]
    00406294 |. 6A 00 ||push 0
    00406296 |. 51 ||push ecx
    00406297 |. E8 84FEFFFF ||call shanghai.00406120
    0040629C |. 83C4 18 ||add esp,18
    0040629F |. 84C0 ||test al,al
    004062A1 74 02 je short shanghai.004062A5
    004062A3 |. B3 01 ||mov bl,1
    004062A5 |> 8B4424 14 ||mov eax,dword ptr ss:[esp+14]
    004062A9 |. 46 ||inc esi
    004062AA |. 3BF0 ||cmp esi,eax
    004062AC |.^ 7C C9 |\jl short shanghai.00406277
    004062AE |. 84DB |test bl,bl
    004062B0 |.^ 0F84 6BFFFFFF |je shanghai.00406221
    004062B6 |> 8B4424 10 |mov eax,dword ptr ss:[esp+10]
    004062BA |. 8B8C24 40010000 |mov ecx,dword ptr ss:[esp+140]
    004062C1 |. 40 |inc eax
    004062C2 |. 83C7 04 |add edi,4
    004062C5 |. 3BC1 |cmp eax,ecx
    004062C7 |. 894424 10 |mov dword ptr ss:[esp+10],eax
    004062CB |.^ 7C 99 \jl short shanghai.00406266
    004062CD |> 5F pop edi
    004062CE |. 5E pop esi
    004062CF |. 5D pop ebp
    004062D0 |. B0 01 mov al,1
    004062D2 |. 5B pop ebx
    004062D3 |. 81C4 2C010000 add esp,12C
    004062D9 \. C3 retn

    在,我们可以在堆栈中看到,这个游戏要判断光盘根目录下是否有"AutoRun.exe"这个文件,看见
    00406297 |. E8 84FEFFFF ||call shanghai.00406120
    吗?很像关键Call哦,F7跟进去看看:
    00406120 /$ 8B4424 04 mov eax,dword ptr ss:[esp+4]
    00406124 |. 6A 00 push 0 ; /amode = 0
    00406126 |. 50 push eax ; |path
    00406127 |. FF15 D4B15800 call dword ptr ds:[<&MSVCRT._access>] ; \_access
    0040612D |. 83C4 08 add esp,8
    00406130 83F8 FF cmp eax,-1
    00406133 |. 0F95C0 setne al
    00406136 \. C3 retn

    cmp eax,-1这句好像是比较是否错误呢,我们把-1改成0试试,然后保存文件,恢复成原状,继续跟踪,从这个call出来,回到:
    00406297 |. E8 84FEFFFF ||call shanghai.00406120
    0040629C |. 83C4 18 ||add esp,18
    0040629F |. 84C0 ||test al,al
    004062A1 74 02 je short shanghai.004062A5 ;主意!关键跳
    004062A3 |. B3 01 ||mov bl,1
    004062A5 |> 8B4424 14 ||mov eax,dword ptr ss:[esp+14]
    004062A9 |. 46 ||inc esi
    004062AA |. 3BF0 ||cmp esi,eax
    004062AC |.^ 7C C9 |\jl short shanghai.00406277
    004062AE |. 84DB |test bl,bl
    004062B0 |.^ 0F84 6BFFFFFF |je shanghai.00406221
    004062B6 |> 8B4424 10 |mov eax,dword ptr ss:[esp+10]
    004062BA |. 8B8C24 40010000 |mov ecx,dword ptr ss:[esp+140]
    004062C1 |. 40 |inc eax
    004062C2 |. 83C7 04 |add edi,4
    004062C5 |. 3BC1 |cmp eax,ecx
    004062C7 |. 894424 10 |mov dword ptr ss:[esp+10],eax
    004062CB |.^ 7C 99 \jl short shanghai.00406266
    004062CD |> 5F pop edi
    004062CE |. 5E pop esi
    004062CF |. 5D pop ebp
    004062D0 |. B0 01 mov al,1
    004062D2 |. 5B pop ebx
    004062D3 |. 81C4 2C010000 add esp,12C
    004062D9 \. C3 retn
    大家会发现,je short shanghai.004062A5,这就是关键跳转,如果跳转了,接着的mov bl,1这句就不能执行了,而mov bl,1这句就是把关键标识置位的!把je short shanghai.004062A5 改成je short shanghai.004062A3,让他直接跳到下一条指令。然后保存文件,运行成功!没有要求插入CD了。


    1楼  2017/8/9 15:17:23  回复

  发表回复

    发帖