-
Notifications
You must be signed in to change notification settings - Fork 2
How It Works
SataDiskInitialize (0x8015DB18 on retail 17559) does two separate things, in this order:
Before the authentication gate, it creates all twelve hard disk device objects by calling
SataDiskCreateDevice → IoCreateDevice:
PhysicalDisk Partition0 Partition1 Cache0 Cache1 DumpPartition
SystemPartition WindowsPartition TitleURLCachePartition
SystemURLCachePartition SystemExtPartition SystemAuxPartition
After the gate, a second block (0x8015DF28–0x8015E0D0) fills in each device's
PartitionInformation and clears DO_DEVICE_INITIALIZING on it.
The gate itself:
8015DEE4 bl 0x8015D9D8 ; SataDiskAuthenticateDevice
8015DEE8 cmplwi r3, 0
8015DEEC bne 0x8015DF28 ; authenticated -> go finish the partitions
; not authenticated: three escape hatches
8015DEF0 lis r11, 0x8E04 ; hardware registers
8015DEF4 lhz r10, 0x860A(r11)
8015DEF8 rlwinm. r10, r10, 0,29,29
8015DEFC beq 0x8015DF0C
8015DF00 lhz r11, 0x8608(r11)
8015DF04 rlwinm. r11, r11, 0,29,29
8015DF08 bne 0x8015DF28 ; -> finish the partitions
8015DF0C addi r3, r1, 0x5C
8015DF10 bl 0x80108E40 ; XeKeysGetStatus(&status)
8015DF14 lwz r11, 0x5C(r1)
8015DF18 rlwinm. r10, r11, 0,28,28 ; bit 0x8
8015DF1C bne 0x8015DF28 ; -> finish the partitions
8015DF20 rlwinm. r11, r11, 0,13,13 ; bit 0x40000
8015DF24 beq 0x8015E10C ; not a devkit -> SKIP the whole block
8015DF28 <partition initialisation>That 0x40000 is the same bit Bad Storage already checks to tell a devkit from a retail console.
In other words, devkits create their partitions without needing authentication at all — which
is exactly why they accept any drive.
On a retail console with an unauthenticated disk, the branch at 0x8015DF24 is taken and the
entire initialisation block is skipped. The device objects survive, but with:
-
PartitionInformationall zeros, and -
DO_DEVICE_INITIALIZINGstill set.
PhysicalDisk is the one exception: it is completed before the gate, which is why it keeps working
and reports the correct disk size even on a disk that failed authentication.
The instinct is to patch SataDiskAuthenticateDevice to return TRUE so the gate is taken. That
does not work, and it is worth being precise about why:
- The gate is evaluated once, early in boot, long before any exploit payload can run.
- There is no warm reboot that keeps patches in memory. Any reset reloads the hypervisor and kernel clean from NAND. Hot-swapping the drive triggers the boot animation and loses the exploit.
- XeUnshackle already applies that exact patch as part of its Freeboot set. Reading the bytes at
0x8015D9D8before writing anything shows38600001 4E800020already in place — and the disk still does not mount.
So the authentication result is not something that can be changed after the fact. It has already been consumed.
It finishes the work the gate skipped:
-
Reach the device objects. They cannot be looked up by name — that is the whole symptom — so
walk the
\Device\Harddisk0object directory instead. - Write each partition's geometry into its device extension.
-
Clear
DO_DEVICE_INITIALIZING. This is the kernel's own final step; its instruction isrlwinm rX, rX, 0, 28, 26, a wrapped mask whose only effect is to clear bit0x10. -
Announce the disk with
XContentDeviceProcessAddRemove(ADD)andBroadcastStorageDevicesChanged.
None of the values written are invented. They are what the kernel's own post-gate block computes, recovered by disassembling it instruction by instruction.
The failing lookups returned 0xC000000E — STATUS_NO_SUCH_DEVICE, not 0xC0000034
STATUS_OBJECT_NAME_NOT_FOUND.
That distinction is the whole diagnosis. The name resolves fine; it is the device that is
refused. A device object with DO_DEVICE_INITIALIZING set is exactly what produces that status.
Missing this cost several rounds of chasing a device that was never actually missing.