Created
August 24, 2024 21:04
-
-
Save profi200/c7fef99003fa5d07235d97296da23db3 to your computer and use it in GitHub Desktop.
GBA BIOS dumper abusing open bus behavior.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ License: Do whatever you want. | |
.syntax unified | |
.cpu arm7tdmi | |
.fpu softvfp | |
@ Based on https://web.archive.org/web/20240111232601/https://gist.github.com/merryhime/797c523724e2dc02ada86a1cfadea3ee | |
@ Thanks to merryhime for discovering this trick. | |
@ void dumpBios(void) | |
.section .iwram.dumpBios, "ax", %progbits | |
.align 2 | |
.thumb | |
.global dumpBios | |
.type dumpBios, %function | |
.func dumpBios | |
.cfi_sections .debug_frame | |
.cfi_startproc | |
dumpBios: | |
push {r4-r7} | |
movs r0, #0 | |
subs r0, r0, #3 @ 0xFFFFFFFD open bus jump. | |
movs r1, #0 @ BIOS address. | |
ldr r2, =dumpBios_return + 1 | |
movs r3, #0x0E | |
lsls r3, r3, #24 @ 0x0E000000 SRAM address. | |
@ Jump to open bus which contains the ldmia and bx instructions | |
@ that got prefetched by the CPU previously. | |
@ Because the CPU will prefetch 2 instructions ahead it will | |
@ fetch from address 0 which unlocks the BIOS for reading. | |
dumpBios_lp: | |
bx r0 @ Must be at an address with bit 1 set. | |
ldmia r1!, {r4-r7} @ Executed from open bus. | |
bx r2 @ Executed from open bus. | |
@ Write data to SRAM. | |
dumpBios_return: | |
strb r4, [r3, #0] | |
lsrs r4, r4, #8 | |
strb r4, [r3, #1] | |
lsrs r4, r4, #8 | |
strb r4, [r3, #2] | |
lsrs r4, r4, #8 | |
strb r4, [r3, #3] | |
strb r5, [r3, #4] | |
lsrs r5, r5, #8 | |
strb r5, [r3, #5] | |
lsrs r5, r5, #8 | |
strb r5, [r3, #6] | |
lsrs r5, r5, #8 | |
strb r5, [r3, #7] | |
strb r6, [r3, #8] | |
lsrs r6, r6, #8 | |
strb r6, [r3, #9] | |
lsrs r6, r6, #8 | |
strb r6, [r3, #10] | |
lsrs r6, r6, #8 | |
strb r6, [r3, #11] | |
strb r7, [r3, #12] | |
lsrs r7, r7, #8 | |
strb r7, [r3, #13] | |
lsrs r7, r7, #8 | |
strb r7, [r3, #14] | |
lsrs r7, r7, #8 | |
strb r7, [r3, #15] | |
@ Increment SRAM pointer. | |
@ Check if bit 14 of BIOS address is set. If yes we read 16 KiB. | |
adds r3, r3, #16 | |
lsrs r4, r1, #14 | |
beq dumpBios_lp | |
pop {r4-r7} | |
bx lr | |
.cfi_endproc | |
.endfunc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// License: Do whatever you want. | |
#include <gba_console.h> | |
#include <gba_interrupt.h> | |
#include <gba_systemcalls.h> | |
#include <stdio.h> | |
__attribute__((aligned(4))) | |
const char saveTypeStr[] = "SRAM_V123"; | |
void dumpBios(void); | |
int main(void) | |
{ | |
irqInit(); | |
irqEnable(IRQ_VBLANK); | |
consoleDemoInit(); | |
// Don't optimize out my save type string plox. | |
if(REG_IME == 0) puts(saveTypeStr); | |
REG_IME = 0; | |
dumpBios(); | |
puts("BIOS dumped. Turn the system off and check the save file."); | |
REG_IME = 1; | |
while(1) VBlankIntrWait(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment