Black-box GBA BIOS dumper
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Luna Catkins ca0a62de4a
Fix ROM name, add README
3 weeks ago
src initial commit 3 weeks ago
.gitignore initial commit 3 weeks ago
LICENSE initial commit 3 weeks ago
Makefile Fix ROM name, add README 3 weeks ago
README.md Fix ROM name, add README 3 weeks ago

README.md

GBA Bios Dumper

This repository contains proof-of-concept code for dumping the Game Boy Advance's "BIOS" ROM, using a modified version of MerryMage's prefetch exploit.

Note about NDS, 3DS, etc

As the register used doesn't exist on DS or 3DS hardware, this exploit only works on the original GBA, GBA SP, or GBA Micro models.

You are of course free to try it anyway, but expect crashes.

If you would like a more mature dumper that is DS-compatible, use mgba-emu/bios-dump.

Explanation

The general idea is that reading from the ROM is disabled unless the CPU is currently executing instructions inside the ROM.

In practice this is achieved with the nOPC CPU signal and checking the address lines. Because the CPU fetches two instructions ahead of the one it is currently executing, instructions executed at FFFF:FFFCh are able to read the BIOS, because the CPU previously prefetched an instruction from address 0.

Exploiting this requires executing unmapped ("open bus") memory through the use of prefetch stuffing.

Register 0400:0800h

The GBA hardware contains an undocumented I/O register at address 0400:0800h.

Among other things, setting bit 0 of said register causes the address mapping of the BIOS ROM and WRAM to swap, changing the memory layout as such:

Address Block
0000:0000h External Work-RAM
0100:0000h Internal Work-RAM
0200:0000h BIOS ROM

This makes it trivial to use the same prefetch exploit to dump the BIOS, simply by placing code at the end of IWRAM, which is mirrored across the entire 01xx:xxxxh range.

Execution

The following ARM code is used:

01FF:FFF8h ldr r0, [r0] <- executed
01FF:FFFCh bx  lr       <- decoded
0200:0000h (BIOS Code)  <- fetched (unlocks BIOS for reading)

Note that the entire execute, decode, fetch pipeline runs in parallel. So, we simply call the above function, passing the address we want to read, and dump the BIOS, one word at a time.

It would of course be possible to optimize this process, use ldmia, etc..

After that's done, all that's left is some housekeeping. Reset the register and stack. The contents of the BIOS ROM are written to SRAM. (Flash card users: if the file is too large, just truncate it.)

You can compare checksums and SHA256 hashes here.

License

All code in this repository is licensed under the MIT license. See LICENSE for more information.