rom structure - wrongbaud/sf-cabinet GitHub Wiki

Notes on Rom Structure

Understanding ROM Loading

Since we are likely dealing with some kind of fork of MAME, which makes sense given the fact that the extracted roms:

wrongbaud@wubuntu:~/output-files$ ls -lathr sf*
-rw-rw-r-- 1 wrongbaud wrongbaud 3.4M Aug  7 09:57 sf2ce.zip
-rw-rw-r-- 1 wrongbaud wrongbaud 317K Aug  7 09:57 sf2ceua.zip

Can be loaded into mainline MAME, we can now assume:

  • sf2ceua.zip is likely the ROM that is targeted by the emulator (this is the child ROM of the sf2ce.zip parent)

If we overwrite the pointer to the sf2ceua.zip to point to the data region in use by the larger sf2ce.zip AND replace that with a different MAME file, does it load?

** Important Distinction **:

  • The file sf2ce.zip reports 920513 as the software version in the title screen:

  • When sf2ceua.zip is loaded, it reports 920313

There is a less than 0 chance that the game directory that we have extracted is just the standard ROMs directory for MAME - the emulator is just hard coded to load up sf2ceua.zip

Welp, it looks like file names absolutely matter in the realm of the MAME program, renaming ROMs to other names causes them to not load.

So it looks like in order to fix this - or get other ROMs to load, we're going to have to patch the emulator ...

Kaitai Graphiz Output

Bootup Notes

It looks like the first executable that the kernel (epos.img) launches is shell.zgj - this is the application that executes the shell script that we were previously modifying. So what does this call?

The zjg files have the following header:

Notes on decoding axf files

Name: game_wl.axf Raw Size: 0x82a28 Original Size: 0x46133

If we look at the header for the file game_wl.axf we have the following:

5D 00 80 00 00 00 00 62 80 3C 17 63 1D 47 CD E9
17 68 A7 61 C3 91 40 2B C1 7F B9 92 A2 19 57 1B

This looks

Alright...this is weird. Looking at the home.axf binary because it's small and any math might be a little easier on my peanut sized brain.

After writing a python script to brute force through multiple header types, I've noticed the following:

  • The max filesize that we can seem to generate is 16512, the reported size of the binary is 16512 let's to a little python math here and see what's going on

0x7e44 32324 16512 *2 33024 (16512 *2)-32324 700

So the difference between these two seems to be 700 bytes, where might this data come from? Are there any 700 byte files?

Important

It looks like the home binary selects the ROM, in the strings at least it has the path:

\game\sf2ceua.zip

Note -

I was able to get the keytest program to run by changing the name entries in the MINFS table, replacing game_ql.axf with keytest.axf and vice versa - I also changed the .desktop files as well just to be safe. This caused the keypress program to be run on startup.

Now I am testing to see if the kernel handles file decompression or the loader

Test Thoughts

  • Since we know that the game_wl.axf is not getting executed (remember we swapped it with keytest). We can null out the 5D 00 80 00 00 sequence in the header. If the cabinet fails to boot, this will tell us that the code responsible for decompression is in the kernel and not handled by the OS loader. Meaning that we can probably reverse engineer the functionality out of the kernel -- results --> NOPE.

Emulator in use

  • Based on some of the debug information, it appears that they are using FlashBack Alpha as the main emulator. This still doesn't quite help us

Revisiting init.axf

Uncompressed Size = 0x643F Largest Decomp: 79648 0x13720 Decompressed size (according to header information): 0x1C780 See the Kaitai output below:

19 [MinfsTableEntry]
    flashOffset = 0x12440C = 1197068
    rawSize = 0x6438 = 25656
    originalSize = 0x1C780 = 116608
    entryLength = 0x9C = 156
    flags = COMPRESSED_AXF (0x6 = 6)
    nameLength = 0x8 = 8
    extraLength = 0x80 = 128
    name = init.axf
    normalPad = [0, 0, 0, 0, 252, 98, 0, 0, ...]
    directoryContents