RED-Project icon indicating copy to clipboard operation
RED-Project copied to clipboard

"Earthion (STEAM)" - extract Genesis / Mega Drive rom?

Open YaketyJoe opened this issue 4 months ago • 21 comments

Hello,

I bought "Earthion" on Steam. I see that the Genesis/Mega Drive roms have been extracted by some people online, but I haven't figured out how to do it myself. I've tried memory dumps and can't find the rom data. I see a game.bin file, but it seems to be all the roms together, but encrypted.

Has someone here figured out how to extract the roms?

YaketyJoe avatar Aug 01 '25 19:08 YaketyJoe

I haven’t bought it yet, but I have heard many people say that they were able to easily extract it and run it on real hardware. Could you try to provide a header for us from the Game.bin file? Maybe that will give us a clue as to how it wants to be run.

DrAzathoth avatar Aug 02 '25 13:08 DrAzathoth

the game.bin seems to be a compressed file, it has no header. There's multiple files inside, it has 7 roms. Also, I think most people saying they got the rom, didn't extract it themselves. it is still unknown who originally extracted it and their method.

YaketyJoe avatar Aug 02 '25 14:08 YaketyJoe

However, the extracted roms have a SSF header. They are easily found on the archive website.

YaketyJoe avatar Aug 02 '25 14:08 YaketyJoe

It seems like there's two layers of protection applied to game.bin. The outer layer is a custom encryption applied to the entire file. That is quite simple and can be decrypted with something like this:

            byte[] buffer = File.ReadAllBytes(inPath);
            uint key = 0xDEADCAFE;
            int counter = 0;
            do
            {
                byte temp1 = (byte)((key >> 9) & 0xff);
                byte temp2 = (byte)(temp1 ^ buffer[counter]);
                buffer[counter++] = temp2;
                key = (temp2 ^ key) * 16777619;
            } while (counter < buffer.Length);

I'm guessing the people who uploaded the ROMs dumped them at runtime because the custom decompression algorithm looks to be tricky. It seems like there's 3 tables in the executable containing different values for each ROM within the binary file. The first 13 bytes at the offsets specified in OFFSETS_1 seem to contain header data required for decompressing that corresponding ROM from the file. Gonna take a break for now though.

        private static readonly uint[] OFFSETS_1 = new uint[] { // Offset of decompression header data within decrypted game.bin
            0x00000043, // English
            0x004C5F87, // Japanese
            0x00987535, // Portugese
            0x00E4D8D2,
            0x010A6A9C,
            0x01404DA0,
            0x018129BD,
        };

        private static readonly uint[] OFFSETS_2 = new uint[] { // ???
            0x004C5F44, // English
            0x004C15AE, // Japanese
            0x004C639D, // Portugese
            0x002591CA,
            0x0035E304,
            0x0040DC1D,
            0x000188D3,
        };

        private static readonly uint[] OFFSETS_3 = new uint[] { // ROM size? Though the last value is weird
            0x00780000,
            0x00780000,
            0x00780000,
            0x006A0000,
            0x006A0000,
            0x00740000,
            0x018129BD,
        };

Infinest avatar Aug 04 '25 21:08 Infinest

I just tried the python scripts on archive.org and they work, it extracted the roms!

YaketyJoe avatar Aug 06 '25 15:08 YaketyJoe

I just tried the python scripts on archive.org and they work, it extracted the roms!

Did they work with the 2.0.1 update?

bootsector avatar Aug 06 '25 15:08 bootsector

yea, with 1.8.0 (the original release version) and 2.0.1. You can see the version on lower left, by holding down "B" when going to the option screen

YaketyJoe avatar Aug 06 '25 15:08 YaketyJoe

Oh, awesome to see the person included the script for unpacking. Last thing i found out yesterday was the reason why you couldn't find any of the ROMs in RAM during runtime. The ROM is still in an "encrypted" state after decompression and the emulator actually "decrypts" each pair of bytes within the ROM at runtime. I'm kind of glad i don't have to figure out the rest now. 😅

Infinest avatar Aug 06 '25 15:08 Infinest

Thanks for looking into it, though, appreciate it!

YaketyJoe avatar Aug 06 '25 16:08 YaketyJoe

