Hacking SRAM Bank switching on Bootleg cartridges

bbsan2k

Well-Known Member
OP
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,444
Country
Germany
Hi everybody,

I'm currently in the process of reverse engineering some of the chinese bootleg cartridge ROMS.
As some of you may know, recently at least all Pokemon Repros are coming with batteryless save.

After some digging around in these ROMS it came to my attention, that they are using the additional SRAM (up to 1024K) that is on board of those repros.

Affected repros are:
- GE28F128W30
- 36L0R
and probably many others.

Things I discovered:
- At startup, the GBA loads a defined area of ROM into SRAM
- After half of it (64KByte), it writes 0x1 to 0x9000000 which seems to switch the Bank from 0->1
- After everything is in SRAM 0x0 is sent to 0x9000000 which seems to switch the bank back from 1->0
- Then ROM continues to start up normally

To make this useable with SRAM patches like those applied through gbata, the bank switching needs to be added accordingly.

For FLASH1M_v103 (Pokemon FireRed), the following could be done:

==================================

Block 1 (Bank switching):
054B AA21 1970 054A 5521 1170 B021 1970 E021 0905 0870 7047
==>
0549 0000 0000 0000 0000 0000 0000 0000 0000 0000 0870 0747

Block 2 (Chip Ident Start):
064A AA20 1070 0549 5520 0870 9020 1070 10A9 034A 101C 08E0
==>
064A AA20 0000 0549 5520 0000 9020 0000 10A9 034A 101C 08E0

Block 3 (Chip Ident End) (Basically this also can be nooped completely):
0749 AA20 0870 074A 5520 1070 F020 0870 0870
==>
0749 AA20 0000 074A 5520 0000 F020 0000 0000

Block 4 (Erase whole Chip):
1449 AA24 0C70 134B 5522 1A70 8020 0870 0C70 1A70 1020 0870
==>
0E21 0906 FF24 8022 134B 5202 013A 8C54 FCD1 0000 0000 0000

Block 5 (Erase 4K sector):
1449 AA25 0D70 144B 5522 1A70 8020 0870 0D70 1A70 3020 2070
==>
0000 FF25 0822 0000 5202 013A A554 FCD1 0000 0000 0000 A554

Block 6 (Store 1 Byte):
0C4A AA20 1070 0B49 5520 0870 A020 1070 2770
==>
0000 0000 0000 0000 0000 0000 0000 0000 2770

Block 7 (Copy 1 Byte from one place in SRAM to another):
0A4C AA22 2270 094B 5522 1A70 A022 2270 0278 0A70
==>
0000 0000 0000 0000 0000 0000 0000 0000 0278 0A70

==================================

Additionally, gbata adds the following patch between Block 1 and 2:

480C ldr r0,=#0xE000001
F005F999 bl #0x81E3C2C --> branch to label???? ==> PATCH: 00000000
0600 lsl r0,r0,#0x18
0C04 lsr r4,r0,#0x10
20E0 mov r0,#0xE0
0500 lsl r0,r0,#0x14
F005F993 bl #0x81E3C2C --> branch to label???? ==> PATCH: 00000000

Is there anybody who can explain to me why this last patch could be needed? It may have something to do with the chip identification, but I'm not sure about this.

Regards,

bbsan
 
Last edited by bbsan2k,

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,321
Country
United Kingdom
Interesting info. Not sure how many people will particularly make use of it (we have reasonably cheap flash carts and repros are not cool) but we have seen discussions on these in the past and I am the last person to say don't fiddle with things.

I am curious about it loading parts of the ROM into SRAM though. I could see it doing it to seed the real time clock or something like that, and I could see it doing it to bypass a valid save needs to be present check but I have not seen pokemon (or any GBA game) have such a requirement. Being pokemon there is no need to be nice to your users and give them a fully unlocked save or something similar. It could be a quasi form of anti piracy or something a ROM hacker did to prevent some measure of ripping or fiddling.

As far as GBATA patches while we figured out the format of GBA patches in the past it was most just to replicate them in other games or for other tools (other batch patching stuff), never particularly looked into their specifics though. I am too out of it right now to be thinking about in depth hacking but I would note you have a large chunk of the list from http://problemkaputt.de/gbatek.htm#gbacartbackupflashrom in the above bits so maybe something out of the rest.
 

bbsan2k

Well-Known Member
OP
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,444
Country
Germany
Thanks for your comment

The ROM --> SRAM loading is basically done to be able to save without battery. Over all the behavior of those roms is as follows:
During Boot:
Load ROM Area to SRAM

During Save:
Save to SRAM --> Copy SRAM back into ROM area and do some voodoo calls to persist.

However:
After a bit of fiddling here and there, I came to the following workflow:

1. Apply GBATA SRAM patch as normal

2. Search for Bank switching pattern in a Hex Editor. For FLASH1M_V103 the pattern is:
Code:
054B 8021 0902 0922 1206 9F44 1180 0349 C302 C918 1180 7047

3. Replace it with pattern:
Code:
054B 8021 0902 0922 1206 9F44 9021 0905 0000 0000 0870 7047


Obviously this is different for different FLASH types. I will try to create some automatic patching script in python or C this weekend that should cover other FLASH1M versions as well.


----
Technical explanation:

For some reason, GBATA SRAM patching does some "voodoo" bank switching that does apparently not work on real cartridges.
To make it work, I removed the "voodoo" parts and simply say:
Write $BANKNUMBER to 0x9000000

