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。