最近怀旧玩老游戏《天地劫-神魔至尊传》
游戏资源和介绍:http://www.verycd.com/topics/2725382/
发现原有的patch.com是win9x时代的免CD补丁,使用的大概是subst挂载的方法虚拟CD。
在WinXP SP3 上已经不能正常无CD启动了。
作为初学OD的新手抱着试一试的心态,决定自己去掉游戏的CD启动。
1启动游戏
立刻弹出消息框“Please insert game cd 2 into drive G:\” G:\是我的光驱
2用OD加载游戏,查找“Please insert game cd 2 into drive”字串
找到字串“Please insert game cd 2 into drive %s.”
3定位引用“Please insert game cd 2 into drive %s.”的代码,将整个函数进行分析:
该函数应该是设定读取光盘部分资料路径的函数。
004129D0 /$ 81EC E4000000 sub esp, 0E4
004129D6 |. 53 push ebx
004129D7 |. 55 push ebp
004129D8 |. 56 push esi
004129D9 |. 57 push edi
函数进入
004129DA |. 8B3D 34B04500 mov edi, dword ptr [<&KERNEL32.GetDr>; kernel32.GetDriveTypeA
004129E0 |. 8BD9 mov ebx, ecx
004129E2 |. 33F6 xor esi, esi
004129E4 |> 8D46 43 /lea eax, dword ptr [esi+43]
004129E7 |. 8D4C24 10 |lea ecx, dword ptr [esp+10]
004129EB |. 50 |push eax
004129EC |. 68 98834600 |push 00468398 ; %c:\
004129F1 |. 51 |push ecx
004129F2 |. E8 69E50300 |call 00450F60
004129F7 |. 83C4 0C |add esp, 0C
004129FA |. 8D5424 10 |lea edx, dword ptr [esp+10]
004129FE |. 52 |push edx
004129FF |. FFD7 |call edi
00412A01 83F8 05 cmp eax, 5
00412A04 |. 74 27 |je short 00412A2D
00412A06 |. 46 |inc esi
00412A07 |. 83FE 17 |cmp esi, 17
00412A0A |.^ 7C D8 \jl short 004129E4
从C:\开始,枚举形如X:\模式的盘符
并找到第一个GetDriveTypeA返回为光驱属性(eax=5)的驱动器
00412A0C |> 8B03 mov eax, dword ptr [ebx]
00412A0E |. 8D53 04 lea edx, dword ptr [ebx+4]
00412A11 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00412A13 52 push edx ; |Title
00412A14 68 7C834600 push 0046837C ; |can't find any cdrom drive.
00412A19 50 push eax ; |hOwner
00412A1A FF15 1CB14500 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
00412A20 |. 5F pop edi
00412A21 |. 5E pop esi
00412A22 |. 5D pop ebp
00412A23 |. 32C0 xor al, al
00412A25 |. 5B pop ebx
00412A26 |. 81C4 E4000000 add esp, 0E4
00412A2C |. C3 retn
00412A2D |> 83FE 17 cmp esi, 17
00412A30 |.^ 7D DA jge short 00412A0C
如果找到Z:\还没找到光驱
弹出消息框"can't find any cdrom drive.",错误返回。
00412A32 |. 8D4424 10 lea eax, dword ptr [esp+10]
00412A36 |. 8D4C24 60 lea ecx, dword ptr [esp+60]
00412A3A |. 50 push eax
00412A3B |. 68 54834600 push 00468354 ; please insert game cd 2 into drive %s.
00412A40 |. 51 push ecx
00412A41 |. E8 1AE50300 call 00450F60
00412A46 |. 8B35 1CB14500 mov esi, dword ptr [<&USER32.Message>; USER32.MessageBoxA
00412A4C |. 8B2D 2CB04500 mov ebp, dword ptr [<&KERNEL32.GetVo>; kernel32.GetVolumeInformationA
00412A52 |. 83C4 0C add esp, 0C
00412A55 |. 8D7B 04 lea edi, dword ptr [ebx+4]
设定函数入口和字符串地址到寄存器。
00412A58 |> 8B03 /mov eax, dword ptr [ebx]
00412A5A 6A 21 |push 21
00412A5C 8D5424 64 |lea edx, dword ptr [esp+64]
00412A60 57 |push edi
00412A61 52 |push edx
00412A62 50 |push eax
00412A63 FFD6 |call esi
弹出消息框"please insert game cd 2 into drive X:\."
00412A65 83F8 01 cmp eax, 1
00412A68 |. 75 79 |jnz short 00412AE3
用户取消信息框,错误返回。
00412A6A |. 8D8C24 B40000>|lea ecx, dword ptr [esp+B4]
00412A71 |. 6A 40 |push 40
00412A73 |. 8D5424 20 |lea edx, dword ptr [esp+20]
00412A77 |. 51 |push ecx
00412A78 |. 8D4424 20 |lea eax, dword ptr [esp+20]
00412A7C |. 52 |push edx
00412A7D |. 8D4C24 20 |lea ecx, dword ptr [esp+20]
00412A81 |. 50 |push eax
00412A82 |. 51 |push ecx
00412A83 |. 8D5424 34 |lea edx, dword ptr [esp+34]
00412A87 |. 6A 40 |push 40
00412A89 |. 8D4424 28 |lea eax, dword ptr [esp+28]
00412A8D |. 52 |push edx
00412A8E |. 50 |push eax
00412A8F |. FFD5 |call ebp
00412A91 |. 85C0 |test eax, eax
00412A93 |.^ 74 C3 |je short 00412A58
利用GetVolumeInformationA判断光驱确实插入了盘片
否则重新提示
00412A95 |. 8D4C24 20 |lea ecx, dword ptr [esp+20]
00412A99 |. 68 48834600 |push 00468348 ; swordman_2
00412A9E |. 51 |push ecx
00412A9F |. E8 8C6A0400 |call 00459530
00412AA4 |. 83C4 08 |add esp, 8
00412AA7 |. 85C0 |test eax, eax
00412AA9 |.^ 75 AD \jnz short 00412A58
并且盘片的卷标为swordman_2
否则重新提示
00412AAB |. 8B13 mov edx, dword ptr [ebx]
00412AAD 6A 30 push 30
00412AAF 57 push edi
00412AB0 68 00834600 push 00468300 ; please notice!!!\ndon't eject game cd when playing,\nor error will occur
00412AB5 52 push edx
00412AB6 FFD6 call esi
弹出消息框:
"please notice!!!
don't eject game cd when playing,
or error will occur"
00412AB8 |. 8D4424 10 lea eax, dword ptr [esp+10]
00412ABC |. 68 F4824600 push 004682F4 ; swordman\
00412AC1 |. 50 push eax
00412AC2 |. 81C3 5C020000 add ebx, 25C
00412AC8 68 F1824600 push 004682EC ; %s%s
00412ACD |. 53 push ebx
00412ACE |. E8 8DE40300 call 00450F60
由于程序老旧OD没有显示使用的C库。
猜测是利用sprintf(路径字串,"%s%s","X:\","swordman\")合并字串。
00412AD3 |. 83C4 10 add esp, 10
平衡堆栈
00412AD6 |. B0 01 mov al, 1
00412AD8 |. 5F pop edi
00412AD9 |. 5E pop esi
00412ADA |. 5D pop ebp
00412ADB |. 5B pop ebx
00412ADC |. 81C4 E4000000 add esp, 0E4
00412AE2 |. C3 retn
正常返回
00412AE3 |> 8B0B mov ecx, dword ptr [ebx]
00412AE5 |. 6A 10 push 10
00412AE7 |. 57 push edi
00412AE8 |. 68 D4824600 push 004682D4 ; can't access game cd 2.
00412AED |. 51 push ecx
00412AEE |. FFD6 call esi
弹出消息框"can't access game cd 2."
00412AF0 |. 5F pop edi
00412AF1 |. 5E pop esi
00412AF2 |. 5D pop ebp
00412AF3 |. 32C0 xor al, al
00412AF5 |. 5B pop ebx
00412AF6 |. 81C4 E4000000 add esp, 0E4
00412AFC \. C3 retn
错误返回
4修改
首先想到跳过繁琐的光驱检查,直接改变字串“%s%s”为".\"
跳过光驱检查:直接跳过
from:
004129E4 |> 8D46 43 /lea eax, dword ptr [esi+43]
004129E7 |. 8D4C24 10 |lea ecx, dword ptr [esp+10]
to:
004129E4 /E9 CF000000 jmp 00412AB8
004129E9 |90 nop
004129EA |90 nop
改变字串“%s%s”为".\"时出现了问题,程序错误退出。如图:
经过跟踪发现,其他地方合并字串时也使用了这个“%s%s”作为模式串。
所以采取添加一个新的字串".\"在00412AC8处使用,修改如下:
在数据段空地添加字串".\":
from:
004682EC 25 73 25 73 00 00 00 00 %s%s....
to:
004682EC 25 73 25 73 00 2E 5C 00 %s%s..\.
修改成使用".\"字串合并:
from:
00412AC8 68 F1824600 push 004682EC ; %s%s
to:
00412AC8 68 F1824600 push 004682F1 ; .\
5将光盘上swordman\目录下内容拷贝到游戏安装目录
成功在不放入光盘的情况下运行程序。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: