Reverse Engineering The Save Ram on A Sonic 3 Genesis/Megadrive Cartridge

Discussion in 'Modding and Hacking - Consoles and Electronics' started by vext01, Jan 26, 2012.

  1. vext01

    vext01 Active Member

    Joined:
    Jan 26, 2012
    Messages:
    39
    Likes Received:
    2
    Hi,

    Just for fun I though I would have a prod about on the sonic 3 save game ram. I had never peeked into a megadrive cart before, so this is all new to me.

    My plan was as follows:

    Use an emulator (I'm using dgen/sdl) to take periodic save game ram (thats the battery backed SRAM) dumps and bindiff them using radare2's radiff2.

    And this does appear to work. I have identified what I believe to be the character (as in sonic/tails/both) field in save game slot 1.

    However, changing this field willy-nilly does not work, I think there is a CRC/checksum which has to be calculated.

    What I did here was:

    1) Start the game as sonic and tails, dump the sram to file.
    2) Start the game as sonic only, dump the sram.
    3) Start the game as tails only, dump the sram.

    To dump the ram you have to exit the emulator. When I say "start the game", I mean start the first act of zone 1 from a fresh sram (just remove the sram dump file from ~/.dgen/ram).

    I did two sram bindiffs:

    Sonic -> Tails
    Sonic -> Sonic + tails

    The table below shows the diff results:



    0x0000016c 01 => 02 => 00
    0x000001cc 70 => c7 => ed
    0x000001ce 4f => fd => 3e
    0x000001f8 01 => 02 => 00
    0x00000258 70 => c7 => ed
    0x0000025a 4f => fd => 3e


    (The columns are byte offset, value for sonic only, value for tails only, value for both characters)

    The first thing to note is that everything was written twice at different offsets. Perhaps for backup purposes? Anyway this is nice, because we now know the length of the save game slot :)

    0x0000016c and 0x000001f8 appear to be where the character is selected:
    0x00 = Sonic and Tails
    0x01 = Sonic
    0x02 = Tails

    But the other bytes? Checksums?

    If this is a checksum, what algorithm is likely to be used?

    Does anyone tinker with this stuff here atall?
     
  2. vext01

    vext01 Active Member

    Joined:
    Jan 26, 2012
    Messages:
    39
    Likes Received:
    2
    To clarify, if you change the character select byte, the sram is erased. This leads me to believe that the other bytes which changed are checksums of some kind. And we need to know how to calculate these.
     
  3. derekb

    derekb Well Known Member

    Joined:
    Jan 7, 2009
    Messages:
    1,964
    Likes Received:
    44
    Given how enthusiastic the Sonic hacking community is, I can't help but imagine this entire file has been broken down to its smallest pieces already
     
  4. Jorge Nuno

    Jorge Nuno Active Member

    Joined:
    Aug 10, 2011
    Messages:
    28
    Likes Received:
    0
    Let me pull and old image from Tmee... (see below)



    And for the "checksum" this was from an old coversation between me and him:

    Looks like some sort of LFSR thingie...

    Don't bother asking me anything because this fossil is about 5 years old, I don't rememeber :p
     

    Attached Files:

    Last edited: Jan 27, 2012
  5. vext01

    vext01 Active Member

    Joined:
    Jan 26, 2012
    Messages:
    39
    Likes Received:
    2
    Ah ha. I knew someone would know.

    This verifies indeed that the data is written twice and that there is some kind of CRC/checksum. When I find some time I'll read the code in more detail.

    This guy's site is also awesome -- thanks for sharing.
     
  6. APE

    APE Site Supporter 2015

    Joined:
    Dec 5, 2005
    Messages:
    6,417
    Likes Received:
    141
    FRAM, not SRAM.
     
  7. vext01

    vext01 Active Member

    Joined:
    Jan 26, 2012
    Messages:
    39
    Likes Received:
    2
    Sweet!

    Works like a beauty. We spent some time reversing the asm code and have a C implementation of the checksummer. When I get some time I will write a program that allows you to make a custom save RAM :)

    There were additional hoops, as dgen-sdl stored the ram slightly differently to as we expected (word align *every* individual byte).

    Thanks for the help.
     

Share This Page