DragonMinded
Professional
Okay so there's definitely more to the header "protection" than just a simple CRC/hash. It is running a hash over the first 0x500 bytes of the header, using a PRNG with the equation NewRNG = (OldRNG * 41C64E6D) + 3039. My google-fu failed me as I couldn't find any algorithms outside of people reverse-engineering pokemon (lol same PRNG there as here). However, simply bypassing the failure condition altogether causes the game to never load settings from the EEPROM at all, and when it freezes it is stuck in an infinite loop of reading the EEPROM. So I am not entirely sure they meant this to be protection so much as they used a hash of the header to see if they should read the settings, and then store a copy of that header and compare against that in the future for speed reasons. This is done as a rolling hash, calculating one position per loop as a background thread. The fix is to make the function that returns the current position always return 0. That way, it only ever hashes over the first byte of the header, but it notices that's different on the first iteration and does load the EEPROM. I've tested this bypass using the settings trojan on both Jambo Safari and Crazy Taxi and both are happy with the changed EEPROM as well as no longer freeze in the attract sequence.
This also explains why changing the free-play portion of the ROM header caused it to crash earlier in the attract than adding an EXE section for the trojan. Anyway, case closed, I don't have to add a compatibility mode to any of my tools, thank GOD. Instead I checked in a pair of patches for CT/JS that disables the "protection" properly so they still load settings but don't crash on header modifications. The only thing you can't modify is the initial "N" in the first byte, but you couldn't modify that anyway as it would then fail the NAOMI ROM check in the BIOS. Good call, @rtw you saved me a ton of time implementing unnecessary crap.
Anyway, if anyone else runs into games that freeze in the attract when applying settings, post them here. The patch should be relatively easy to locate for any game that uses this style of "protection". You just look for references to the constant "0x0C020000" in the code, find the section that compares an offset into that constant against another location, and gets that offset from some function. Then you patch the call to the location gathering function to instead set r0 to "0" and then nop the next instruction (branch delay register setup for the function call). Its as easy as that. But if people run into more games like this and they want settings working, I can probably jump in and fix the problem pretty fast.
This also explains why changing the free-play portion of the ROM header caused it to crash earlier in the attract than adding an EXE section for the trojan. Anyway, case closed, I don't have to add a compatibility mode to any of my tools, thank GOD. Instead I checked in a pair of patches for CT/JS that disables the "protection" properly so they still load settings but don't crash on header modifications. The only thing you can't modify is the initial "N" in the first byte, but you couldn't modify that anyway as it would then fail the NAOMI ROM check in the BIOS. Good call, @rtw you saved me a ton of time implementing unnecessary crap.
Anyway, if anyone else runs into games that freeze in the attract when applying settings, post them here. The patch should be relatively easy to locate for any game that uses this style of "protection". You just look for references to the constant "0x0C020000" in the code, find the section that compares an offset into that constant against another location, and gets that offset from some function. Then you patch the call to the location gathering function to instead set r0 to "0" and then nop the next instruction (branch delay register setup for the function call). Its as easy as that. But if people run into more games like this and they want settings working, I can probably jump in and fix the problem pretty fast.