Friday, October 3, 2014

Hacking 'I Wanna Be The Boshy' Game Saves


Background

It seems that the world missed the "good ol' days" of ridiculously hard platform games. Games that were made difficult mostly due to the fact that they had to be short to fit on a cartridge. Years ago, a guy known as Kayin created a game called "I Wanna Be The Guy" - a masochistic game to show us just how insanely difficult developers could make platform games.

The game is known for being legendarily difficult; sporting difficulty options for no saves, longer boss battles, and countless "gotcha" moments. Essentially, a compilation of ripped assets from roms to create something ridiculously difficult, but insanely fun:

Anyone who played IWBTG remembers the goddamned spike corridor at the bottom, lol.


Eventually, this went on to inspire a more polished indie game called:


Who dialed back the difficulty a bit and brought it more mainstream.



Eventually, this wave of super hard "throwback platformers" even reached Capcom when they developed 

and


... further proving that, not only can they still make nail ripping-ly difficult platformers, but are still pretty damn good at it.



During this time period, a guy who goes by the name of Solgryn developed a game much like "I Wanna Be The Guy", but added multiple characters:



And online play as well:


It's also much longer and calls itself "I Wanna Be The Boshy"


The game runs on Multimedia Fusion 2's engine - a staple for a lot of platformer indie games.

During a playthrough, I wondered what the game save format was like and if values could be modified to fully unlock the game and set options passed their normal limitations. 





The Save Format

By default, data is passed around in MMF2 in ini files - IWBTB is no different:



Unlike normal ini files, however, these are encrypted...

After running procmon to take a look at this massive 130MB executable, we can see that it unpacks itself and operates out of a directory...



In the directory, we see a whole bunch of mfx modules which are basically renamed .dll files. The most interesting of which is INI++... what could this be???


oh...
ooohhh....

OH!



Ok, so we have a custom module that basically acts like a read/write wrapper for the normally plaintext ini files, takes a password, and encrypts the data. It also supports MD5 hashing without changing the size of the output file (from the site).

Well... if  that's not information bleed...

So we have this crypto that is the same size as plaintext (meaning no key or salt attached to the encrypted data) and theres a password that somehow encrypts or decrypts it. Yay stored secrets!!!

Throwing their dll in IDA will get you something like this with IDAScope (I used it to see what crypto modules they're using):

Ok... just the MD5 inits - well, they already said they had the ability to store hashes of the strings instead, but MD5 is one way so thats no way to encrypt something (doesn't do ya much good if you can't recover it, haha).

So no fingerprints of a common crypto interface - looks like someone wanted to hand-roll their own crypto... the only thing someone should roll about that is their eyes (lel).

Well , guess it's time to start digging for "crypto" functions in the binary (Hint: just look for a bunch of bitwise operations and stupid array shaking).


....aaaaaand pwnt.


Alternatively, you could also just find that an open source python impl of MMF2 is online called anaconda. They happen to have this extension module already converted.


With this, I could make a python tool to encrypt/decrypt the data:




So now we know the algorithm... but we still don't know the damn password! Fortunately, MMFS2 is publicly available and so is this plugin.

Getting The Password


After making a small test project that simply starts and writes an ini file with some data into an encrypted file, I find that the password allows no special characters and one line.



I compiled my project and set out in its running memory to find my password in plaintext because... #YOLO I guess...




Doing the same thing on IWBTB will net you a lot more text, but looking near the areas in memory where I found my password, theirs stuck out as well






The result:

The src below will decrypt/encrypt any of Boshy's INI files - the algorithm is reversible... just run again to re-encrypt. Decrypt a fully unlocked save available online if you want :)

Fin






Thursday, August 7, 2014

Hacking Clocktower - The First Fear



This one... this one should be fun - let's take a great Japanese survival-horror game, figure out how it works, make it English, and do some other stuff to it :)

Introduction
If you've never heard of ClockTower (or Clocktower - The First Fear as it's known in Japan), it was a game originally for the Super Nintendo by Human Entertainment.

It's one of those point and click adventure games (if you're old like me and remember those), but it's also one of the earlier games that would help create the survival horror genre. Basically, these 4 orphans end up at this mansion after the orphanage closes and they start disappearing; you take over the role of Jennifer in the group and have to find a way out, hopefully find your friends, and figure out what's going on in the mansion.

