Adventures into Reverse Engineering

Taking Apart Legacy of Kain: Soul Reaver

So, I recently got into speed-running, and when I did, I decided to advertise myself as being relatively competent at taking apart programs, and figuring out how they work. Within a day, I was given this reply

Reply I got

This message was from one of the primary community members of this game, and of course, I rose to the challenge.

So, I did a bit of research, and replied with this

My reply

Turns out they already knew this, as shown in this reply

The reply

So, I did some more digging. To my surprise, in the GOG.com release of the game, there is a file named kain2.map , which, instead of being a level file like I though it was, was actually a linker address map, which look something like this

kain2 Timestamp is 381a30c7 (Fri Oct 29 16:41:59 1999) Preferred load address is 00400000 Start Length Name Class

0001:00000000 000eab1eH .text CODE

0002:00000000 000002b8H .idata$5 DATA

0002:000002b8 00002603H .rdata DATA

0002:000028bc 000000b4H .idata$2 DATA

0002:00002970 00000014H .idata$3 DATA

0002:00002984 000002b8H .idata$4 DATA

0002:00002c3c 00000c3aH .idata$6 DATA

0002:00003876 00000000H .edata DATA

0003:00000000 00000004H .CRT$XCA DATA

0003:00000004 00000004H .CRT$XCZ DATA

0003:00000008 00000004H .CRT$XIA DATA

0003:0000000c 00000004H .CRT$XIC DATA

0003:00000010 00000004H .CRT$XIZ DATA

0003:00000014 00000004H .CRT$XPA DATA

0003:00000018 00000004H .CRT$XPX DATA

0003:0000001c 00000004H .CRT$XPZ DATA

0003:00000020 00000004H .CRT$XTA DATA

0003:00000024 00000004H .CRT$XTZ DATA

0003:00000030 00017a24H .data DATA

0003:00017a58 007606b8H .bss DATA

0004:00000000 00000178H .rsrc$01 DATA

0004:00000180 000015f8H .rsrc$02 DATA Address Publics by Value Rva+Base Lib:Object 0001:00000000 _ALUKA_ControllersEnabled 00401000 f aluka.obj

0001:00000020 _ALUKA_SetPitch 00401020 f aluka.obj

0001:00000080 _ALUKA_EnableControllers 00401080 f aluka.obj

0001:00000170 _ALUKA_DisableControllers 00401170 f aluka.obj

0001:00000230 _ALUKA_SetSwimBodyTwist 00401230 f aluka.obj

0001:00000370 _ALUKA_NotDaylight 00401370 f aluka.obj

0001:000003a0 _ALUKA_CapDepth 004013a0 f aluka.obj

0001:00000460 _ALUKA_AngleTooWide 00401460 f aluka.obj

0001:000004e0 _ALUKA_VectorFromPitchYaw 004014e0 f aluka.obj

0001:00000590 _ALUKA_FacingVector 00401590 f aluka.obj

0001:00000660 _ALUKA_SimpleLineCheck 00401660 f aluka.obj

0001:00000720 _ALUKA_TerrainInPath 00401720 f aluka.obj

0001:00000850 _ALUKA_ApplyIncr 00401850 f aluka.obj

0001:00000890 _ALUKA_ApplyForwardAccel 00401890 f aluka.obj

0001:000008f0 _ALUKA_ApplyAngularAccel 004018f0 f aluka.obj

0001:00000990 _ALUKA_ApplyRots 00401990 f aluka.obj

0001:00000b10 _ALUKA_MoveForward 00401b10 f aluka.obj

0001:00000c00 _ALUKA_FixPitch 00401c00 f aluka.obj



The linker file first declares the executable name, minus extension, then the timestamp, load address, and then sections of the executable.

The next section specifies in more detail what is in each section of the executable file. e.g. 0001:00000000 00EAB1EH .text CODE is a section starting from offset 0x0 with length 961310 which held CODE . However, a most of these declarations aren’t correct entirely, with the .CRT$XXX sections holding data and functions related to the Windows Common Run Time, the core of C/C++ on Windows.

After that comes the stuff we care about, the address names. These take the form of XXXX:OFFSET NAME OFFSET+BASE OBJFILE . This was invaluable when working with disassembly, as without debugging files, all functions are named something along the lines of sub_offset where offset is the address of the function. This file allowed me to identify function names and what source file they came from (the OBJFILE field). However, despite initially renaming functions manually, I soon got sick of it. Eventually, I decided to use the IDA Python scripting interface to automate the process, as the existing plugins hadn’t loaded the map-file completely. The script is a bit hackish, but it works reliably, and did the job.

Map parsing script

De-mangling and Mangling