如何制作免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了。