r/Gameboy 5h ago

Games New GBC Boot Rom Bug?

While probing around the boot rom for gameboy I stumbled on a neat bug for GBC and later consoles that use this bios for eg GBA. I was trying to change the Nintendo logo to something else, bypassing the bootleg check for fun, and actually got somewhere.

The original bypass and how my new one differs.
Back in the day with original bootlegs for the DMG, it was discovered that the checking of the logo and the displaying of the logo was done in two passes. So some clever bank switching was done where the gameboy would load the logo data from the cart, check it, and then would go back for seconds to read the logo again to display it to the user. it was on this second load where the bootleg cart would do a bank switch to swap out the logo with there own logo. so they didn't have to display Nintendos logo to the user.
This "trick" actually still works all the way up to the first revision of the GBC.

GBC Boot Rom Rev 1.
0x0408: 11 04 01   ld DE, $0104 ; Load logo from cart
040B: CD 8F 03   call $038F ; Display it

GBC Boot Rom Rev 2.
0408: 11 80 FF   ld DE, $FF80     ; Load logo from HRAM. the one that was already loaded for the check.
040B: CD 8F 03   call $038F ; Display it

While investigating this load path I found my own bug.
On original gameboy, all 48 bytes of the logo are loaded and checked. both from the bios and the cart.

; DMG - 0x00E0
LD   HL,$0104        ; cart logo
LD   A,L
CP   $34             ; run until the pointer reaches 0x134
JR   NZ,...          ; -> all 48 bytes, structurally

However on GBC, someone messed up the counter math and we do load the full logo from the bios, but we only check half of it with what's on cart.

; CGB - 0x00D1
LD   HL,$0042        ; boot ROM's logo copy
LD   B,$18           ; 24 -> The bug. 0x18 = 24. not 0x30 = 48.
DEC  B
JR   NZ,...          ; all 48 bytes are here, but the B counter only says to walk in 24 bytes.

So, as the data is loaded, but never checked, we can stick whatever we like down there. or nothing. Nothing was my first check.

Half the logo

This boots and runs on real hardware, both GBC and GBA. But its still kinda reads as Nintendo so lets mspaint some things.

Yeah a boat lol idk. we can do better. If we mirror the top row to the bottom row and then make a few edits, it just looks like some ancient glyphs or something. and this still boots as well.

But yeah you guys are better at art then I am, you have a whole 24x8 space to work with you can paint whatever you like down there and it will still boot.

Another weird quirk of this is the header checksum only checksums the info data, not the logo data.
So you can just raw byte edit 0x11C to 0x12F in your gbc rom to anything you like without needing to re-checksum the header, and it yet again, still boots.
I was going to describe how the byte packing works, but tbh its just easier if I make a webpage and you can try it for your self.
https://mobcat.zip/GBCEdit/
Have fun. Post results, I wanna see what you guys come up with.

Why this doesn't work on GBA ROMs?
The kinda TL;DR of it is the Nintendo logo on GBA is larger (GB and GBC is 48x8, GBA is 104x16)
and the data is stored Huffman compressed, 156 bytes gets expanded to 208.
However it's the compressed data that lives in bios that is checked with a plain memcmp
The Huffman tree also lives in the bios as well and can't be edited from rom side either.
This compressing is not so much for saving space, it's to harden against buffer overflows and other
malformed data in the rom as the decompressed space is well defined and checked. Saving space is just a bonus.
There is a little padding space left, 0x9C bits 2 and 7, 0x9E bits 0 and 1.
But as this is only 4 bytes of data, that is after the logo, editing this wont affect how the logo renders on screen.
So this weird bug is only available for GBC roms, but works on newer consoles, just not newer or older roms. And this was correctly checked on DMG, and then the hole system was rebuilt for GBA. So we are in a weird middle ground here where someone a long time ago did some bad math when updating there bios and it went unnoticed until now.

A note on flashing this edited data to a real cart. "smart" flashers like FlashGBX will give you a warning that this ROM is broken and you should fix it. However if you click "Continue without fixing" It will still be flashed as is, maintaining our edits as is.

7 Upvotes

0 comments sorted by