The unpacker script (wish they didn't bundle the unpacker with rips...): earthion-unpack by Anonymous.py.txt

hadess avatar Aug 06 '25 16:08 hadess

exactly, that's why I didn't link to it.

YaketyJoe avatar Aug 06 '25 16:08 YaketyJoe

Here's a backup of the older script for posterity. decrypt_earthion by SharpNull.py.txt

DrAzathoth avatar Aug 07 '25 01:08 DrAzathoth

I noticed that when I ran Earthion in Genesis Plus GX, the game would have an address error and crash when entering demo mode after being idle for a while. Curiously, I was never able to recreate the issue on any subsequent trigger of demo mode.

Make sure to disable the "68K Address Error" option when playing the game or any similar feature in other emulators if you encounter this crash.

DrAzathoth avatar Aug 07 '25 02:08 DrAzathoth

Updated extraction tool for Earthion 3.3.0 This tool also supports all older versions as well.

earthion_unpack_v3.3.0_v3.zip

Both "3.3.0" builds released on Steam have byte-for-byte identical ROMs. There is no reason to downgrade aside from if you want "2.0.1" or the launch version of the game.

DrAzathoth avatar Sep 11 '25 07:09 DrAzathoth

Interesting that the Summer / Fall / Winter 2024 demos also got updated. Only a single byte in the exception vector table changed for each of these roms, at 0x70 from E0 to 00.

According to ChatGPT, bytes 0x70 to 0x74 are for the VBlank interrupt, with E0 -> 00 changing the memory location of the interrupt from an invalid location in the ROM space to a valid location in RAM instead: https://chatgpt.com/share/68c2e50a-a790-8005-9ac4-0625e75bb734

farmerbb avatar Sep 11 '25 15:09 farmerbb

@farmerbb I noticed that as well. I assumed it had to do with emulation accuracy, and I guess I was correct.

For anyone curious, an oversimplified explanation of what we noticed is that some “metadata” in the ROM was changed. Specifically, one byte. The original ROMs for the 2024 demos were probably intended for a specific cartridge mapper, while the “new” 2024 demo ROMs are compatible with both real hardware and emulators.

TL;DR The new versions of the 2024 demo ROMs introduced alongside Ver. 3.3.0 are more compatible with both real hardware and emulation, so use those versions if you want to play them.

DrAzathoth avatar Sep 11 '25 20:09 DrAzathoth

Earthion Ver 4.0 is out.

Awaiting an updated version of the script to support it.

DrAzathoth avatar Oct 25 '25 08:10 DrAzathoth

Same as before. I did not find any differences in the demo ROMs this time.

earthion_unpack_v4.0.0.zip

And here are the instructions once more:

Step 1: Go to the 7-zip website, from the sidebar, select "LZMA SDK", download the latest version. Unzip it. Inside you'll want to go to the "bin" folder and find lzma.exe. Place this in a folder. Step 2: Right click on Earthion on Steam, choose "Manage > Browse local files". Go to the folder called "Data". That's where game.bin is going to be. Go ahead and place it in this folder as well, right next to lzma.exe. Step 3: Install Python 3 from the official Python website if you haven't already. Make sure to choose "Add to PATH variable" before you start the installation. Reminder: You now have a folder that has the following files all right next to each other: lzma.exe, earthion unpack script, game.bin. Step 4: Open command prompt here. Run "py earthion_unpack_v4.0.0.py". Wait until it's done.

I did not need "lzma.exe". Perhaps users with 7-zip already installed don't need it?

DrAzathoth avatar Oct 30 '25 00:10 DrAzathoth

I'm able to decompress the ROMs on Linux just fine by running python earthion_unpack_v4.0.0.py with game.bin in the same directory. Not sure if I have any required dependencies already installed or not.

farmerbb avatar Oct 30 '25 04:10 farmerbb

You'll probably need to change line 90 to v += int.to_bytes((int.from_bytes(vec_enc[off:off+3], 'big') << 1), 4, 'big')

vadimkulmanoff avatar Oct 30 '25 08:10 vadimkulmanoff

I'm seeing no difference in the extracted files when making the change to line 90.

MD5 sums:

03b801307139d2dfe1c0f14c5120b9bd  Earthion Portuguese (v4.0.0).md
1145b489d2fad3ce284700b2efcbfdaf  Earthion Japanese (v4.0.0).md
1657b315f4ec2e9ef012a78989f4df6d  Earthion Fall 2024 Demo (v4.0.0).md
5c865c848edcca81d380f1f10173d423  Earthion Early Prototype (v4.0.0).md
aa5475a6cceff3b84ab23d374f0c4cbd  Earthion English (v4.0.0).md
b516a4c3ce3c2bd2984778fdf1a79057  Earthion Winter 2024 Demo (v4.0.0).md
cae2c5e0de6c09826a20e19f6b39887f  Earthion Summer 2024 Demo (v4.0.0).md

farmerbb avatar Oct 30 '25 16:10 farmerbb