An Evening With Assembly
Back when I was young child, my brothers and I used to play a game called Moonstone. So it was with a bit of nostalgic glee that I went about spending a few hours or so in evening poking around the innards of the game. I wish I had bothered to take a look at the time, as I managed to remove the cool, but unbelievably long, unskippable intro that the game has, which would of saved my brothers and I a few hours of pain, enduring the intro whilst waiting for the game to start.
You can find the game itself on various abandonware sites and it runs fine in DOSBox. The game comes with three executables, MS.EXE (the executable to play the game), INTR.EXE (the executable that runs the intro sequence) and MAIN.EXE (the main game itself). DOSBox has a debugger build that allows you to examine memory, step through execution, set breakpoints and more. There's a guide to help you along.
The freeware version of IDA, thankfully supports dos exes, so I could open up all three to have a poke around.
IDA will attempt to identify all the subroutines and possible strings in the exe. Armed with this and the DOSBox debugger, I went through the assembly and spent the next few hours figuring out and labelling all the subroutines, which you should be able to see a few of in the “Names” list in the screenshot. It was once everything was labelled and much easier to read that it occurred to me that it would be a good idea to get rid of the intro.
For the most part, MS.EXE will do a bit of checking to see if there is enough memory, checking the dos version is compatible and setting up the graphics to mode 13h. After this it'll launch INTR.EXE followed by MAIN.EXE, hopefully you can see this in the screen shot, for example, runIntroAndMain
will load 0x00be
into the dx register before calling executeBinary
. You'll notice that 0x0be
corresponds to the “MAIN.EXE” string in the strings window. Also notice that in runIntroAndMain
, it'll load 0x00b5
(the INTR.EXE) string, followed by a series of nop instructions. This is where I had replaced the call to executeBinary
with a nop slide, thus saving my future self the pain of the intro ever again.
I took a look at INTR.EXE, just out of interest and IDA gave me a warning that it might be packed. For my purposes, I'm not interested in the figuring out how to decompress the data myself, but in the hexedit view there were a couple of strings that might indicate how it had been compressed. With a bit of searching, the “Packed file is corrupt” message, led me to this page informing me it had been packed with EXEPACK. A bit more searching led me to an old UNPACK.EXE that would unpack the fille, I ran this in DOSBox on INTR.EXE and could now analyze it in IDA. I really didn't want to do any unnecessary work if I didn't have to. After, firing up the modified MS.EXE to make sure it worked, I had a quick play for a bit of nostalgia (I think I got more satisfaction from getting rid of the intro than playing the game) before deciding to call it a day and go for some tea.
Next time I take a look at this, I'll take a deeper look at MAIN.EXE and perhaps examine the other file formats.