What's new

mathieulh

Enthusiast
Joined
Jun 17, 2020
Messages
138
Reaction score
249
Location
France
PROOF OF CONCEPT, NAOMI1 MULTI BIOSES.


*DISCLAIMER* This was done as a proof of concept, I advise you to run the latest multi bioses I released earlier (the naomi1 version is present in this archive as "epr-21576h_multi.ic27_proper")

These are multiple revisions of the naomi1 BIOSes patched with the multi region enabled and using a proper bootstrap (not the one from the HOTD2 beta/DEV HAT used to bypass the HOLLY checksum)
This includes the following BIOSes:

NAOMI:

epr-21576e
epr-21576g
epr-21576h


All the naomi bioses present in this archive have been tested on real hardware, they should fix the compatibility
issues introduced by the original multibios.

Older revisions in this archive are just there for completeness' sake as a proof of concept.

As a reminder these are the tested available DIPSW configurations

DSW2 DSW3 DSW4

OFF OFF OFF Japan
ON OFF OFF USA
OFF ON OFF Export
ON ON OFF Korea
OFF OFF ON Australia


What is the "Redundant" folder? It contains a parity fixed versions of the epr-21576h multi bios.
because parity didn't need to be changed in the first place for this bios to run (it ran at first try during tests), you don't actually need to use it,
they are there for completeness's sake and educational purposes, they will behave exactly the same as the BIOSes which have not been parity fixed.




- How was it made?

Aside from the patches themselves, originally discovered by MetalliC, which reenable some leftover development feature made by SEGA allowing for easy region changes with DIPSW,

HOLLY, the Power VR GPU used by many SEGA systems (Dreamcast, NAOMI, Atomiswave...) acts as a gatekeeper to the G1 BUS
(which on NAOMI, your cart/dimm sits on top of), in order for the G1 bus to be unlocked the BIOS sends itself to HOLLY.
HOLLY will then perform some unknown check on the whole data and if it doesn't like what it sees, it will keep G1 locked and set
a register that can only be cleared at reboot (so that G1 remains locked if the check failed once until next power cycle)
so far the algorithm is unknown though it's been weak enough that, if you get lucky, the check still passes depending on the changes you make (you get a successful collision)
such is what happened with epr-23605c and epr-21576h which passed at first try due to some extreme luck.

SEGA during development uses an IPL that is internally referenced as KABUTO (old Japanese word for HAT (or headpiece)), this piece of code is already properly hashed for HOLLY and will (among other things), send itself to HOLLY and eventually
runs the bra 0xa0000420 instructuion to jump to the rest of the BIOS data, this made it very convenient as the HAT is only 0x400 in size and allowed to edit the rest of the bios with HOLLY being nonethewiser.
This however caused issues both in terms of timing and initialization, I therefore attempted to replace the first 0x400 used by the Development HAT back by the proper BIOS data, while this worked without issues for the latest BIOSes it unofortunaly did
not pass the HOLLY check during testing for others such as epr-21576g.

After attempting to set bits at random and getting somewat unlucky (about a dozen unsucessful tries), I knew I had to take a better, more scientific approach, so I started looking at how
the sum was performed if any, after looking at what I assumed were inverted bytes set by SEGA at 0x1FFFFA in the NAOMI BIOS, especially comparing the same revision across regions, I realized they were anything but, as it seemed some equalisation was going on.
Sadly while I somewhat guessed what some of the bytes were calculated, I could not regenerate the whole 6 bytes (I am still working on that).

Eventually I started talking to Japanese_cake (author of the Dreamcast dev bioses) who has had some amount of success in having small modifications pass the check, he eventually suggested that I look at his latest bios 1.032 and compare the HAT he repurposed from the NAOMI DEV one with the DEV HAT itself.
where he had to replace the bra 0xa0000420 to bra 0xa0000518, in order to do that he had to tweak another byte to 0x31, that's when everything started to make sense, in order to do this he had to change one byte from 0x8C to 0x10, this means adding 0x7C from the orginal value, the other byte that was modified,
located exactly at 0x200, exactly 4 bytes later contained the equalized value, that is 0xAD (the original value) - 0x7C (the amount of bytes added 4 bytes earlier), it actually made sense how collisions were possible in the first place and how you can modify any data without modifying the expected parity by balancing values.

