Thursday, June 19, 2014

Cross-Platform Classic Game Hacking

 

Introduction

Quite a bit of work these days goes into compatibility with legacy programs. In the area of reverse-engineering, few things are more fun than being able to hack up a game and make it do something valuable (like run properly on a modern system). Many games in the past were based on principles that no longer apply (almost standardization of CDDA and optical drives in systems, non floating paths, etc.) Today, we're going to dive into hacking up an old game (Croc2) and make it run on a modern machine complete with CDDA audio without mounting bin/cues or any of that shit - we're going to hack up the binary and modernize the shit out of this; let's get going.

Analysis
 
 We have what looks like an old-school installer after mounting the iso. Installing the game gives us this:





Ok, nothing really interesting here - the installer just puts a copy of the game binary onto the hdd (pretty common). Running it without the disc mounted will probably...







Yup... time to throw it in IDA.

The first place we want to look at is the imports table if it doesn't need reconstructing:

 
These Reg imports are a telltale sign that this game reads/writes registry entries... let's go to the registry to make sure nothing critical is listed in there:
 


Nope - Just the install path which we won't need because the goal is to make it run from anywhere.



alright - NOW we're in business... this guy used to be used a lot on cd checks to find the cdrom drive letter (assuming everyone had only one cdrom or the first optical/removable drive they had was their primary cdrom drive) - this is the one where we'll have to fuck up some logic I bet..
 
Enum 5 is normally REMOVABLE or CDROM. This basically goes through all the letters to find the first CDROM drive from C->Z and  call that our root device for the game. Normally, this is where other logic would come into play, but Croc 2 actually isn't even THAT difficult.





After the drive check, we see it calling access - running the binary will show that it's checking if it can open DEFANIM.WAD from the current directory. The game basically has a short-circuit that says:

if(can_open(CDIR->WADS->DEFANIM.WAD)):
   run_from_cd = True

horrible pseudo-code, but the point is that the game will skip any other check and assume the current dir is where it will find everything (even the music which is in digital format - saves us from CDDA hacking here)).

Copy the files from the cd to any dir:




It even runs perfectly in Wine.



WELL WTF - THAT WASN'T ANY FUN :(

You know what? No - we're gonna do a decent one...


Ok - THIS ONE... this one has CDDA, was a nightmare to even get working back then, and so many people had problems with this one. Most people have played the N64 version of this game, but what's interesting is that the N64 version is actually a butchered port of the PC version (the PC version has cutscenes instead of the comic-strip narrative, voice acted audio sequences for all the text ingame, and a musical score).  Also, the resolution can be bumped up so it even LOOKS better. 

The real SHADOW here is the fact that the N64 hype train shadowed the better PC version.

The bin/cue content looks like this:
Standard setup - binary+data+CDDA on the second session.
Running the setup program gives us:


typical.


Might as well dump the audio tracks (I used UltraISO - you can use whatever... make sure you dump them to ogg unlike the image).

As an unrelated side-note, checking the resources from the autorun program will show how in a hurry they were to get this out the door (copypasta alert)

 

Apart from that , the REAL binary we care about is SHADOWS.EXE in the SDATA directory - we actually only need the SDATA directory... everything else is just redundant setup crap.

Running the binary gives us:


Ok - typical... probably a GetDriveTypeA thing again.

 

Yup - checks for a CDROM, then checks if the volume name is SHADOWS
Changing the conditional from jnz to jmp (0xeb) in the second image will get us where we wanna be.


Ok making headway - annnnd CRASHES

Oh! The registry!

 Looking at the entries we normally add on installation:
"SData Path"
"Video Path"
are the two most important as the game uses these... although we COULD make the functions in the binary return ./, I'll just make a reg file that will set all those to relative paths:
 [HKEY_LOCAL_MACHINE\SOFTWARE\LucasArts Entertainment Company\Shadows of the Empire]
"Install Path"=".\\"
"SData Path"=".\\"
"Video Path"=".\\"
"Source Dir"=".\\"
"Fog"="TRUE"
"Force Alpha"="FALSE"
"Display Device"="Primary Display Driver"
"3D Device"="Microsoft Direct3D Hardware acceleration through Direct3D HAL"
"Width"="1024"
"Height"="768"
"Game Pad"="FALSE"
"Direct Movie"="TRUE"
"CD Audio"="TRUE"
"Cutscene Text"="FALSE"
"Executable"=".\\Shadows.exe"
"Numb Hand"="FALSE"
Works!