And that's it
 

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,321
Country
United Kingdom
Save backup and restore akin to the SMS feature of EZ1/EZ2 carts. Interesting twist, more than I expected from repros too.
 

JahBrask1947

New Member
Newbie
Joined
Jan 15, 2021
Messages
2
Trophies
0
Age
25
XP
51
Country
United States
2. Search for Bank switching pattern in a Hex Editor. For FLASH1M_V103 the pattern is:
Code:
054B 8021 0902 0922 1206 9F44 1180 0349 C302 C918 1180 7047

3. Replace it with pattern:
Code:
054B 8021 0902 0922 1206 9F44 9021 0905 0000 0000 0870 7047
How would i find the code in hex editior? im a bit new to using hex editor
 
Last edited by JahBrask1947,

bbsan2k

Well-Known Member
OP
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,444
Country
Germany
You need to make sure you are actually searching in hex- and not in the „interpreted“ part.

unfortunately I’m not using HxD since I’m on a Mac. If you just want to patch a game for SRAM 1M you can simply use my patcher tool!
 

Nix_Lon

Well-Known Member
Newcomer
Joined
Feb 17, 2020
Messages
52
Trophies
0
Age
22
XP
182
Country
Philippines
Pardon my ignorance but does this patch produce batteryless saves for Gen 3 Pokemon and any FLASH1Mb game or is this a workaround to make FLASH1Mb games save properly on SRAM w/ battery bootlegs?

Do I need to use this patch for FLASH1Mb games with an SRAM battery?
 

bbsan2k

Well-Known Member
OP
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,444
Country
Germany
Pardon my ignorance but does this patch produce batteryless saves for Gen 3 Pokemon and any FLASH1Mb game or is this a workaround to make FLASH1Mb games save properly on SRAM w/ battery bootlegs?

Do I need to use this patch for FLASH1Mb games with an SRAM battery?

This patches ROMs for SRAM Saves, so you need a battery in your cartridge.
Patching for batteryless is a lot more difficult, as it involves emulating the flash commands. Theoretically a patcher is possible, also I currently don’t have the time for writing one.
 

fexean

Member
Newcomer
Joined
Mar 2, 2021
Messages
8
Trophies
0
Age
26
XP
117
Country
Finland
This patches ROMs for SRAM Saves, so you need a battery in your cartridge.
Patching for batteryless is a lot more difficult, as it involves emulating the flash commands. Theoretically a patcher is possible, also I currently don’t have the time for writing one.
How would you implement a batteryless save patcher?
In the bootlegs I've seen, the flashing code is inserted into the game's own save functions which are different for each game.
 

bbsan2k

Well-Known Member
OP
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,444
Country
Germany
A while ago I reverse engineered the way the batteryless save patches work in a Pokémon mod...

There are essentially three things that need to be done:

1. Find an empty ROM area that is big enough to store the save + some additional code
2. Both steps required:
a)Write a function that reads all data from SRAM and writes that to the specific ROM area from 1) with the magic commands found in a reverse engineered ROM for that cartridge type.
b) Write a function that reads all data from the specific ROM area from 1) and writes it to SRAM
3. Patch the ROM so the entry point in the ROM header points to the Code from 2b). Patch all save calls to store in SRAM and then jump to the code in 2a).

While doing this for individual ROMs might be quiet an „easy“ task, injecting it dynamically is a lot more difficult, as you always need to make sure to be able to use the generated offsets in step 3).
The cool thing is: Functions 2a and 2b could theoretically be written without knowing their exact offset, as the code itself can be loaded into WRAM first and executed from there.

Although I still like the idea of looking into this further, I think the SRAM patch is already enough for my personal collection...
 

chunll

New Member
Newbie
Joined
Oct 1, 2022
Messages
2
Trophies
0
Age
34
Location
chin
XP
52
Country
China
Thanks for sharing. Want to know if there is a way to backup 1m sram save?
I use the1MFLash sram patch(my bootleg cartridge is not the ones mentioned in yout project, donot know if it works), and I use gba backup tool to dump save. It gots a 1M file. But the first 512k seems just the same of the last 512k of dump file. Seems not working correct? The game is super mario advance 4.
 

metroid maniac

An idiot with an opinion
Member
Joined
May 16, 2009
Messages
2,086
Trophies
2
XP
2,632
Country
Thanks for sharing. Want to know if there is a way to backup 1m sram save?
I use the1MFLash sram patch(my bootleg cartridge is not the ones mentioned in yout project, donot know if it works), and I use gba backup tool to dump save. It gots a 1M file. But the first 512k seems just the same of the last 512k of dump file. Seems not working correct? The game is super mario advance 4.
GBA backup tool doesn't understand anything about bootleg cartridges. It will try to dump save files according to the save chip the original game has, not what's actually present in the cartridge.
Flash and SRAM share the same address space, so reading flash is the same as reading SRAM. But switching banks on flash requires a write to address 0x0E005555 which means that offset in SRAM will be trashed if the cart actually uses SRAM.
You should check the save you dumped - if the values at 0x5555 and 0x15555 are different, or if they're known command values like B0 or F0, GBA backup tool probably corrupted it.
 

chunll

New Member
Newbie
Joined
Oct 1, 2022
Messages
2
Trophies
0
Age
34
Location
chin
XP
52
Country
China
cundang.png

thanks. And I check the file, both of them are B0.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Veho @ Veho: https://www.keepretro.com/products/miyoo-a30