<SPAN CLASS="pediy">Roadrush</SPAN>跨平台运行(2千字)
Roadrush是一款古老的摩托车赛车游戏。当我把os由win95升级到win2k简体中文版的时候,发现这个游戏不能运行了。启动时显示:0x77f88fc8引用0x00000000内存,该内存不能为read
看来是游戏不能在win2k上运行,这也不是什么奇怪的事,就没有深究下去。
前几天刚好在ollydb的官方网站上读了ollydb的trace教程,突发奇想,准备拿roadrush做个实验。
用ollydb装载roadrush,选择trace into,非常走运,没有定义任何代码块,仅仅耐心的等待1分钟(PIII 500),程序就来到了出错的地方,察看trace的结果,发现直接的原因是因为0042F43F处的call EBP,重新启动roadrush,在0042F43F处设断点,看到如下的代码
0042F410 /$ 83EC 08 SUB ESP,8
0042F413 |. 8D4424 00 LEA EAX,DWORD PTR SS:[ESP]
0042F417 |. 53 PUSH EBX
0042F418 |. 55 PUSH EBP
0042F419 |. 6A 07 PUSH 7 ; /BufSize = 7
0042F41B |. 50 PUSH EAX ; |Buffer
0042F41C |. 6A 03 PUSH 3 ; |InfoType = 3
0042F41E |. 51 PUSH ECX ; |LocaleId
0042F41F |. FF15 60A64C00 CALL DWORD PTR DS:[<&KERNEL32.GetLocaleI>; \GetLocaleInfoA
0042F425 |. 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8]
0042F429 |. 68 D4C34600 PUSH Roadrash.0046C3D4 ; ASCII ".dll"
0042F42E |. B9 CCC34600 MOV ECX,Roadrash.0046C3CC ; ASCII "Text/"
0042F433 |. E8 483F0100 CALL Roadrash.00443380
0042F438 |. 50 PUSH EAX ; /FileName
0042F439 |. 8B2D 64A64C00 MOV EBP,DWORD PTR DS:[<&KERNEL32.LoadLib>; |shim.78144662
0042F43F |. FFD5 CALL EBP ; \LoadLibraryA
0042F441 |. 5D POP EBP
0042F442 |. 5B POP EBX
0042F443 |. 83C4 08 ADD ESP,8
0042F446 \. C3 RETN
跟踪发现,0042f438处的eax为0,用空指针调用loadlibrarya,难怪会出错!
熟悉windows编程的程序员其实很容易猜出这段代码的用意,调用GetLocaleInfoA,取得locale信息,根据默认的语言,装载相应的资源dll,在我的系统中,0042F425处的代码之行后,edx指向的字符串为"CHS",即简体中文,但./text/目录下,不存在chs.dll这个动态连接库,所以
0042F433处的call返回值为0,但不知道哪个粗心的程序员不检查返回值,就调用loadlibrary,导致上面所说的错误。
修改的方法就容易了,可以有很多种改法,我用了最懒惰的一种,把enu.dll拷贝成chs.dll。