The atmosphere is gritty, things happen in the house for no apparent reason at random (it's pretty haunted; let's just say), sometimes things just come out and kill you, and all the while, this psychopath with a pair of gardening shears is chasing you around the house - stalking you (the nemesis thing from Resident Evil 3 was not some cute idea Capcom came up with):


The game is filled with gritty situations that involve thinking quickly on your feet to survive, running and hiding is the only option, but saving what sanity Jennifer has left is also important as she can trip over her own feet and die of a heart attack if things get too intense (a la Illbleed).

Anyway, this game was released in 1994 for the SNES, re-released with more content on the PSX in 1997, released on the Wonderswan (but nobody gives a damn about the Wonderswan), and finally released on the PC (and then later re-released on the PC in 1999 as a value edition).

Yes - there's an English translation of the SNES rom by Aeon Genesis (I think it was him, anyway), but the SNES version is kinda shitty compared to the PC version which has much better sounds, an FMV intro, etc. Probably the only version with a bit more content is the PSX version, but we'll get into that later.

First, let's focus on getting the game running without the CD!

Part 1 - The Landscape

Basically, we have a game directory that looks like this:

We have a BG directory containing what looks to be the room backgrounds in a carved up format along with an accompanying .MAP file for each one which I can only assume maps the various slices to the screen:


We have a DATA directory containing various PTN and PYX files... not sure what these are at the moment... probably mapping the level screens to logic or something.

We have a FACE directory containing bmps of the faces when people speak:

We have an item directory containing all the items Jennifer can use:


We have a PATTERN directory with ABM files. I believe these are used for sprite animations, but I could be wrong.

We have a SCE directory with two files: CT.ADO and CT.ADT... we'll get to these - basically, it's a logical script for the actions that happen in the entire game using a custom binary scripting language... this is going to be where we spend most of our time.

We have a SNDDATA directory with MIDI and WAV files for BGM and SFX

We have a VISUAL directory with all the HQ renders shown, menu options, etc in BMP format. This is also where the intro video is held.

Finally, we have a DATA.BIN file which... I have no idea what it does at the moment in addition to the ct32.exe which is our game executable.

Running the game without the CD present will give us this:

Running it in a debugger to find this string, you'll find that it's basically saying it doesn't know where the game data is (ie CD is not inserted).

Part 2 - Let's NOCD this bitch
Looking in IDA, we already see RegQueryValueEx used - basically pulling from a registry key... I wonder what it's getting?

Well then... I guess that's the answer.

BUT WAIT.
Let's check first to see what calls this... maybe we can hardcode it:

It seems to be a bit more digging has paid off! The game looks for an arg called NOREG. If it doesn't find it, it checks the registry value, it skips the check and starts the game assuming it's in the parent directory. A simple patch to make the game think it's always being executed with NOREG as an arg by changing the jz to 0xEB (or unconditional JMP) should do the trick here.

Running it now produces:


Oh YES :D

Part 3 - Finding the in-game text 
Stepping back from a logical standpoint, should we expect all the text to be in the executable? Well, it's possible - many games do it. There are even some strings in the binaries (like the NOCD error we found) that are static, but I have a feeling they're going to be elsewhere (maybe in the DATA files?) - let's see:

Japanese text that uses the SHIFT-JIS format (extremely popular) normally starts with a control character of 0x80-0x8F... simply looking for stuff like this in the executable is a good place to start.

We then copy these strings out  to a new file and open in notepad++ - pasting it into Google Translate:
Well, these look like some errors, but no real game dialogue... time to look in other files!!!

Hrmm - well the PTN and PYX files don't really have anything text-related... let's check the SCE folder :)

Well, the CT.ADT file looks to have 4 byte offsets (they count up from 0x100 all the way to the end of the file, 4 bytes at a time).

The CT.ADO file, however...


Now we're getting somewhere... not only are there ASCII strings that look like file paths, but also SHIFT-JIS text strings. The data in this file is kind of odd... let's see if we can understand it, better. We're gonna have to if we need to parse it.

 Part 4 - Diving into ADO/ADT
We've already looked a bit into how ADT works, let's take a look at what ADO looks like:

