Discussion in 'Sega Saturn Programming and Development' started by jhl, Jun 30, 2014.
The SH1 ROM checks 512kB with random data when you run the Authenticate MPEG Card command. If it doesn't pass, it won't boot the card ROM. Guess it's another security measure - you can't just plop a ROM chip in the slot and run a nice little modchip program.
55 is selector-related and will set ESEL.
It takes a filter number in CR3 high, and a sector number within the selector in CR2 low. CR2=FFFF will use the last sector in the buffer. The specified sector must exist in the buffer.
A FAD is provided in CR3:CR4. It then appears to seek through the buffer from that point, looking at the first 4 bytes of each sector (where a Mode1 MSF:mode header lives), until it finds the requested FAD's MSF.
56 gets the response from 55. There are three outcomes.
On error, CR2=CR3=CR4=FFFF, except for the filter number in CR3 high.
If exactly matching MSF found, returns the FAD in CR3:CR4 and the buffer sector number in CR2.
If an exact match was not found, returns the latest FAD and sector number.
If no sectors at all were found, returns FFFF for the sector number.
Anyway, that's how the code reads, I'd be interested to hear if I'm actually right
While on the topic of documentation, the Hardware Flags from Get Hardware Info are:
0x80 - LSI or DRAM tests failed at startup
0x02 - MPEG card is present (reading a chip register succeeded and the IRQ lines toggle)
0x01 - there is a stubbed-out test in CDB105 which never sets this bit
A little status update on my project. I spent 21 hours on a plane beating on code; now I have an emulator that boots the CDB105 ROM, emulating the CDB CPU. You can issue commands to it, and it even authenticates an emulated Saturn disc (wobble and ring). I'm planning to use that to develop the SH-1 hooking portion of the emulation device.
As far as hardware goes, I just sent off the prototype PCB for fab. It has a micro SD slot and a USB OTG mini AB connector; we'll see what sticks when I get further with the firmware.
Now I'm going to not do this for a while - the plane trip has brought me home and I have a hellish workload for the next 6 months. The PCB will be in in a few weeks, though...
Thanks for the project update, jhl. Take as much time as you need.
Amazing work there jhl
After 21 hours of anything I imagine you need a break. Looking forward to when you work on it again.
Pretty much right on. And in a screwy twist, apparently those functions were documented, just not on the Yabause wiki. And to boot I ended up forgetting about them. Proper names are "Execute FAD Search" and "Get FAD Search Results". I've updated the wiki with the correct info.
It pleases me greatly to tell that the analysis of this dump has already borne some fruit, allowing one of the Saturn's security expectations to be gently violated.
The assumption in question is that burned Saturn discs - ie. those beginning with SEGA SEGASATURN, but missing the ring wobble or ring data - will be detected as fakes (type 3), and access to their data disallowed. This prevents any SH-2 code - BIOS or cartridge - from booting such a disc.
Using a combination of static analysis of the binary, and tests in my CDB emulator (which is getting quite decent), it's been possible to find a sequence of commands which tricks the CDB into authenticating such a disc as a data disc (type 2). In this case, access to the whole disc is permitted, although the stock Saturn BIOS will still not try and boot it as it's not seen as a Saturn disc (type 4).
This means that it will be possible for Cyber Warrior X's Pseudo Saturn to boot burned discs without needing them to be patched first. It would also be possible for a sufficiently motivated person to build the attack into a modified BIOS (presumably in conjunction with the region mods which are already deployed in this way), essentially embedding the core idea (booting type2 discs) of Pseudo Saturn.
A description of the attack follows, for the sake of public documentation (sorry, I'm slack about documenting things). For details of how the CDB interfaces with the Saturn please see CWX's docs here:
The CDB runs a multi-tasking operating system. Each task has a priority determining who gets to run when. There are also mutexes, used to protect things like the selector/filter data structures, which are accessed from many tasks.
The CDB is notified of new commands by an interrupt. For simple/fast tasks, the interrupt handler directly calls the relevant code. For slower or more complicated tasks - which may run in the background - the handler instead sends off a message to wake a task to perform the action. Relevant here are tasks 4, 7, C, and D (they're numbered but not contiguously). During the execution of the authentication process, no commands at all are accepted; this limits the possible attack moves to things that can be performed before kicking off auth.
Task 7 is the critical one: filesystem ops and authentication. The former represents a lot of spaghetti code in the task but isn't relevant to us; the latter is what's critical. At the beginning of authentication, the TOC is checked to see if there's a first data track to consider (otherwise it's an audio CD). If so, the first sector is read and checked: if it's a Mode1 sector, the task continues on to read a bunch of sectors, looking for SEGA SEGASATURN - and the various other auth jobs, not relevant here. If Task 7 gets a non-Mode1 sector, it assumes it's a VCD or other data disc.
Looking more closely at how it gets that sector: it sets up one of the CDB selectors, filtering on FAD 150 (the first sector of a disc). It then stores the number of the next sector to be read into that selector's buffer - for example, if there are 10 sectors in the buffer, it will store the number of sector 11, where it'll expect to find this sector.
It then requests a read from FAD 150 through the CD mechanism task (task 6), and then looks at the position it stored in the buffer. Whatever's there determines how it will proceed. So, if you can somehow write arbitrary sectors into this selector in between the first part (where it stores the sector number) and the second part (where it reads the sector), you can cause it to see a sector that's not really on the disc - and miss the SEGA SEGASATURN header that may be there.
On to the other actors.
Task 4 performs selector-related tasks: commands 0x40, 42, 46, 42, 52, 55. A number of these are capable of modifying the sector count in a selector, but unfortunately, they're all pretty quick. Any attempt to start one of these before the auth process just results in it all happening either before or after the auth process: no good.
Task C is used for Saturn<->CDB DMA: commands 0x61, 62, 63, 64.. That's how the Saturn normally gets its data from the CD; it can also be used in the other direction, putting sectors from the Saturn into CDB selectors. This is really nifty, and higher priority than Task 7 - but unfortunately, it doesn't actually update the selectors until the transfer is done and you call command 0x06, and that executes immediately. So it's a piece of the puzzle but it's not useful for attack.
Our final friend appears in Task D: handling the somewhat mysterious Copy/Move Sector commands 0x65, 66. These don't seem to be used very often (if at all), but their purpose is simply to move or duplicate sectors from a selector into another. They're fully filtered on the way; for example, if you're copying sectors with FAD 149-151 into a selector with FAD 150 filtering active, only the 150 will get through. This has the rather nice property that it will keep running over the top of Task 7 when 7 sleeps waiting for the CD to read that critical first sector - so it's actually possible to write into the necessary sector before the CD drive returns with the real data.
So, putting it all together, the attack is as follows:
1. Use the Put Sector Data command to put a whole bunch of sectors into the CDB - all with FAD 150, Mode 2 in their headers.
2. Call End Data Transfer to push them into the selector.
3. Call Copy Sector Data, starting a copy of all those fake sectors into the selector that the Authenticate Disc command will be using.
4. Immediately (like 15 microseconds later immediately) call the Authenticate Disc command, specifying the same selector.
The authentication process sees the fake sectors, decides it's a data disc, unlocks read access, and returns Type 2 - data disc. VoilÃ¡!
Technically the process looks very similar to that just described:
- set sector size to 2352
cmd: 0x6003, 0x0300, 0x0000, 0x0000
- write 150 sectors into selector 1
cmd: 0x6400, 0x0000, 0x0100, 0x0096
Then write 150 x 2352 bytes to the transfer register -
content is unimportant, except at offset 12 in each sector, you must
have the sequence:
00 02 00 02
as in, MSF 00:02:00, Mode 2 header
- end the transfer
cmd: 0x0600, 0x0000, 0x0000, 0x0000
- start a sector copy to seltr 0, but not enough secs to overflow the
buffer space available
cmd: 0x6600, 0x0000, 0x0100, 0x0032
- immediately begin auth with seltr 0 (wait for HIRQ_CMOK or about 15
microseconds so that the copy command is accepted)
cmd: 0xe000, 0x0000, 0x0000, 0x0000
- Wait for HIRQ_EFLS and HIRQ_ECPY, then clear the buffer and go back to business.
The attack has now been tested on real hardware, with many thanks to CWX; expect some news in the Pseudo Saturn thread in due course.
How to exploit race conditions for fun and profit (well, maybe not profit, now...).
Another very nice piece of work - and to think I had concluded that there was nothing interesting left to find out about the Saturn.
I didn't see any link for the rom in this post (but it's maybe against the rules), so is the rom have been released ?
As it's reverse engineering research on an old system, I'm pretty sure it'd be allowed by the rules on the same basis modified bioses are.
Good job jhl and CWX!
The link points to "here" which browsers redirect to www.here.com...
I'm assuming jhl's referring to http://wiki.yabause.org/index.php5?title=CDBlock
Also, I just want to clarify that this new exploit was the result jhl's hard work. I mainly just implemented his proposed exploit in the Pseudo Saturn boot loader to verify whether it worked in practice with a couple small refinements.
Edit: Exploit will be included in the next release of Pseudo Saturn. No release date is set. I still have some bugs and code cleanups that need to be done first.
That's fantastic that you don't even need to patch the CD-Rs with this attack. It'll be a convenient improvement to PsuedoSaturn for sure.
Great work. Maybe there will be even more learned through this CD Block ROM analysis.
Well done & thank you to both you and jhl then and looking forward to the new release
Also will Pseudo patched discs still be working or will that be dropped?
So far all the multi disc games I have looked at don't let you change discs mid game anyway as the console resets as soon as you hit eject anyway but instead creates save data automatically to be loaded by the next disc
I need to get more CD-R's to do any more testing though I used a full 100 CD-R spindle up with my last test run, settled into enjoying Shining Force III for a bit for now so not in a great rush for anything anyway
EDIT: oops jumped threads :/
Can't wait for this!
Amazing piece of work!
Is the Action Replay cartridge, a must have in, order to make this work?
(Because, then I will order it now)
Separate names with a comma.