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.

4 comments:

angrylion said...

How about publishing this rtlink_decode tool? It would help me immensely if I ever decide to continue my work on disassembling Sid Meier's Colonization.

Dreammaster said...

Sure. it's now available as part of the new RogueVM fork of ScummVM for RPGs: See https://github.com/roguevm/roguevm-tools.git. There are two versions; the older "MADS" version that the blog post refers to, and a new one I'm just now currently working on for the Legend Entertainment games.

angrylion said...

Wow, you even took time to write some helpful notes for me. Thanks muchly!

Dreammaster said...

You're welcome :)