Join the discord

Command & Conquer - map corner bugfix

24 Mar, 2013 20:26
Pushed by nostalgia, I've wanted to play some of the Command & Conquer game series. Through the years, I've played Red Alert 2 and its expansion pack - Yuri's revenge, probably more than ten times, so this time I decided to start from the very beginning, with the first of the C&C series, released back in 1995.

The game was originally developed for MS-DOS, but a year later the Westwood, re-released it for Windows 95.

In 2006 Electronic Arts (that in 1998 acquired Westwood) released a game pack, containing all of the C&C based games, released between 1995 and 2006, called "Command & Conquer: The First Decade". Even better, the package also includes all of the expansion packs, so technically we have six games, plus six expansion packs, or 12 games in total (yes, back then, expansion packs were technically a whole game, not like the DLC packs today).

So enough story tellings.
When i started the game and played a few missions, I've stumble upon a very annoying situation. On some maps, when i tried to uncover the fog of war in the left top corner, the games just freezes. It actually gives an error message, but since the main window is on top, the message box can only be seen if you ALT-TAB it.

This message is:

which most of the time means exactly what it says - the program is trying to access part of the memory which is not accessible or even not existing, due to bad code or problem with other application, sharing the same memory space.

So, i load the game in OllyDbg, and set a breakpoint at address 00432421, here:


There's a TEST instruction over EAX, used as memory address, and EBX as offset to that address.

I've run the game, and send my unit to the upper left corner of the map, to clear the fog, then suddenly olly breaks here...



Wait, what?
That's the bad address, but lets get more clear.
EAX holds the address 048C0030, which in this case is a base address (of probably the fog matrix of the map), and it looks fine:

EBX is the offset, but it contains a negative value 0xFFFFF9F1!

From previously running the game, i saw that EBX always hold small values between 0x700 and 0x2000.

I didn't want to get deeper into the game's guts, since my goal was to fix this as fast as I can, then continue pwning the bad guy's army. So, the best solution i thought was to check EBX, and if it holds a negative value, I'll pass it through NEG instruction, to turn it into positive.

There's obviously not enough place for my TEST, JS and NEG instruction here, so I'll have to make a small code cave somewhere.
For the sake of the test, i chose this place to be at the end of the code, where there's plenty of empty bytes, like here:


So, first of all, I'll redirect the bad code there, by placing a JMP in place of the MOV at 0043241F:


Then, at 004E79CF i will first make the EBX check, then place the MOV and TEST code that was replaced by the redirect JMP, and finally set another jump, that will return to the next line after the redirect JMP:


Time to test the changes!

WOO-HOO!
The game is working now. The changes so far were made on runtime, directly in OllyDbg, so next time i run the game that nasty bug will be back. That's why I've code a little patch, that you can download from the gametools section of the site.

Comments

* You have an opinion? Let us all hear it!

Guest 27 Aug, 2013 20:46
Thanks a lot! I owe you a beer!
© nullsecurity.org 2011-2024 | legal | terms & rules | contacts