From this (and more tests) the following was concluded:

- Parity is checked in blocks of 4 bytes
- There is more than just balancing the value of the entire blob, if you equalize too far from the original modification (I don't know how far yet), the check will not pass, I assume it eventually performs some internal modulus and generates parity for groups of several 4 bytes chunks.
- You do not have to equalize at a neighbouring 4 bytes block, that is you don't need to use the exact previous or next block to equalize the parity, instead you can go further, increading the usability of this flaw, as if you have a whole bunch of nops (0x0900) closeby or useless strings near the patched instruction you can reuse these to equalize parity without breaking anything.
- The less bytes you change (and thus need to equalize), the more likely the parity check will pass.

Using this somewhat ugly hack, you can pass the HOLLY check with very high reliability (close to 100%?) if you don't stem too far from the initially patched values).

I would like to fully figure out the algorithm at some point, I am confident that it is simple enough to discover mathematically given enough samples, using DPA would also give it away so that's a venue I consider exploring.



- Mathieulh

Credits go to the following people

@MetalliC /p1pkin for providing the original multi region patches in his multi bios and discovering the hidden code by SEGA.
@mathieulh for porting the multi region patches to other BIOS versions and generating versions that work on original hardware, as well as some initial work into figuring out how HOLLY parity works.
@jc_dcdev (Japanese Cake) for sharing his own research on the HOLLY checksum and giving me very useful insight as to what to look for.



https://mega.nz/file/xp1CwKpI#eEm8k6yMC8Ymg7X0O3cLqLhkOyfkDJHobVUBsjC5z7s
 
good work. have few things to add

Parity is checked in blocks of 4 bytes
BIOS chip have 8 bit data bus, so data read and checked byte by byte, not in 32 bit blocks, but algo itself shows some 4-byte circularity, and the sum possible are 32 bit value.
you may see more test results and observed patterns there - http://www.dc-swat.ru/forum/thread-2150.html
especially at last 3-4 pages of the topic.

as of credits - all the cool things started back in 2014 https://forum.emu-russia.net/viewtopic.php?p=23024#p23024
when I discovered how this protection works in general and found it is possible to reuse part of HOD2 proto BIOS (dumped by farzeno), and created "unprotected" BIOSes for NAOMI, Dreamcast and SystemSP.
later together with @rtw and megavolt85 (one of DreamShell devs) we discovered more things like protection status register, restart behavior etc, and documented in MAME sources.

to my knowledge other folks like japanese-cake just used our findings it theirs projects and haven't done real research by himself...
 
Last edited:
good work. have few things to add

Parity is checked in blocks of 4 bytes
BIOS chip have 8 bit data bus, so data read and checked byte by byte, not in 32 bit blocks, but algo itself shows some 4-byte circularity, and the sum possible are 32 bit value.you may see more test results and observed patterns there - http://www.dc-swat.ru/forum/thread-2150.html
especially at last 3-4 pages of the topic.

as of credits - all the cool things started back in 2014 https://forum.emu-russia.net/viewtopic.php?p=23024#p23024
when I discovered how this protection works in general and found it is possible to reuse part of HOD2 proto BIOS (dumped by farzeno), and created "unprotected" BIOSes for NAOMI, Dreamcast and SystemSP.
later together with @rtw and megavolt85 (one of DreamShell devs) we discovered more things like protection status register, restart behavior etc, and documented in MAME sources.

to my knowledge other folks like japanese-cake just used our findings it theirs projects and haven't done real research by himself...
That's great! I actually didn't know about that dc-swat thread it's helpful! :)
 
Back
Top