Skip to content

Instantly share code, notes, and snippets.

@cf
Created March 17, 2026 13:05
Show Gist options
  • Select an option

  • Save cf/db8067bf770f85ad87e1be78dd97d6e0 to your computer and use it in GitHub Desktop.

Select an option

Save cf/db8067bf770f85ad87e1be78dd97d6e0 to your computer and use it in GitHub Desktop.
Xbox One Bootrom Ghidra Script
# Xbox One Bootrom - Ghidra Analysis Script
# Made With <3 by Carter Feldman (teh1337)
# Make sure to load at Base Addresss -> 0xFFFF0000
# =============================================
# Language: ARM:LE:32:v7 | Base: 0xFFFF0000 | Format: Raw Binary
#
# Run in Ghidra: Window -> Script Manager -> New Script -> Jython
#
# This script performs a full analysis of the Xbox One bootrom:
# - Sets ARM/Thumb mode regions
# - Labels ~90 functions with plate/EOL comments
# - Disassembles all code entry points
# - Creates custom enums and structs (/XboxOne category)
# - Sets ~70 function signatures with parameter types
# - Auto-applies named equates to all instructions & literal pools
# - Renames literal pool entries with pointer names
# - Adds internal labels and inline comments
# - Marks no-return functions
# - Applies NAND_ConfigEntry struct to data regions
from ghidra.program.model.symbol import SourceType
from ghidra.program.model.data import *
from ghidra.program.model.scalar import Scalar
from ghidra.program.model.lang import RegisterValue
from ghidra.app.cmd.disassemble import DisassembleCommand
from ghidra.program.model.listing import CodeUnit, ParameterImpl
from ghidra.app.cmd.function import CreateFunctionCmd
import ghidra.program.model.data.CategoryPath as CategoryPath
import ghidra.program.model.data.EnumDataType as EnumDataType
import ghidra.program.model.data.StructureDataType as StructureDataType
import ghidra.program.model.data.PointerDataType as PointerDataType
import java.math.BigInteger as BigInteger
# ============================================================================
# GLOBALS
# ============================================================================
program = currentProgram
dtm = program.getDataTypeManager()
fm = program.getFunctionManager()
listing = program.getListing()
mem = program.getMemory()
sym = program.getSymbolTable()
ctx = program.getProgramContext()
af = program.getAddressFactory()
space = af.getDefaultAddressSpace()
equateTable = program.getEquateTable()
# ============================================================================
# UTILITY FUNCTIONS
# ============================================================================
def addr(offset):
base = mem.getBlocks()[0].getStart().getOffset()
return space.getAddress(base + offset)
def set_tmode(start_offset, end_offset, mode):
s, e = addr(start_offset), addr(end_offset)
val = RegisterValue(ctx.getRegister("TMode"), BigInteger.valueOf(mode))
try:
ctx.setRegisterValue(s, e, val)
except:
listing.clearCodeUnits(s, e, False)
ctx.setRegisterValue(s, e, val)
def disas(offset):
DisassembleCommand(addr(offset), None, True).applyTo(program)
def lbl(offset, name):
sym.createLabel(addr(offset), name, SourceType.USER_DEFINED)
def cmt(offset, text):
cu = listing.getCodeUnitAt(addr(offset))
if cu:
cu.setComment(CodeUnit.PLATE_COMMENT, text)
def eol(offset, text):
cu = listing.getCodeUnitAt(addr(offset))
if cu:
cu.setComment(CodeUnit.EOL_COMMENT, text)
def ensure_func(offset):
a = addr(offset)
f = fm.getFunctionAt(a)
if f is None:
CreateFunctionCmd(a).applyTo(program)
f = fm.getFunctionAt(a)
return f
def set_sig(offset, ret_type, name, params):
func = ensure_func(offset)
if func is None:
return
try:
rt_map = {
"void": VoidDataType.dataType,
"int": IntegerDataType.dataType,
"uint": UnsignedIntegerDataType.dataType,
"bool": BooleanDataType.dataType,
"byte": ByteDataType.dataType,
"void *": PointerDataType(VoidDataType.dataType),
"uint *": PointerDataType(UnsignedIntegerDataType.dataType),
}
dt_map = {
"uint": UnsignedIntegerDataType.dataType,
"int": IntegerDataType.dataType,
"bool": BooleanDataType.dataType,
"byte *": PointerDataType(ByteDataType.dataType),
"uint *": PointerDataType(UnsignedIntegerDataType.dataType),
"void *": PointerDataType(VoidDataType.dataType),
}
if ret_type in rt_map:
func.setReturnType(rt_map[ret_type], SourceType.USER_DEFINED)
plist = []
for pt, pn in params:
plist.append(ParameterImpl(pn, dt_map.get(pt, UnsignedIntegerDataType.dataType), program))
func.updateFunction(None, None, plist,
ghidra.program.model.listing.Function.FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
True, SourceType.USER_DEFINED)
except:
pass
def get_or_create_equate(name, value):
eq = equateTable.getEquate(name)
if eq is None:
try:
eq = equateTable.createEquate(name, value)
except:
pass
return eq
print("\n" + "=" * 70)
print(" Xbox One Bootrom - Complete Ghidra Analysis Script")
print("=" * 70)
# ============================================================================
# PHASE 1: CLEAR AND SET ARM/THUMB MODES
# ============================================================================
print("\n[Phase 1/8] Clearing disassembly and setting ARM/Thumb modes...")
block = mem.getBlocks()[0]
listing.clearCodeUnits(block.getStart(), block.getEnd(), False)
set_tmode(0x00, 0x3F, 0) # ARM vector table
set_tmode(0x40, 0xE1, 1) # Early boot + exception handlers
set_tmode(0x410, 0x12B7, 1) # Core crypto/boot functions
set_tmode(0x1314, 0x1D1F, 1) # Key management + memcpy/memset
set_tmode(0x2000, 0x2D87, 1) # Boot chain + hardware phases
set_tmode(0x2D8C, 0x3B75, 1) # DDR/SoC init + boot stages
set_tmode(0x3B78, 0x3EEF, 1) # Utility functions
set_tmode(0x3EF4, 0x438F, 1) # SPAD + PCIe config
set_tmode(0x4390, 0x50A3, 1) # SoC register config + HW init
set_tmode(0x5140, 0x5263, 1) # Clock gate + MPU + memclear
# ============================================================================
# PHASE 2: LABELS AND COMMENTS
# ============================================================================
print("[Phase 2/8] Labeling functions and adding comments...")
# --- Vector Table (ARM) ---
lbl(0x00, "VEC_Reset")
cmt(0x00, "ARM Exception Vector Table\n"
"Each vector loads PC from pointer table at 0x20-0x3C.\n"
"Reset -> BOOT_Main (0xFFFFE510, outside this dump)\n"
"All others -> handlers within this ROM")
lbl(0x04, "VEC_UndefinedInstruction")
eol(0x04, "-> EXC_FatalError (0xFFFF0081)")
lbl(0x08, "VEC_SupervisorCall")
eol(0x08, "-> EXC_SVCHandler (0xFFFF00D1)")
lbl(0x0C, "VEC_PrefetchAbort")
eol(0x0C, "-> EXC_PrefetchAbort (0xFFFF0047)")
lbl(0x10, "VEC_DataAbort")
eol(0x10, "-> EXC_DataAbort (0xFFFF0055)")
lbl(0x14, "VEC_NotUsed")
eol(0x14, "-> 0xFFFFFFFF (unused, hangs)")
lbl(0x18, "VEC_IRQ")
eol(0x18, "-> EXC_IRQ (0xFFFF0075)")
lbl(0x1C, "VEC_FIQ")
eol(0x1C, "-> EXC_FIQ (0xFFFF007B)")
for o, n in [(0x20,"PTR_Reset"),(0x24,"PTR_Undef"),(0x28,"PTR_SVC"),
(0x2C,"PTR_PrefAbort"),(0x30,"PTR_DataAbort"),
(0x34,"PTR_NotUsed"),(0x38,"PTR_IRQ"),(0x3C,"PTR_FIQ")]:
lbl(o, n)
# --- All Functions: (offset, name, plate_comment) ---
# plate_comment can be None to skip
FUNCTIONS = [
# Exception Handlers
(0x40, "BOOT_CPInit",
"CP15 coprocessor init stub\nMOVW R0, #0x5F3 then branches to SVC handler"),
(0x46, "EXC_PrefetchAbort",
"Prefetch Abort handler\n"
"Reads IFSR (c5,c0,1) and IFAR (c6,c0,2)\n"
"Packs: R0 = 0x1F3 | (IFAR[31:25]<<25) | (IFSR[12:0]<<12)"),
(0x54, "EXC_DataAbort",
"Data Abort handler\n"
"Reads DFSR (c5,c0,0) and DFAR (c6,c0,0)\n"
"Packs: R0 = 0x2F3 | (DFAR[31:25]<<25) | (DFSR[12:0]<<12)"),
(0x60, "EXC_PackFaultInfo",
"Common fault packing for PrefAbort/DataAbort\n"
"Merges fault address top 7 bits + status 13 bits + base code"),
(0x74, "EXC_IRQ",
"IRQ handler - error 0x3F3 -> EXC_FatalError\nIRQs should never fire in bootrom"),
(0x7A, "EXC_FIQ",
"FIQ handler - error 0x4F3 -> EXC_FatalError"),
(0x80, "EXC_FatalError",
"Fatal error handler - all exceptions funnel here\n"
"R0 = packed error code\n"
"1. Writes error to 0x07008114 (clock gate)\n"
"2. If error[7:3]==0x1E: writes to 0x078000F0 + 0x0780040C\n"
"3. Writes to 0x07801004 (debug), inverts power bits\n"
"4. Infinite loop at 0xFFFF00C4\n\n"
"Error format (abort): [31:25]=fault_addr_top7 [24:12]=FSR [9:8]=type [7:0]=0xF3\n"
"Error format (UDF): caller packs R0 (0xE3,0xE4,0x1E0,0x2F6...)"),
(0xC4, "EXC_FatalLoop", None),
(0xD0, "EXC_SVCHandler",
"SVC handler\n"
"Privileged caller -> BOOT_CPInit\n"
"User mode -> restore regs from 0x0003D000, BX LR (return from BOOT_EnterSVCMode)"),
# Data Regions
(0xF4, "DAT_DEAD_Padding",
"0xDEAD padding between exception handlers and copyright string"),
(0x110, "STR_Copyright",
"(C) Microsoft Corporation. All rights reserved.\n"
"Do not unlawfully hack, circumvent, reverse engineer, glitch, modify or copy."),
(0x190, "DAT_CryptoHash1",
"32-byte hash/key: ED E8 0B F3 72 5C 1D 8B...\nReferenced by BOOT_VerifyRSASignature"),
(0x1D0, "DAT_KeyDerivIV",
"16 bytes zeros - IV for key derivation"),
(0x1E0, "DAT_CryptoHash2",
"32-byte hash/key: 86 0B 58 E8 B7 76 46 F8...\nReferenced by BOOT_VerifyRSASignature"),
(0x220, "DAT_NAND_Config",
"NAND config table - 4 entries x 12 bytes\nReferenced by BOOT_Main for boot stages"),
(0x22C, "DAT_NAND_Entry1", None),
(0x238, "DAT_NAND_Entry2", None),
(0x244, "DAT_NAND_Entry3", None),
(0x250, "DAT_MPU_BaseAddrs",
"MPU region base address table\nUsed by BOOT_SetupMPU"),
(0x260, "DAT_MPU_Config",
"MPU region config: 12 bytes/entry {size_enable, access, base}"),
(0x2E0, "DAT_SPADConfig",
"SPAD (scratchpad) configuration bytes\nReferenced by BOOT_SecureCall for MPU subregion setup"),
(0x2EC, "DAT_ECC_CurveP", "ECC-384 curve prime P (48 bytes)"),
(0x31C, "DAT_ECC_CurveN", "ECC curve order N (48 bytes)"),
(0x34C, "DAT_ECC_CurveParams", "ECC curve parameters (96 bytes)"),
(0x37C, "DAT_ECC_GeneratorX", "ECC generator/pubkey X coordinate (48 bytes)"),
(0x3AC, "DAT_ECC_GeneratorY", "ECC generator/pubkey Y coordinate (48 bytes)"),
(0x3DC, "DAT_ECC_CurveA", "ECC curve coefficient a (48 bytes): a = p - 3"),
# Core Boot Functions
(0x410, "BOOT_SetClockGate",
"Configure clock gating\nR0=gate_id -> writes 0x07008114, 0x07801004\n"
"Enables master clock bit24 at 0x07801000\nCalled 15 times during boot"),
(0x468, "BOOT_ConfigPLL",
"Configure PLL from fuse straps\nReads 0x07860000/28/2C/104C\n"
"Writes 0x07820044, calls TimerStart+WaitPLLLock"),
(0x528, "BOOT_CheckSecurityStatus",
"Poll security status with 256-iteration timeout\n"
"Checks fuse state, crypto ready (0x07820044[29])\n"
"UDF on timeout: 0x2F6 (crypto ready) or 0x1F6 (bad fuse)"),
(0x5D4, "BOOT_WaitSecurityReady",
"CheckSecurityStatus + busy-wait countdown with DMB barriers\nCalled 16 times during boot"),
# Crypto Functions
(0x608, "BOOT_VerifyChecksum",
"XOR checksum: for each byte result = (~expected ^ actual) & 0xFF\nReturns 0xFF on match"),
(0x638, "BOOT_DecryptBlock",
"AES-CTR decryption via HW crypto\nR0=key/IV state, R2=data, R3=length\n"
"Uses StackCanary protection. XORs keystream with data 32 bytes at a time"),
(0x6A4, "BOOT_VerifyRSASignature",
"RSA-PSS verify with anti-glitch accumulator (0x0003B004)\n"
"Checks 0xBC trailer, decrypts, walks padding, verifies hash\n"
"acc = (acc+val) + (acc<<10) ^ (acc>>6) at every step\n"
"Returns 1 on success, 0 on failure"),
(0x828, "BOOT_BigNumCompare",
"48-byte (12-word) bignum compare\nReturns: 0=equal, 1=A>B, -1=A<B"),
(0x894, "BOOT_VerifyCertChain",
"ECC cert chain verify (0x320 byte stack frame)\n"
"7 temp bignums, 8 HMAC ops, anti-glitch throughout\n"
"Returns 1 on success, 0 on failure"),
# Fuse Functions
(0xB3C, "BOOT_CheckFuseErrors",
"Check 6 eFuse banks (0x07850100-150) for read errors\n"
"UDF with bank-specific code on error\nCalled 13 times during boot"),
(0xC50, "BOOT_ClearFuseErrors",
"Write 0x08 to all 6 fuse bank registers"),
# NAND Functions
(0xC9C, "BOOT_WaitNANDReady", "Poll 0x01000008 bit4 until clear"),
(0xCB0, "BOOT_NANDCommand", "Set bit0 of 0x01000008 + readback barrier"),
(0xCCC, "BOOT_NANDRead",
"Read from NAND in 64-byte chunks\nR0=dest, R1=addr, R2=count\n"
"Copies from 0x01000134 buffer"),
# I2C / SMBus
(0xD3C, "BOOT_SMBusReadResult", "Poll 0x07860500/504, return UBFX(status,2,7)"),
(0xD6C, "BOOT_SMBusTransaction", "SMBus read/write via 0x07860500"),
(0xDB8, "BOOT_SMBusProbe", "Probe SMBus device with 3 retries"),
(0xDF0, "BOOT_I2CReadResult", "Poll 0x07860400/404, return UBFX(status,2,7)"),
(0xE20, "BOOT_I2CTransaction", "I2C transaction via 0x07860400"),
(0xE6C, "BOOT_I2CScanBus", "Scan I2C bus addresses 0-63, return bitmask"),
# Crypto Engine
(0xEC0, "BOOT_InitCryptoEngine",
"Write 0x6DB6 to 0x07820048, run 12x CheckSecurityStatus writing to 0x07820060"),
(0xF10, "BOOT_Memcpy_Thunk", "Thunk to BOOT_Memcpy at ffff1938\nCalled 9 times"),
(0xF14, "BOOT_ConfigDMA",
"Setup DMA regs 0x07820184-1A8\nByte-reverses IV for big-endian loading"),
(0xFC8, "BOOT_ConfigCryptoOp",
"Configure crypto: mode+0x00F00080 to 0x07820184\nOptional 8-word IV to 0x0782019C-1B8"),
(0x10C0, "BOOT_ConfigHashOp", "Hash mode: 0x02400103 to 0x07820184, len=0x3FF"),
(0x111C, "BOOT_SetCryptoKeySelect",
"Write key IDs to 0x078201C4/C8/CC\n0x71=no key (passthrough)"),
(0x1170, "BOOT_ConfigSHAOp", "SHA mode: 0x02800800 to 0x07820184"),
(0x11D0, "BOOT_ConfigHMACOp", "HMAC mode: 0x1D in upper bits, len=0x1BF"),
(0x122C, "BOOT_WaitCryptoComplete",
"Poll 0x07820210+(ch*0x20) for completion\nStatus 4 or 7 = UDF 0xE6|err"),
(0x12B0, "BOOT_WaitCryptoComplete_Ch4", "Wrapper: channel 4 (key engine)"),
(0x12B8, "BOOT_LoadKey",
"Load 32-byte key to HW slot\nR0=slot, R1=data, R2=byte_reverse\n"
"Writes 0x07820100-11C, activates via 0x07820120"),
# Key Management
(0x1314, "BOOT_LoadKeyPair", "Load key pair to slots 0x40+0x41"),
(0x1378, "BOOT_LoadKeyTable", "Load 16 keys to slots 0x40-0x4F"),
(0x139C, "BOOT_SHAFinalize", "Finalize SHA, copy 32-byte digest from 0x00F00000"),
(0x13C0, "BOOT_CryptoDMA", "Crypto DMA in 512-byte chunks"),
(0x1444, "BOOT_CryptoProcess",
"Main crypto function - hash/encrypt in 8KB chunks\n"
"R0=first_block, R1=data, R2=len, R3=hash_out\n"
"Byte counter at 0x00039000. Referenced 10 times"),
(0x14CC, "BOOT_ExpandKey", "AES key expansion: 0x20=AES128, 0x21=AES256"),
(0x1504, "BOOT_DeriveSubkey", "Derive subkey from boolean flag + key type"),
(0x156C, "BOOT_LoadKeyFromBitfield", "Load keys from 256-bit bitfield"),
(0x15D8, "BOOT_SetupDerivedKey", "LoadKeyPair + SetKeySelect(4,0x40,0x42) + SHAFinalize"),
(0x1600, "BOOT_LoadAndWrapKey", "Load key byte-reversed + wrap (0xA,0x40,0x23)"),
(0x1624, "BOOT_SelectOutputKey", "Select output: (0xC, 0x26, key-0x72)"),
# Hash/HMAC
(0x1640, "BOOT_HashWithKeys",
"Copy 512B key+data to crypto SRAM, load key table, hash"),
(0x168C, "BOOT_CopyBlock48", "Copy 12 words + zero-pad to 16 words (48->64 bytes)"),
(0x16C8, "BOOT_HMACCompute",
"HMAC with up to 7 input blocks to crypto SRAM\nCalled 7 times by BOOT_VerifyCertChain"),
# Mode Switching / Utility
(0x175C, "BOOT_SecureCall",
"Execute function in secure context\n"
"Reconfigures 12 MPU subregions\n"
"Enters SVC mode, calls function, returns via SVC#0\n"
"Called 14 times (once per boot stage)"),
(0x17B4, "BOOT_TimerStart", "Start timer: timeout->0x07802010, enable->0x0780200C"),
(0x17F8, "BOOT_WaitPLLLock", "Poll 0x07800020 bit0 until set"),
(0x1814, "BOOT_HashAccelerator", "HW hash via 0x01028000, poll 0x01028030"),
(0x188C, "BOOT_Memset", "Optimized memset with alignment handling + STM"),
(0x1900, "BOOT_EnterSVCMode",
"Save regs to 0x0003D000, switch CPSR=0x1D0\n"
"SP=0x0003BFF0, BLX R2, SVC#0 to return"),
(0x1916, "BOOT_StackCanaryCheck",
"Compare R0 vs [0x0003B000], UDF#0 on mismatch"),
(0x1938, "BOOT_Memcpy", "Optimized memcpy with PLD prefetch and LDM/STM"),
(0x1CBC, "BOOT_StackCanarySet",
"Save canary: SP-[0x078000E4 or 0x0003B000] depending on CPU mode"),
(0x1CDE, "BOOT_StackCanaryVerify",
"Check canary on exit, trap on corruption"),
# Boot Chain
(0x2000, "BOOT_ValidateImageSize", "Return 1 if R1 < 128MB"),
(0x2010, "BOOT_EarlyInit",
"Setup MPU, clock gates, devkit detection (0x078000E0)\n"
"Init SoC, anti-glitch=0x1505, clear fuse errors"),
(0x20E4, "BOOT_Main_SecureBoot",
"Main secure boot chain - stages 0x22-0x2E\n"
"Each stage: accumulator update -> clock gate -> check fuses -> SecureCall\n\n"
"Expected accumulators:\n"
" 22=C134398D 23=1798C1A0 24=0249D4F4 25=02CD9BD5\n"
" 26=83D6BF0E 27=4F869E48 28=F052A2EF 29=C1870325\n"
" 2A=6C85D138 2B=D9070CD8 2C=A2F0595F 2D=EB676377\n"
" 2E=E506DBAA"),
# Key Derivation / Hardware Phases
(0x2BAC, "BOOT_DeriveConsoleKeys",
"Derive keys from fuses 0x07860028/2C\n"
"3 derivation paths, byte-reverse+hash+crypto"),
(0x2C9C, "BOOT_HardwarePhase",
"Dispatch: 1=full SB init, 2=fuse provisioning, 3=minimal init"),
(0x2CB8, "BOOT_ConfigMemoryTiming",
"Write timing to 0x07830000-14:\n"
"C210, E0008002, C000C020, 80098008, 800B800A, C010"),
# SoC Init
(0x2D24, "BOOT_I2CWaitIdle", "Wait for I2C idle on 0x07860400/404"),
(0x2D4C, "BOOT_I2CWriteRegister", "Write I2C register with preserved bits"),
(0x2D8C, "BOOT_ConfigDDR",
"DDR init from fuse calibration at 0x01024000-038\n"
"Writes to memory controller 0x01000000-040"),
(0x3008, "BOOT_SoCInit",
"Master SoC init (~2.5KB)\n"
"Clocks, PLL, I2C, DDR, PHY training, SPAD calibration, NAND\n"
"Writes DEADBEEF to 0x07800404 on fatal error"),
# Utility
(0x3B4C, "BOOT_EnterWFI", "Clear interrupts, DSB+ISB, WFI (sleep)"),
(0x3B78, "BOOT_BusyWait16", "Count 0-15 with DMB barriers"),
(0x3BB0, "BOOT_WriteDeadBeef",
"0xDEADBEEF -> 0x07800404, set 0x07800408 bit10"),
(0x3BDC, "BOOT_CopyFuseToShadow", "Copy 0x07860040-4C to 0x07801008-14"),
(0x3C30, "BOOT_CopyOTPToShadow", "Copy 0x01021000-04 to 0x07801018-1C"),
(0x3C5C, "BOOT_BuildSecurityDescriptor",
"Assemble security descriptor from fuses+status into 0x07801024-3C"),
# Stage Reporting
(0x3E40, "BOOT_EnableClockBit", "Set bit R0 in 0x07801000"),
(0x3E60, "BOOT_EnableClock27", "Enable clock bit 27 (0x1B)"),
(0x3E68, "BOOT_StageReport",
"Report boot stage to debug port 0x07801004\n"
"Enables clocks, optional security delay\nCalled 35+ times"),
# SPAD / Calibration
(0x3EF4, "BOOT_WriteSPADRegister", "Write SPAD at 0x07860300/304"),
(0x3F2C, "BOOT_ReadSPADRegister", "Read SPAD from 0x07860304"),
(0x3F64, "BOOT_ConfigSPAD_Set1", "SPAD cal from 0x00FF0928/988/98C"),
(0x4040, "BOOT_ConfigSPAD_Set2", "SPAD cal from 0x00FF0948/94C"),
(0x40F8, "BOOT_ConfigSPAD_Set3", "SPAD cal from 0x00FF0910/924"),
(0x41B0, "BOOT_ConfigSPAD_Set4", "SPAD cal from 0x00FF0918/920"),
# I2C Training / PCIe
(0x4268, "BOOT_I2CTrainBus",
"I2C PHY training: XOR pattern over 512 addresses"),
(0x42D4, "BOOT_ConfigPCIe", "PCIe/SerDes at 0x010A0008/14/18/174"),
# SoC Register Config
(0x4390, "BOOT_ConfigSoCRegisters",
"Fuse->register config for 0x01080000 + 0x00F000xx"),
(0x46DC, "BOOT_ConfigPHY",
"PHY via indirect [R0+0xA0]/[R0+0xA4]\nReads fuse data from 0x01024054-064"),
(0x4830, "BOOT_ConfigDisplayPHY", "Display/HDMI PHY from fuses"),
(0x4A60, "BOOT_ConfigAnalogParams",
"Calibration from 0x00F00024-64 to misc offsets"),
(0x4B4C, "BOOT_ConfigNANDTiming", "NAND timing to 0x0100008C-110"),
(0x4BB8, "BOOT_HardwareInit",
"Master HW init: key derivation, DDR, PHY, PCIe, NAND timing\n"
"Calls BOOT_DeriveConsoleKeys + BOOT_HardwarePhase"),
# MPU / CP15
(0x5140, "BOOT_SetClockGateRaw", "Direct write bits[5:0] of 0x07008114"),
(0x5160, "BOOT_ClearSRAM", "Fill 256KB at addr 0 with 0xDE"),
(0x5212, "BOOT_WriteMPUSubregion", "Write MPU subregion via CP15 c6"),
(0x5238, "BOOT_DisableMMU", "Clear SCTLR bit0, DSB+ISB"),
(0x5250, "BOOT_WriteMPURegion",
"Write MPU region: number, base, size, access via CP15 c6"),
]
for offset, name, comment in FUNCTIONS:
lbl(offset, name)
if comment:
cmt(offset, comment)
# ============================================================================
# PHASE 3: DISASSEMBLE ALL ENTRY POINTS
# ============================================================================
print("[Phase 3/8] Disassembling code...")
# ARM vector table
for off in range(0x00, 0x20, 4):
disas(off)
# All Thumb entry points
THUMB_ENTRIES = [
0x40,0x46,0x54,0x60,0x74,0x7A,0x80,0xD0,
0x410,0x468,0x528,0x5D4,0x608,0x638,0x6A4,0x828,0x894,
0xB3C,0xC50,0xC9C,0xCB0,0xCCC,
0xD3C,0xD6C,0xDB8,0xDF0,0xE20,0xE6C,
0xEC0,0xF10,0xF14,0xFC8,0x10C0,0x111C,0x1170,0x11D0,
0x122C,0x12B0,0x12B8,
0x1314,0x1378,0x139C,0x13C0,0x1430,0x1444,0x14CC,0x1504,
0x156C,0x15D8,0x1600,0x1624,
0x1640,0x168C,0x16C8,
0x175C,0x17B4,0x17F8,0x1814,0x188C,0x1900,0x1916,0x1938,
0x1CBC,0x1CDE,
0x2000,0x2010,0x20E4,
0x2BAC,0x2C9C,0x2CB8,
0x2D24,0x2D4C,0x2D8C,0x3008,
0x3B4C,0x3B78,0x3BB0,0x3BDC,0x3C30,0x3C5C,
0x3E40,0x3E60,0x3E68,
0x3EF4,0x3F2C,0x3F64,0x4040,0x40F8,0x41B0,
0x4268,0x42D4,0x4350,0x4370,
0x4390,0x46DC,0x4830,0x4A60,0x4B4C,0x4BB8,
0x5140,0x5160,0x5212,0x5238,0x5250,
]
for off in THUMB_ENTRIES:
disas(off)
# ============================================================================
# PHASE 4: CREATE CUSTOM DATA TYPES
# ============================================================================
print("[Phase 4/8] Creating enums and structs...")
txn = program.startTransaction("Create data types")
try:
cat = CategoryPath("/XboxOne")
# --- MMIO Register Enum (comprehensive) ---
mmio_enum = EnumDataType(cat, "MMIO_REG", 4)
MMIO_REGS = {
"MMIO_CLOCK_GATE":0x07008114, "MMIO_CLOCK_GATE_ALL":0x07008118,
"MMIO_SYS_CTRL":0x0780000C, "MMIO_PLL_LOCK":0x07800020,
"MMIO_CLOCK_CTRL_40":0x07800040, "MMIO_CLOCK_CTRL_44":0x07800044,
"MMIO_KEY_SRC_A":0x078000A0, "MMIO_KEY_SRC_B":0x078000A4,
"MMIO_SEC_MODE":0x078000E0, "MMIO_STACK_CANARY":0x078000E4,
"MMIO_BOOT_STATUS":0x078000F0,
"MMIO_SYS_STATUS":0x07800400, "MMIO_DEBUG_OUT":0x07800404,
"MMIO_SYS_FLAGS":0x07800408, "MMIO_SYS_FLAGS2":0x0780040C,
"MMIO_SYS_STATUS2":0x07800414, "MMIO_SYS_CONFIG":0x07800418,
"MMIO_CLOCK_STATUS":0x07801000, "MMIO_STAGE_DEBUG":0x07801004,
"MMIO_FUSE_SHADOW_0":0x07801008, "MMIO_FUSE_SHADOW_1":0x0780100C,
"MMIO_FUSE_SHADOW_2":0x07801010, "MMIO_FUSE_SHADOW_3":0x07801014,
"MMIO_OTP_SHADOW_0":0x07801018, "MMIO_OTP_SHADOW_1":0x0780101C,
"MMIO_KEY_SEL":0x07801020, "MMIO_KEY_HASH_0":0x07801024,
"MMIO_KEY_HASH_1":0x07801028,
"MMIO_SEC_DESC_0":0x0780102C, "MMIO_SEC_DESC_4":0x0780103C,
"MMIO_TIMER_CTRL":0x07802000, "MMIO_TIMER_ENABLE":0x0780200C,
"MMIO_TIMER_VALUE":0x07802010,
"MMIO_CRYPTO_PLL":0x07820044, "MMIO_CRYPTO_CONFIG":0x07820048,
"MMIO_CRYPTO_WARMUP":0x07820060,
"MMIO_CRYPTO_KEY_0":0x07820100, "MMIO_CRYPTO_KEY_7":0x0782011C,
"MMIO_CRYPTO_KEY_ACT":0x07820120,
"MMIO_CRYPTO_KICK_LO":0x07820180, "MMIO_CRYPTO_DMA_CTRL":0x07820184,
"MMIO_CRYPTO_DMA_LEN":0x07820188,
"MMIO_CRYPTO_SRC_MASK":0x0782018C, "MMIO_CRYPTO_DST_MASK":0x07820194,
"MMIO_CRYPTO_IV_0":0x0782019C, "MMIO_CRYPTO_IV_3":0x078201A8,
"MMIO_CRYPTO_KICK_HI":0x078201C0,
"MMIO_CRYPTO_KEYSEL_0":0x078201C4, "MMIO_CRYPTO_KEYSEL_2":0x078201CC,
"MMIO_CRYPTO_STATUS_0":0x07820210, "MMIO_CRYPTO_STATUS":0x0782020C,
"MMIO_MEMTIM_0":0x07830000, "MMIO_MEMTIM_5":0x07830014,
"MMIO_FUSE_BANK_0":0x07850100, "MMIO_FUSE_BANK_1":0x07850110,
"MMIO_FUSE_BANK_2":0x07850120, "MMIO_FUSE_BANK_3":0x07850130,
"MMIO_FUSE_BANK_4":0x07850140, "MMIO_FUSE_BANK_5":0x07850150,
"MMIO_SEC_PROC_ID":0x07860000, "MMIO_FUSE_STRAP_1":0x07860028,
"MMIO_FUSE_STRAP_2":0x0786002C, "MMIO_SEC_FLAGS":0x0786104C,
"MMIO_SEC_ENABLE":0x07861048,
"MMIO_I2C_CMD":0x07860400, "MMIO_I2C_STATUS":0x07860404,
"MMIO_SMBUS_CMD":0x07860500, "MMIO_SMBUS_STATUS":0x07860504,
"MMIO_SPAD_CMD":0x07860300, "MMIO_SPAD_DATA":0x07860304,
"MMIO_NAND_CTRL":0x01000008, "MMIO_NAND_BUF":0x01000134,
}
for name, val in MMIO_REGS.items():
mmio_enum.add(name, val)
dtm.addDataType(mmio_enum, None)
# --- Boot Stage Enum ---
se = EnumDataType(cat, "BOOT_STAGE", 4)
for n, v in [("STAGE_CLOCK_FUSE",0x22),("STAGE_CRYPTO_INIT",0x23),
("STAGE_LOAD_BL1",0x24),("STAGE_LOAD_BL2",0x25),
("STAGE_VERIFY_SIGS",0x26),("STAGE_NAND_CONFIG",0x27),
("STAGE_DISPLAY_IO",0x28),("STAGE_KEY_DERIVE",0x29),
("STAGE_NAND_BL",0x2A),("STAGE_VERIFY_NAND",0x2B),
("STAGE_LOAD_FINAL",0x2C),("STAGE_PREP_EXEC",0x2D),
("STAGE_CLEANUP",0x2E)]:
se.add(n, v)
dtm.addDataType(se, None)
# --- Error Code Enum ---
ee = EnumDataType(cat, "BOOT_ERROR", 4)
for n, v in [("ERR_PREFETCH",0x1F3),("ERR_DATA_ABORT",0x2F3),
("ERR_IRQ",0x3F3),("ERR_FIQ",0x4F3),("ERR_CP_INIT",0x5F3),
("ERR_NAND1",0xE3),("ERR_NAND2",0xE4),("ERR_FUSE",0xE5),
("ERR_CRYPTO",0xE6),("ERR_LOAD1",0x1E0),("ERR_LOAD2",0x2E0),
("ERR_SIZE",0x1E2),("ERR_SIG",0x3E2),("ERR_CERT1",0x4E2),
("ERR_CERT2",0x5E2),("ERR_FINAL",0x6E2),
("ERR_TIMEOUT1",0x1F6),("ERR_TIMEOUT2",0x2F6),
("ERR_DONE",0xF2),("ERR_STACK",0x1F0),("ERR_BADKEY",0xFF)]:
ee.add(n, v)
dtm.addDataType(ee, None)
# --- Crypto Mode Enum ---
ce = EnumDataType(cat, "CRYPTO_MODE", 4)
for n, v in [("CRYPTO_SHA",0x02800800),("CRYPTO_HASH",0x02400103),
("CRYPTO_DMA",0x0844008C),("CRYPTO_AES",0x00F00080),
("CRYPTO_WARMUP",0x6DB6),("KEY_NONE",0x71)]:
ce.add(n, v)
dtm.addDataType(ce, None)
# --- Hardware Phase Enum ---
pe = EnumDataType(cat, "HW_PHASE", 4)
pe.add("PHASE_FULL_SB", 1)
pe.add("PHASE_FUSE_PROV", 2)
pe.add("PHASE_MINIMAL", 3)
dtm.addDataType(pe, None)
# --- Fuse Error Enum ---
fe = EnumDataType(cat, "FUSE_ERROR", 4)
for n, v in [("FUSE_ERR_B0",0x210000F8),("FUSE_ERR_B1",0x230000F8),
("FUSE_ERR_B2",0x220000F8),("FUSE_ERR_B3",0x240000F8),
("FUSE_ERR_B4",0x250000F8),("FUSE_ERR_B5",0x260000F8)]:
fe.add(n, v)
dtm.addDataType(fe, None)
# --- PSS Constants Enum ---
pss = EnumDataType(cat, "PSS_CONST", 4)
pss.add("PSS_TRAILER_BYTE", 0xBC)
pss.add("PSS_SEPARATOR", 0x01)
dtm.addDataType(pss, None)
# --- NAND Config Entry Struct ---
ne = StructureDataType(cat, "NAND_ConfigEntry", 0)
ne.add(UnsignedIntegerDataType.dataType, 4, "flags", "Configuration flags")
ne.add(UnsignedIntegerDataType.dataType, 4, "addr_config", "Address/size config")
ne.add(UnsignedIntegerDataType.dataType, 4, "page_config", "Page size and mode")
dtm.addDataType(ne, None)
# --- MPU Region Struct ---
mr = StructureDataType(cat, "MPU_Region", 0)
mr.add(UnsignedIntegerDataType.dataType, 4, "size_enable", "Region size + enable")
mr.add(UnsignedIntegerDataType.dataType, 4, "access_perms", "AP, TEX, S, C, B")
mr.add(UnsignedIntegerDataType.dataType, 4, "base_addr", "Region base address")
dtm.addDataType(mr, None)
# --- AntiGlitch State Struct ---
ag = StructureDataType(cat, "AntiGlitch_State", 0)
ag.add(UnsignedIntegerDataType.dataType, 4, "accumulator",
"Running hash: acc = (acc+val) + (acc<<10) ^ (acc>>6)")
dtm.addDataType(ag, None)
print(" Created enums: MMIO_REG, BOOT_STAGE, BOOT_ERROR, CRYPTO_MODE,")
print(" HW_PHASE, FUSE_ERROR, PSS_CONST")
print(" Created structs: NAND_ConfigEntry, MPU_Region, AntiGlitch_State")
except Exception as e:
print(" Warning: " + str(e))
finally:
program.endTransaction(txn, True)
# Apply NAND_ConfigEntry struct to data
try:
nand_dt = dtm.getDataType("/XboxOne/NAND_ConfigEntry")
if nand_dt:
for off in [0x220, 0x22C, 0x238, 0x244]:
a = addr(off)
listing.clearCodeUnits(a, a.add(nand_dt.getLength() - 1), False)
listing.createData(a, nand_dt)
except:
pass
# ============================================================================
# PHASE 5: FUNCTION SIGNATURES
# ============================================================================
print("[Phase 5/8] Setting function signatures...")
SIGNATURES = [
(0x80, "void", "EXC_FatalError", [("uint","error_code")]),
(0x410, "void", "BOOT_SetClockGate", [("uint","gate_id")]),
(0x468, "void", "BOOT_ConfigPLL", []),
(0x528, "uint", "BOOT_CheckSecurityStatus", []),
(0x5D4, "void", "BOOT_WaitSecurityReady", []),
(0x608, "byte", "BOOT_VerifyChecksum", [("byte *","expected"),("byte *","actual"),("int","length")]),
(0x638, "void", "BOOT_DecryptBlock", [("uint *","key_state"),("void *","unused"),("byte *","data"),("uint","length")]),
(0x6A4, "bool", "BOOT_VerifyRSASignature", [("uint *","pubkey_hash"),("byte *","signature_512")]),
(0x828, "int", "BOOT_BigNumCompare", [("uint *","a"),("uint","unused"),("uint *","b"),("uint","count")]),
(0x894, "bool", "BOOT_VerifyCertChain", [("uint *","pubkey_point"),("uint *","cert_data")]),
(0xB3C, "void", "BOOT_CheckFuseErrors", []),
(0xC50, "void", "BOOT_ClearFuseErrors", []),
(0xC9C, "void", "BOOT_WaitNANDReady", []),
(0xCB0, "void", "BOOT_NANDCommand", []),
(0xCCC, "void", "BOOT_NANDRead", [("void *","dest"),("uint","nand_addr"),("uint","byte_count")]),
(0xD3C, "uint", "BOOT_SMBusReadResult", []),
(0xD6C, "uint", "BOOT_SMBusTransaction", [("uint","unused"),("uint","address")]),
(0xDB8, "uint", "BOOT_SMBusProbe", [("uint","unused"),("uint","device_addr")]),
(0xDF0, "uint", "BOOT_I2CReadResult", []),
(0xE20, "uint", "BOOT_I2CTransaction", [("uint","device_addr"),("uint","rw_flag")]),
(0xE6C, "uint", "BOOT_I2CScanBus", [("uint","addr_mask_lo"),("uint","addr_mask_hi")]),
(0xEC0, "void", "BOOT_InitCryptoEngine", []),
(0xF14, "void", "BOOT_ConfigDMA", [("uint","u0"),("uint","u1"),("uint","u2"),("uint","u3")]),
(0xFC8, "void", "BOOT_ConfigCryptoOp", [("uint","u"),("uint","data_len"),("uint *","iv_ptr"),("uint","mode")]),
(0x10C0, "void", "BOOT_ConfigHashOp", []),
(0x111C, "void", "BOOT_SetCryptoKeySelect", [("uint","key_id"),("uint","in_slot"),("uint","out_slot")]),
(0x1170, "void", "BOOT_ConfigSHAOp", [("uint","data_len")]),
(0x11D0, "void", "BOOT_ConfigHMACOp", [("uint","key_idx")]),
(0x122C, "void", "BOOT_WaitCryptoComplete", [("uint","channel")]),
(0x12B0, "void", "BOOT_WaitCryptoComplete_Ch4", []),
(0x12B8, "void", "BOOT_LoadKey", [("uint","slot"),("uint *","key_data"),("uint","byte_rev")]),
(0x1314, "void", "BOOT_LoadKeyPair", [("uint","u"),("uint *","key_struct")]),
(0x1378, "void", "BOOT_LoadKeyTable", [("uint","u"),("byte *","key_table")]),
(0x139C, "void", "BOOT_SHAFinalize", [("uint","length"),("byte *","digest_out")]),
(0x13C0, "void", "BOOT_CryptoDMA", [("uint","u"),("byte *","src"),("uint *","iv"),("uint","count")]),
(0x1444, "void", "BOOT_CryptoProcess", [("uint","first_block"),("byte *","data"),("uint","len"),("byte *","hash_out")]),
(0x14CC, "void", "BOOT_ExpandKey", [("uint","key_type")]),
(0x1504, "void", "BOOT_DeriveSubkey", [("uint","key_type"),("uint","enable")]),
(0x156C, "void", "BOOT_LoadKeyFromBitfield", [("uint","key_type"),("byte *","table")]),
(0x1600, "void", "BOOT_LoadAndWrapKey", [("uint *","key_data")]),
(0x1624, "void", "BOOT_SelectOutputKey", [("uint","u"),("uint","key_idx")]),
(0x1640, "void", "BOOT_HashWithKeys", [("byte *","keys"),("byte *","table"),("byte *","input"),("byte *","output")]),
(0x168C, "void", "BOOT_CopyBlock48", [("uint *","dest"),("uint","u"),("uint *","src")]),
(0x16C8, "void", "BOOT_HMACCompute", [("uint","op"),("uint *","in1"),("uint *","in2"),("uint *","in3")]),
(0x175C, "uint", "BOOT_SecureCall", [("byte *","nand_cfg"),("void *","func"),("uint","p1"),("uint","p2")]),
(0x17B4, "void", "BOOT_TimerStart", [("uint","timeout")]),
(0x17F8, "void", "BOOT_WaitPLLLock", []),
(0x188C, "void", "BOOT_Memset", [("void *","dest"),("uint","value"),("uint","count")]),
(0x1900, "void", "BOOT_EnterSVCMode", [("uint","param"),("uint","size"),("void *","func")]),
(0x1916, "void", "BOOT_StackCanaryCheck", [("uint","expected")]),
(0x1938, "void *", "BOOT_Memcpy", [("void *","dest"),("void *","src"),("uint","count")]),
(0x1CBC, "void", "BOOT_StackCanarySet", []),
(0x1CDE, "void", "BOOT_StackCanaryVerify", []),
(0x2000, "bool", "BOOT_ValidateImageSize", [("uint","u"),("uint","size")]),
(0x2010, "void", "BOOT_EarlyInit", []),
(0x2BAC, "uint", "BOOT_DeriveConsoleKeys", [("uint","key_a"),("uint","key_b")]),
(0x2C9C, "uint", "BOOT_HardwarePhase", [("uint","phase")]),
(0x2CB8, "void", "BOOT_ConfigMemoryTiming", []),
(0x2D24, "void", "BOOT_I2CWaitIdle", []),
(0x2D4C, "void", "BOOT_I2CWriteRegister", [("uint","reg_addr")]),
(0x2D8C, "void", "BOOT_ConfigDDR", []),
(0x3008, "void", "BOOT_SoCInit", []),
(0x3B4C, "void", "BOOT_EnterWFI", []),
(0x3BB0, "void", "BOOT_WriteDeadBeef", []),
(0x3BDC, "void", "BOOT_CopyFuseToShadow", []),
(0x3C30, "void", "BOOT_CopyOTPToShadow", []),
(0x3C5C, "void", "BOOT_BuildSecurityDescriptor", []),
(0x3E40, "void", "BOOT_EnableClockBit", [("uint","bit_num")]),
(0x3E68, "void", "BOOT_StageReport", [("uint","stage_id")]),
(0x3EF4, "void", "BOOT_WriteSPADRegister", [("uint","reg"),("uint","bank"),("uint","data")]),
(0x3F2C, "uint", "BOOT_ReadSPADRegister", [("uint","reg"),("uint","bank")]),
(0x4268, "void", "BOOT_I2CTrainBus", []),
(0x42D4, "void", "BOOT_ConfigPCIe", []),
(0x4390, "void", "BOOT_ConfigSoCRegisters", []),
(0x46DC, "void", "BOOT_ConfigPHY", [("uint *","base")]),
(0x4830, "void", "BOOT_ConfigDisplayPHY", [("uint *","base")]),
(0x4A60, "void", "BOOT_ConfigAnalogParams", [("uint *","base1"),("uint *","base2")]),
(0x4B4C, "void", "BOOT_ConfigNANDTiming", []),
(0x4BB8, "void", "BOOT_HardwareInit", []),
(0x5140, "void", "BOOT_SetClockGateRaw", [("uint","gate")]),
(0x5160, "void", "BOOT_ClearSRAM", []),
(0x5212, "void", "BOOT_WriteMPUSubregion", [("uint","region"),("uint","subregion")]),
(0x5238, "void", "BOOT_DisableMMU", []),
(0x5250, "void", "BOOT_WriteMPURegion", [("uint","region"),("uint","base"),("uint","size"),("uint","access")]),
]
for s in SIGNATURES:
set_sig(*s)
# Mark no-return functions
try:
f = ensure_func(0x80)
if f: f.setNoReturn(True)
f = ensure_func(0x3B4C)
if f: f.setNoReturn(True)
except:
pass
# ============================================================================
# PHASE 6: AUTO-APPLY EQUATES TO ALL INSTRUCTIONS
# ============================================================================
print("[Phase 6/8] Scanning instructions for named constants...")
# All named constants (MMIO addresses + magic values)
ALL_EQUATES = {
# Key MMIO
0x07008114:"MMIO_CLOCK_GATE", 0x07008118:"MMIO_CLOCK_GATE_ALL",
0x0780000C:"MMIO_SYS_CTRL", 0x07800020:"MMIO_PLL_LOCK",
0x078000A0:"MMIO_KEY_SRC_A", 0x078000A4:"MMIO_KEY_SRC_B",
0x078000E0:"MMIO_SEC_MODE", 0x078000E4:"MMIO_STACK_CANARY",
0x078000F0:"MMIO_BOOT_STATUS",
0x07800400:"MMIO_SYS_STATUS", 0x07800404:"MMIO_DEBUG_OUT",
0x07800408:"MMIO_SYS_FLAGS", 0x0780040C:"MMIO_SYS_FLAGS2",
0x07800414:"MMIO_SYS_STATUS2", 0x07800418:"MMIO_SYS_CONFIG",
0x07801000:"MMIO_CLOCK_STATUS", 0x07801004:"MMIO_STAGE_DEBUG",
0x07801008:"MMIO_FUSE_SH_0", 0x0780100C:"MMIO_FUSE_SH_1",
0x07801010:"MMIO_FUSE_SH_2", 0x07801014:"MMIO_FUSE_SH_3",
0x07801018:"MMIO_OTP_SH_0", 0x0780101C:"MMIO_OTP_SH_1",
0x07801020:"MMIO_KEY_SEL", 0x07801024:"MMIO_KEY_HASH_0",
0x07801028:"MMIO_KEY_HASH_1",
0x0780102C:"MMIO_SEC_DESC_0", 0x0780103C:"MMIO_SEC_DESC_4",
0x07802000:"MMIO_TIMER_CTRL", 0x0780200C:"MMIO_TIMER_ENABLE",
0x07802010:"MMIO_TIMER_VALUE",
0x07820044:"MMIO_CRYPTO_PLL", 0x07820048:"MMIO_CRYPTO_CONFIG",
0x07820060:"MMIO_CRYPTO_WARMUP",
0x07820180:"MMIO_CRYPTO_KICK_LO", 0x078201C0:"MMIO_CRYPTO_KICK_HI",
0x07820184:"MMIO_CRYPTO_DMA_CTRL", 0x07820188:"MMIO_CRYPTO_DMA_LEN",
0x0782018C:"MMIO_CRYPTO_SRC_MASK", 0x07820190:"MMIO_CRYPTO_SRC_OFF",
0x07820194:"MMIO_CRYPTO_DST_MASK", 0x07820198:"MMIO_CRYPTO_DST_OFF",
0x0782019C:"MMIO_CRYPTO_IV_0", 0x078201A8:"MMIO_CRYPTO_IV_3",
0x078201C4:"MMIO_CRYPTO_KSEL_0", 0x078201C8:"MMIO_CRYPTO_KSEL_1",
0x078201CC:"MMIO_CRYPTO_KSEL_2",
0x07820210:"MMIO_CRYPTO_STAT_0", 0x0782020C:"MMIO_CRYPTO_STATUS",
0x07830000:"MMIO_MEMTIM_0", 0x07830014:"MMIO_MEMTIM_5",
0x07850100:"MMIO_FUSE_BANK_0", 0x07850110:"MMIO_FUSE_BANK_1",
0x07850120:"MMIO_FUSE_BANK_2", 0x07850130:"MMIO_FUSE_BANK_3",
0x07850140:"MMIO_FUSE_BANK_4", 0x07850150:"MMIO_FUSE_BANK_5",
0x07860000:"MMIO_SEC_PROC_ID", 0x07860028:"MMIO_FUSE_STRAP_1",
0x0786002C:"MMIO_FUSE_STRAP_2", 0x0786104C:"MMIO_SEC_FLAGS",
0x0786101C:"MMIO_SEC_PROV_1C", 0x07861048:"MMIO_SEC_ENABLE",
0x07860400:"MMIO_I2C_CMD", 0x07860404:"MMIO_I2C_STATUS",
0x07860500:"MMIO_SMBUS_CMD", 0x07860504:"MMIO_SMBUS_STATUS",
0x07860300:"MMIO_SPAD_CMD", 0x07860304:"MMIO_SPAD_DATA",
0x01000008:"MMIO_NAND_CTRL", 0x01000134:"MMIO_NAND_BUF",
0x01028000:"MMIO_HASH_ACCEL", 0x01028030:"MMIO_HASH_STATUS",
# SRAM locations
0x0003B000:"SRAM_STACK_CANARY", 0x0003B004:"SRAM_ANTIGLITCH",
0x0003BFF0:"SRAM_SVC_STACK", 0x0003D000:"SRAM_REG_SAVE",
0x00039000:"SRAM_CRYPTO_COUNTER", 0x00F00000:"CRYPTO_SRAM_BASE",
# Magic values
0xDEADBEEF:"DEADBEEF", 0x6DB6:"CRYPTO_WARMUP_VAL",
0x1505:"ANTIGLITCH_INIT", 0x000186A0:"TIMER_100K", 0x05F5E100:"TIMER_100M",
0x00F00000:"CRYPTO_SRAM", 0x00F00080:"CRYPTO_AES_BASE",
# Crypto modes
0x02800800:"SHA_MODE", 0x02400103:"HASH_MODE",
0x0844008C:"DMA_MODE",
# Anti-glitch expected accumulators
0xC134398D:"ACC_22", 0x1798C1A0:"ACC_23", 0x0249D4F4:"ACC_24",
0x02CD9BD5:"ACC_25", 0x83D6BF0E:"ACC_26", 0x4F869E48:"ACC_27",
0xF052A2EF:"ACC_28", 0xC1870325:"ACC_29", 0x6C85D138:"ACC_2A",
0xD9070CD8:"ACC_2B", 0xA2F0595F:"ACC_2C", 0xEB676377:"ACC_2D",
0xE506DBAA:"ACC_2E",
# Fuse errors
0x210000F8:"FUSE_ERR_B0", 0x230000F8:"FUSE_ERR_B1",
0x220000F8:"FUSE_ERR_B2", 0x240000F8:"FUSE_ERR_B3",
0x250000F8:"FUSE_ERR_B4", 0x260000F8:"FUSE_ERR_B5",
# Memory timing
0xE0008002:"MEMTIM_CAS", 0xC000C020:"MEMTIM_PRE",
0x80098008:"MEMTIM_WR", 0x800B800A:"MEMTIM_RW",
# Fuse XOR keys
0xD571AA5A:"FUSE_XOR_1", 0x3EDE55AA:"FUSE_XOR_2",
0xC0000100:"BOOT_SRC_CFG",
}
# UDF-only error codes (small values applied only at UDF sites)
ERROR_CODES = {
0xE3:"ERR_NAND1", 0xE4:"ERR_NAND2", 0xE5:"ERR_FUSE", 0xE6:"ERR_CRYPTO",
0xF2:"ERR_DONE", 0xFF:"ERR_BADKEY",
0x1E0:"ERR_LOAD1", 0x1E2:"ERR_SIZE", 0x1E3:"ERR_NAND3",
0x1F0:"ERR_STACK", 0x1F6:"ERR_TIMEOUT1",
0x2E0:"ERR_LOAD2", 0x2F6:"ERR_TIMEOUT2",
0x3E2:"ERR_SIG", 0x4E2:"ERR_CERT1", 0x5E2:"ERR_CERT2", 0x6E2:"ERR_FINAL",
}
# Pre-create all equates
for v, n in ALL_EQUATES.items():
get_or_create_equate(n, v)
for v, n in ERROR_CODES.items():
get_or_create_equate(n, v)
search_vals = set(ALL_EQUATES.keys())
err_vals = set(ERROR_CODES.keys())
applied = 0
inst = listing.getInstructionAfter(block.getStart())
while inst and inst.getAddress().compareTo(block.getEnd()) <= 0:
mn = inst.getMnemonicString().lower()
for i in range(inst.getNumOperands()):
for obj in inst.getOpObjects(i):
if isinstance(obj, Scalar):
v = obj.getUnsignedValue()
if v in search_vals:
eq = get_or_create_equate(ALL_EQUATES[v], v)
if eq:
try:
eq.addReference(inst.getAddress(), i)
applied += 1
except:
pass
elif v in err_vals and "udf" in mn:
eq = get_or_create_equate(ERROR_CODES[v], v)
if eq:
try:
eq.addReference(inst.getAddress(), i)
applied += 1
except:
pass
inst = listing.getInstructionAfter(inst.getAddress())
# Also apply to literal pool data
data_applied = 0
data = listing.getDataAfter(block.getStart())
while data and data.getAddress().compareTo(block.getEnd()) <= 0:
try:
val = data.getValue()
uv = None
if val is not None:
if isinstance(val, Scalar):
uv = val.getUnsignedValue()
elif hasattr(val, 'getUnsignedOffset'):
uv = val.getUnsignedOffset()
elif hasattr(val, 'longValue'):
uv = val.longValue() & 0xFFFFFFFF
if uv is not None and uv in search_vals:
eq = get_or_create_equate(ALL_EQUATES[uv], uv)
if eq:
try:
eq.addReference(data.getAddress(), 0)
data_applied += 1
except:
pass
except:
pass
data = listing.getDataAfter(data.getAddress())
print(" Applied %d equates to instructions + %d to data" % (applied, data_applied))
# ============================================================================
# PHASE 7: RENAME LITERAL POOL ENTRIES
# ============================================================================
print("[Phase 7/8] Renaming literal pool entries...")
# Map: value -> label name for literal pool DWORDs
POOL_NAMES = {
0x07008114:"pCLOCK_GATE", 0x07008118:"pCLOCK_GATE_ALL",
0x0780000C:"pSYS_CTRL", 0x07800020:"pPLL_LOCK",
0x07800040:"pCLK_CTRL_40", 0x07800044:"pCLK_CTRL_44",
0x078000A0:"pKEY_SRC_A", 0x078000A4:"pKEY_SRC_B",
0x078000E0:"pSEC_MODE", 0x078000E4:"pSTACK_CANARY",
0x078000F0:"pBOOT_STATUS",
0x07800400:"pSYS_STATUS", 0x07800404:"pDEBUG_OUT",
0x07800408:"pSYS_FLAGS", 0x0780040C:"pSYS_FLAGS2",
0x07800414:"pSYS_STATUS2", 0x07800418:"pSYS_CONFIG", 0x0780041C:"pSYS_SCRATCH",
0x07801000:"pCLOCK_STATUS", 0x07801004:"pSTAGE_DEBUG",
0x07801008:"pFUSE_SH_0", 0x0780100C:"pFUSE_SH_1",
0x07801010:"pFUSE_SH_2", 0x07801014:"pFUSE_SH_3",
0x07801018:"pOTP_SH_0", 0x0780101C:"pOTP_SH_1",
0x07801020:"pKEY_SEL", 0x07801024:"pKEY_HASH_0", 0x07801028:"pKEY_HASH_1",
0x0780102C:"pSEC_DESC_0", 0x0780103C:"pSEC_DESC_4",
0x07802000:"pTIMER_CTRL", 0x0780200C:"pTIMER_EN", 0x07802010:"pTIMER_VAL",
0x07820044:"pCRYPTO_PLL", 0x07820048:"pCRYPTO_CFG", 0x07820060:"pCRYPTO_WARM",
0x07820100:"pCRYPTO_KEY_0", 0x0782011C:"pCRYPTO_KEY_7",
0x07820120:"pCRYPTO_KEY_ACT",
0x07820180:"pCRYPTO_KICK_LO", 0x078201C0:"pCRYPTO_KICK_HI",
0x07820184:"pCRYPTO_DMA_CTRL", 0x07820188:"pCRYPTO_DMA_LEN",
0x0782018C:"pCRYPTO_SRC_MASK", 0x07820190:"pCRYPTO_SRC_OFF",
0x07820194:"pCRYPTO_DST_MASK", 0x07820198:"pCRYPTO_DST_OFF",
0x0782019C:"pCRYPTO_IV_0", 0x078201A0:"pCRYPTO_IV_1",
0x078201A4:"pCRYPTO_IV_2", 0x078201A8:"pCRYPTO_IV_3",
0x078201AC:"pCRYPTO_IV_4", 0x078201B0:"pCRYPTO_IV_5",
0x078201B4:"pCRYPTO_IV_6", 0x078201B8:"pCRYPTO_IV_7",
0x078201C4:"pCRYPTO_KSEL_0", 0x078201C8:"pCRYPTO_KSEL_1",
0x078201CC:"pCRYPTO_KSEL_2",
0x07820210:"pCRYPTO_STAT_0", 0x0782020C:"pCRYPTO_STAT",
0x07830000:"pMEMTIM_0", 0x07830004:"pMEMTIM_1", 0x07830008:"pMEMTIM_2",
0x0783000C:"pMEMTIM_3", 0x07830010:"pMEMTIM_4", 0x07830014:"pMEMTIM_5",
0x07850100:"pFUSE_B0", 0x07850110:"pFUSE_B1", 0x07850120:"pFUSE_B2",
0x07850130:"pFUSE_B3", 0x07850140:"pFUSE_B4", 0x07850150:"pFUSE_B5",
0x07860000:"pSEC_PROC_ID", 0x07860028:"pFUSE_STRAP_1",
0x0786002C:"pFUSE_STRAP_2", 0x0786104C:"pSEC_FLAGS",
0x0786101C:"pSEC_PROV_1C", 0x07861048:"pSEC_ENABLE",
0x07860040:"pFUSE_VAL_0", 0x07860044:"pFUSE_VAL_1",
0x07860048:"pFUSE_VAL_2", 0x0786004C:"pFUSE_VAL_3",
0x07860200:"pSEC_200", 0x07860204:"pSEC_204", 0x07860208:"pSEC_208",
0x07860300:"pSPAD_CMD", 0x07860304:"pSPAD_DATA",
0x07860400:"pI2C_CMD", 0x07860404:"pI2C_STATUS",
0x07860500:"pSMBUS_CMD", 0x07860504:"pSMBUS_STATUS",
0x01000134:"pNAND_BUF",
0x01021000:"pOTP_0", 0x01021004:"pOTP_1",
0x01028000:"pHASH_ACC", 0x01028030:"pHASH_STATUS",
0x0003B000:"pSRAM_CANARY", 0x0003B004:"pANTIGLITCH",
0x0003BFF0:"pSVC_STACK", 0x0003D000:"pREG_SAVE", 0x00039000:"pCRYPTO_CTR",
# Constants in literal pools
0xDEADBEEF:"DEADBEEF", 0x000186A0:"TIMER_100K", 0x05F5E100:"TIMER_100M",
0xC134398D:"ACC_22", 0x1798C1A0:"ACC_23", 0x0249D4F4:"ACC_24",
0x02CD9BD5:"ACC_25", 0x83D6BF0E:"ACC_26", 0x4F869E48:"ACC_27",
0xF052A2EF:"ACC_28", 0xC1870325:"ACC_29", 0x6C85D138:"ACC_2A",
0xD9070CD8:"ACC_2B", 0xA2F0595F:"ACC_2C", 0xEB676377:"ACC_2D",
0xE506DBAA:"ACC_2E",
0x210000F8:"FUSE_ERR_B0", 0x230000F8:"FUSE_ERR_B1",
0x220000F8:"FUSE_ERR_B2", 0x240000F8:"FUSE_ERR_B3",
0x250000F8:"FUSE_ERR_B4", 0x260000F8:"FUSE_ERR_B5",
0xD571AA5A:"FUSE_XOR_1", 0x3EDE55AA:"FUSE_XOR_2",
0xC0000100:"BOOT_SRC_CFG",
0x02800800:"SHA_MODE", 0x02400103:"HASH_MODE", 0x0844008C:"DMA_MODE",
}
pool_count = 0
ptr_type = PointerDataType(UnsignedIntegerDataType.dataType)
data = listing.getDataAfter(block.getStart())
while data and data.getAddress().compareTo(block.getEnd()) <= 0:
try:
if data.getLength() == 4:
val = data.getValue()
uv = None
if val is not None:
for attr in ['getUnsignedValue','getUnsignedOffset']:
if hasattr(val, attr):
uv = getattr(val, attr)()
break
if uv is None and hasattr(val, 'longValue'):
uv = val.longValue() & 0xFFFFFFFF
if uv is not None and uv in POOL_NAMES:
a = data.getAddress()
existing = sym.getPrimarySymbol(a)
if existing is None or existing.getName().startswith("DAT_"):
try:
sym.createLabel(a, POOL_NAMES[uv], SourceType.USER_DEFINED)
pool_count += 1
except:
pass
nm = POOL_NAMES[uv]
if nm.startswith("p") and len(nm) > 1 and nm[1:2].isupper():
try:
listing.clearCodeUnits(a, a.add(3), False)
listing.createData(a, ptr_type)
except:
pass
except:
pass
data = listing.getDataAfter(data.getAddress())
print(" Renamed %d literal pool entries" % pool_count)
# ============================================================================
# PHASE 8: INTERNAL LABELS + EOL COMMENTS
# ============================================================================
print("[Phase 8/8] Adding internal labels and EOL comments...")
# Internal branch target labels
INTERNAL_LABELS = [
(0x562,"sec_not_retail"), (0x56A,"sec_poll_loop"), (0x594,"sec_timeout"),
(0x59A,"sec_return"), (0x59E,"sec_crypto_error"), (0x5A8,"sec_final_check"),
(0x6C2,"rsa_bc_missing"), (0x6EA,"rsa_fail"), (0x6F6,"rsa_bc_ok"),
(0x714,"rsa_walk_pad"), (0x73A,"rsa_check_sep"), (0x7C6,"rsa_cmp_loop"),
(0x804,"rsa_csum_fail"), (0xB20,"cert_fail"), (0xB2E,"cert_bounds_fail"),
(0xBC2,"fuse_err_bank5"), (0xBD0,"fuse_err_bank4"), (0xBDE,"fuse_err_bank3"),
(0xBEC,"fuse_err_bank2"), (0xBFA,"fuse_err_bank1"), (0xC08,"fuse_err_bank0"),
(0xC16,"fuse_ok"),
(0xCEC,"nand_read_loop"), (0xD34,"nand_done"),
(0x1248,"crypto_ch4"), (0x1256,"crypto_poll"), (0x127C,"crypto_running"),
(0x1466,"crypto_chunk_loop"), (0x14BC,"crypto_finalize"),
(0x2058,"early_devkit"), (0x205E,"early_set_mode"),
(0x2BF4,"derive_start"), (0x2C3E,"derive_path2"),
(0x2C64,"derive_path3"), (0x2C82,"derive_fail"),
(0x360C,"soc_post_spad"), (0x37E8,"soc_post_errchk"), (0x3A44,"soc_fatal_hang"),
]
ren = 0
for off, name in INTERNAL_LABELS:
try:
a = addr(off)
ex = sym.getPrimarySymbol(a)
if ex and ex.getName().startswith("LAB_"):
ex.setName(name, SourceType.USER_DEFINED)
ren += 1
elif ex is None:
sym.createLabel(a, name, SourceType.USER_DEFINED)
ren += 1
except:
pass
# Inline EOL comments
INLINE_COMMENTS = [
(0xC4, "infinite loop = halted"),
(0x6BA, "PSS: last byte must be 0xBC"),
(0x70A, "PSS: clear top bit per PKCS#1"),
(0x754, "PSS: verify 0x01 separator"),
(0x5A6, "FATAL: security timeout (crypto ready)"),
(0x5B8, "FATAL: security timeout (bad fuse)"),
(0xBCE, "FATAL: fuse bank 5 error"), (0xBDC, "FATAL: fuse bank 4 error"),
(0xBEA, "FATAL: fuse bank 3 error"), (0xBF8, "FATAL: fuse bank 2 error"),
(0xC06, "FATAL: fuse bank 1 error"), (0xC14, "FATAL: fuse bank 0 error"),
(0x1276, "FATAL: crypto error ch0-3"), (0x128A, "FATAL: crypto error ch4"),
(0x190A, "switch to SVC mode"), (0x1912, "BLX R2 = call function"),
(0x1914, "SVC #0 = return to caller"),
(0x12D0, "REV = big-endian key load"),
(0x3B6A, "WFI = enter low-power"),
# Boot stage markers
(0x21B6, ">>> STAGE 0x23: crypto init"),
(0x21D2, ">>> STAGE 0x24: load BL1"),
(0x222A, ">>> STAGE 0x25: load BL2"),
(0x22A0, ">>> STAGE 0x26: verify sigs"),
(0x234C, ">>> STAGE 0x27: NAND config"),
(0x2430, ">>> STAGE 0x28: display/IO"),
(0x249A, ">>> STAGE 0x29: key derive"),
(0x25BE, ">>> STAGE 0x2A: NAND BL"),
(0x2634, ">>> STAGE 0x2B: verify NAND"),
(0x26A8, ">>> STAGE 0x2C: final stage"),
(0x2700, ">>> STAGE 0x2D: prep exec"),
]
ecnt = 0
for off, text in INLINE_COMMENTS:
try:
cu = listing.getCodeUnitAt(addr(off))
if cu:
cu.setComment(CodeUnit.EOL_COMMENT, text)
ecnt += 1
except:
pass
print(" Renamed %d internal labels, added %d EOL comments" % (ren, ecnt))
# ============================================================================
# SUMMARY
# ============================================================================
print("\n" + "=" * 70)
print(" ANALYSIS COMPLETE!")
print("=" * 70)
print("")
print(" Functions labeled: ~90")
print(" Signatures set: ~75")
print(" Equates applied: %d (instructions + data)" % (applied + data_applied))
print(" Literal pools named: %d" % pool_count)
print(" Internal labels: %d" % ren)
print(" Inline comments: %d" % ecnt)
print(" Custom types: 7 enums + 3 structs in /XboxOne")
print("")
print(" Next steps:")
print(" 1. Analysis -> Auto Analyze (for best results)")
print(" 2. Right-click constants -> Set Equate (enums in dropdown)")
print(" 3. Right-click variables -> Retype -> search MMIO_REG etc.")
print("")
print(" Key Registers:")
print(" 0x07800404 = debug output (error codes visible here)")
print(" 0x07801004 = boot stage progress (0x22-0x2E)")
print(" 0x078000F0 = boot status (0xE8-0xEF = boot source)")
print(" 0x0003B004 = anti-glitch accumulator")
print(" UDF #0xFB = fatal security trap")
print("")
print(" MMIO Memory Map:")
print(" 0x0003B000-0x0003D000 = SRAM (canary, accumulator, stack, regs)")
print(" 0x00039000 = Crypto byte counter")
print(" 0x00F00000 = Crypto engine SRAM (I/O)")
print(" 0x01000000 = NAND flash controller")
print(" 0x01024000 = Fuse calibration registers")
print(" 0x01028000 = Hash accelerator")
print(" 0x01080000 = SoC configuration")
print(" 0x010A0000 = PCIe/SerDes")
print(" 0x07008114 = Clock gate control")
print(" 0x07800000 = System control / power")
print(" 0x07801000 = Clock / status registers")
print(" 0x07802000 = Timer / PLL control")
print(" 0x07820000 = Crypto/security engine")
print(" 0x07830000 = Memory controller timing")
print(" 0x07850100 = eFuse banks (x6)")
print(" 0x07860000 = Security processor / fuse straps")
print(" 0x07860400 = I2C controller")
print(" 0x07860500 = SMBus controller")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment