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.
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:
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.
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.
Wow, you even took time to write some helpful notes for me. Thanks muchly!
You're welcome :)
Post a Comment