Basically, we have a magic (ADC Object File) across the top, then a bunch of 0xFFs to get the offset up to 256, then it looks like data begins. Time to think like a Computer Scientist!!!

We have all these strings, a binary format with no apparent lookup besides potentially that ADT file, there has to be some kind of control code in here mixed in with the data to let the game know what it's looking at as it's being parsed... everything has a structure, somehow.

Looking at the strings with .BMP, we notice that they follow a similar pattern:

39FF followed by a null 2-byte value (most of the time, sometimes it's 0x0100 which makes me think this is a WORD value), then a null-terminated ASCII string and some padding... In fact, EVERY time a BMP is loaded for FACE, 0xFF39 as a value is at the front! 

Let's check the executable:

Nice! Not only do we have this valule, but we have other values as well - let's check a few Shift-JIS strings to see if we can find a pattern:

Awesome! All strings start with 0xFF33, have two 16-bit values (0x0F00), and then a Shift-JIS string.

Note: One thing you'll notice about SHIFT-JIS is that it is NOT null terminated; it can't be. You see, certain programs can operate on a mix of both single and multi-byte character values, but older ones had a more difficult time with this. As a result, you'll notice that all linebreaks (0x0a) have an 0x00 after them. In fact, ANY ASCII character in this has an 0x00 after it (and numbers or english letters). This is a way that the text rendering can support multibyte interpretation with ASCII characters (0-127) and not accidentally fuck up and read a data byte as a control byte and vice-versa.

As a result, we can concur that some logic in the game must parse the string until it finds the end somehow (probably by looking for a new opcode (normally 0x28FF).

So now we know that an ADO file is basically a shit-ton of scripting 'opcodes' and subsequent data. We can theorize that the game reads this and knows what data to expect based on the preceding opcode. Now, we can look at the switch statement in the executable that we found earlier (with all the cases) to mark down every opcode the game supports (to better understand the format)

We do this by noting the values (0xFF20, 0xFF87) and looking at them in the ADO file, determining if they have the same number of data bytes before the next opcode, attempt to figure out if they're 2 byte values, strings, etc, and so on.

In addition, you'll notice that the executable has some interesting text:


In fact, this is a list and looks suspiciously like opcode names - lucky for us, they ARE! We now know what the opcode names are :)
From this point, we can run the game with a debugger, breaking at the various switch statements to see operations of various opcodes - one that might be interesting to us is JMP...

In fact, the first JMP (0xFF22) has a 2 byte value of 0x17 after it.

If you watch this in the game, and set the ADO_offset as a watched variable in IDA, you'll see the game jump from this value to 0x1B32 - How did it know to do that? It's not a multiple... maybe :


AHA!

0x17 * 4 is 0x5C - the ADT is a jump table for various scenes... you'll notice that the CALL function (0xFF23) works in a similar way, but returns to this offset after a while... The first few ADT offsets all point to 0xFF00... it seems to be pretty prominent in the game... the jumps actually skip over them though (they add +2 to the offset after jumping)... are we seeing some kind of RETN opcode???? I think so ;)

You'll notice, however, that the ADT file has various values at the end that are far beyond the size of the ADO file... what gives?! We'll get into that, but it will take a bit more introspection into the game running to determine how these jumps work (specifically watching the jumps).
Dumping the memory, one thing you'll notice is that the ADC object file in memory (CT.ADO) has a value of 0x8000 int16 written in every 0x8000 or 32kb. Besides that, the ADO is unchanged. You can also see in the executable that it a function parses the values and skips 2 bytes ahead if it sees this value (akin to a NOP).


As this game splits the data into 32k chunks (most likely to reference memory in a more segmented fashion (we're dealing with 2 byte values a ton - this is important), there has to be some sort of "address translation" for the ADT (as the ADT uses 4 bytes to reference an offset).

So there's a bunch of math here that, if you watched the debugger, you'd see something akin to this:

I didn't find the function originally, I actually went to the end of the ADT file (assuming it was a pointer to the end of the ADO file (the last RETN being offset 0x253F4). The ADT had this listed as 0x453F4... after looking at various others, I noticed that the translation took the two significant bytes, halved them, and stuck them back onto the end :)

Ok, so far, we can generate ADT files (generating is the opposite; multiplying the most significant depending how many intervals of 0x8000 we've been over), we also have a general breakdown of the opcodes, and we know where the strings are. Before we dive into disassembly; let's keep our eye on the prize and go for broke (translation first).


Part 4: Enter CTTDTI Suite
We know what format the strings are in and how to read them out of the ADO file... of course, injecting them back in will involve modifying the ADT offsets as string sizes are going to be much larger or smaller depending. Firstly, let's focus on ripping the ADO strings out into a text file ... something easily editable and that can be read back into another program to mess with them, even still, let's make a format where we can easily inject the strings into a new ADO file and update offsets easily... what do we need???

Well, the offset where the string starts is important, so is the size of the original string in bytes, then the string itself... sort of like

0xE92 25 blahblahblah

Enter cttd.py:
Basically, I renamed CT.ADO to CT_J.ADO for when I generate a new one.
This program reads in the ADO file, finds 0xFF33, skips 6 bytes ahead (to skip the opcode and 2-2byte values), and writes the starting offset of the string, the length of the string, and the string itself in a tab delimited format ending with a newline to a text file - simple :)

You'll notice that I replace any 0x0a value (newline) with [NEWLINE] - this is because I want the whole string to be processed on one line and be able to specify newlines where I want them without having to modify the format of the text file.

For fun, let's do something kinda silly - we're gonna parse this text file with translator; a python module that dumps data out to google translate and autodetects language, translates, and returns it in your desired language:
cttt.py:

Let's try a couple of strings with an injector now - the last program in this suite parses the text file,adds null-padding to any ASCII character in the strings, and reads the lines into a dict so we know what offsets are affected. It also rebuilds an ADO from scratch (it reads the ADT, loads all the "scenes" into an array with their offsets, copies all the data between strings and afterward), and then regenerates an ADT based upon the sizes of the ADO "scenes" while constructing:
ctti.py:


And we test to see if it works:

Nice!
The Engrish in this is gonna be terrible though - thankfully, I found an rtf on some Clocktower Fan Forum ( ;) ) and can manually edit the strings based upon the rough translations.


It's all translated and ready to go! We run it:


GOD DAMMIT!!!

Ok - something's wrong; let's throw it into IDA and see what's up:

So it looks like it's trying to read the ADO file into memory, but it tries to resolve a pointer and can't because nothing exists at that spot!

Seeing the struct a1 and all the malloc'ing it does, this must be the issue - digging back further, you'll find that these pointers are made here:

So the game (based on the cmp5 opcode) will only make pointers for 5 * 0x8000 chunks of the ADO but will read the ADO data in until EOF (definitely a bug). As a result, we can only load an ADO file of max size 0x28000. Does that stop us!? FUCK NO! Let's dig into this SCE struct in memory a bit more...

We can change all instances of loading the ADO pointers in from 5 to 6 in order to add another pointer, but what's after that last pointer? Why, the start of the ADT offsets, of course :)

We see that ADT offset 0x00 is at struct_head + 0x2A and goes for 0x7D0... seriously? 0x7D0 pointers??? that's like 0x8000 wait a minute:D:D:D:D:D

As a result of only having 0x4800 bytes used for our ADT file, we can say that bumping the ADT start index down to , say, 0x2E would give us 4 more bytes to write another ADO pointer there and we'd still have a ton of reserved room to spare at the end!

Finding struct references to 0x2A and changing them to 0x2E as well and:

#AWWWWWYEAAAAAAA - Gotta love Object Oriented Reverse-Engineering :)

Ok - so now we have the game completely translated, now what?!

In fact - here are the ADO/ADT files I created (drop them in your SCE directory to play clocktower in English :)))
You'd also need to make binary changes with a hex editor to CT32.exe:
Future Work - Part 5 - SCEDASM - the SCE disassembler
The next logical step would be to disassemble all the other opcodes as well to build a text file that could eventually be read into a game/editor :)

Sort of like, well - this:
scedasm.py (WIP and extremely hacky... an exercise for the reader):


Then of course, we'd need to push this all back into an ADO/ADT pair:

sceasm.py:
**NOW PRINTING**

Future Work - Part 6 - The PSX Version
The PSX version of the game uses ADO/ADT as well!!! We could convert the assets and add the PSX exclusive content to the PC version, it would seem.

Until Next Time :)