Friday, May 23, 2008

It's a real pleasure to be able to be able to return to proper disassembly work after the interval I had to spend writing the delinker tool. Subjectively, I know that writing the tool was a necessary step that would save me issues in the long run, but it was still annoying to have to write and then spend all the time fiddling with it to get it work, particularly since I'd never really bothered to look at the structure of executables, and was learning from scratch.

Getting stuck into Rex Nebular, I've started debugging it using the DOSBOX debugger. I was a bit unsure about using it at first, but it's turned out to be an excellent tool. Back when I was disassembling Lure of the Temptress, I made do with DEBUG, which wasn't bad, but obviously had issues with trying to debug graphics programs.. I'd actually had to hack the game executable to stop it setting graphics mode so that I could use DEBUG to trace through all the startup code. Now with DOSBOX, I can trace anywhere in the program, since the debugger itself is in a separate window, which is wonderful.

About the only real annoyance remaining is the RTLink library itself. Although I do have a full disassembly based on a processed executable, I still need to do my debugging on the original executable (if the game worked without the extra space it provides, they wouldn't have needed it in the first place). The issue is that due to the way RTLink works, a call through a proxy stub can actually unload the calling code, which then gets reloaded when the called function exits.. but not necessarily in the same place.

Which means that you might try stepping over a function call, and suddenly the entire game sequence will play out, because the location returned to after the function call may now be at another segment address. Confused me at first, until I happened to trace out of a method and realised what was happening. :)

Wednesday, May 14, 2008

My first posting

Welcome, everyone, to my new blog. I figured that since blogs have been becoming popular in the ScummVM community lately, I might as well start my own as well. My interests lie in disassembling and reverse engineering old adventure games, and then re-implementing them in ScummVM.

For this inaugural blog post, I'd like to talk about one of my latest projects - working on the MADS/M4 engine. I'm concentrating mainly on the MADS side of the engine at the moment, which was the game engine used for the three games - Rex Nebular, Dragonsphere, or Return of the Phantom, what the current status is of the engine.

I've been concentrating primarily on disassembling Rex Nebular - the game itself is split into a series of executables to save space:
  • mainmenu.exe - Which contains the logic for the main menu
  • animview.exe - Which contains the logic for displaying cutscenes, like the intro and ending animations
  • textview.exe - Which contains the logic for displaying scrolling text, as in the credits and quotes.
  • nebular.exe - The actual game itself.
So far, I've spent time disassembling the various executables, excluding the game executable, which I'll get onto in a moment, and along with work done by MD5 and others, we've got the main menus showing for Rex Nebular and Dragonsphere, as well as the scrolling credits and partial support for the cut-scene animations.

The next big step now was to start disassembling the main game executables to figure out all the in-game logic. This was when I'd hit a big stumbling block.. In order to properly understand a game, you have to be able to disassemble it in a dissassembler in it's entirety, so you can start identifying methods and variables, and gradually build up an understanding of how the game works. In the case of the actual game executable, though, all three games had been compiled with an overlay manager called RTLink/Plus, which was designed to save memory by swapping parts of the program code in and out of memory on the fly at runtime.

This therefore made the game difficult to disassemble, because:
1) The functions calls and jumps between code in different segments went via an intermediate table which was dynamically filled in at runtime
2) The data segment was in the middle of the program - this posed a problem because programs typically have the data segment at the end of the program, to allow for uninitialised data areas - space for variables which don't have an explicit value set at startup, so don't need to be part of the executable image.

As such, I was forced to write a program, which I've named rtlink_decode to handle these executables. I'm really quite proud of it - it takes in an executable, and presuming that it detects that is was compled with RTLink/Plus, creates a new executable with the following changes:
1) It detects all the dynamic segments and adds in relocation entries to the executable so that all segment references within these segments are treated like normal code segments
2) Processes the table used for inter-segment calls to fix them to go to the correct segment (what RTLink would have done dynamically at runtime wherever it loaded a segment)
3) Shifts the data segment to the end of the executable, and adjusts any data segment references in the executable to point to the new position.

The result is a new executable which was able to be fully disassembled by IDA Free - which I strongly recommend as a wonderful disassembler for anyone who's thinking about experimenting with reverse engineering.

Now that I've got a clean complete disassembly to work with, I can start figuring out the game logic. This time, though, I won't be starting from scratch - there is shared code between the game executables and the menu, credits, and animation executables, so I've already been able to identify a lot of runtime library methods, as well as other MADS methods I'd previously already figured out.

Nevertheless, it's likely still going to be a while before there's enough disassembled that any major functionality can be implemented into ScummVM, so you'll need to be patient.