Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

recon - BC-250 firmware analysis toolkit

A single CLI plus curated chip data for BC-250 hardware research. 43 subcommands, 64 python modules, ~110 atlas data files, 457 tests.

Five tracks share one tool:

  1. Per-firmware analysis - scan / map / target / disasm a firmware blob (PSP_TOS, ABL0..N, PMFW, UMC_FW, ...) into a versioned research-map.
  2. Chip-wide atlas - queryable hardware schematic for the whole part (IP blocks, mailboxes, msgids, feature mask, driver gates, live silicon state); emits JSON + Markdown + interactive HTML with 10 Mermaid diagrams. Drives kernel-patch generation and wiki publishing.
  3. SPI boot-trace analysis - analyses pico2-spi-tap captures against a BIOS image, classifies blobs by read pattern, surfaces re-read windows, simulates firmware-substitution logic before flashing.
  4. PSP triage - LIVE/DEAD classification for ring-cmd handlers, SVC dispatch tables, TBB jump tables, USR-controlled write destinations, caller chains, SVC-name recovery.
  5. BIOS / envelope tooling - PSP firmware-directory parser, $PS1 signed-envelope decode + repack, ABL stage characterization, APCB v3 parser + checksum-preserving editor, UEFI FV/FFS parser.

Quickstart

bin/recon doctor                  # health check (run this first)
bin/recon tools                   # categorized index of every probe (NEW)
bin/recon tools --ns bios         # one namespace
bin/recon tools --grep apcb       # substring filter

bin/recon profiles                # list known firmware targets
bin/recon atlas                   # chip-wide hardware schematic (default: bc250)
bin/recon atlas --probe           # … and pull live state from the chip via SSH

recon tools is the canonical tool index — same data the MCP server exposes, grouped by namespace. Use it to discover what's available without reading source.

Per-firmware analysis:

bin/recon scan --profile psp_tos              # full audit + bridges + MMIO snapshot
bin/recon map  --profile psp_tos              # parse outputs → research-map.{json,md}
bin/recon target                              # ranked next-step findings
bin/recon disasm 0x031f8                      # Thumb-2 disassembly with annotations
bin/recon disasm-fn --input <fw> --addr 0x11920

SPI MITM trace analysis:

bin/recon spi-trace --trace boot1.csv --bios $BIOS                  # baseline classify
bin/recon spi-trace --trace boot1.csv --bios $BIOS --rereads        # TOCTOU window surfacer
bin/recon spi-trace --trace boot1.csv --bios $BIOS --simulate-mitm  # dry-run Mode B logic

Tool index (auto-generated)

Canonical inventory generated from the ProbeSpec registry. Refresh with recon docs sync; CI guards against drift via recon docs check. For interactive filtering, use recon tools (--ns, --grep, --cli, --tier, --summary, --explain-tiers, --json).

Auto-generated by recon docs sync from the ProbeSpec registry. 57 probes across 11 namespaces. Do not edit by hand — run recon docs sync to refresh.

atlas/ — chip-wide hardware schematic + queries + diffs

Tier MCP probe CLI subcommand Description
T0 atlas recon atlas Chip-wide hardware schematic; emits JSON+Markdown+HTML.
T0 atlas_diff recon diff Diff two research-maps.
T0 atlas_query recon query Point lookup over a run's research-map.

bios/ — BIOS / envelope tooling (PSP-dir, $PS1, ABL, APCB, extract)

Tier MCP probe CLI subcommand Description
T0 bios_abl_decoder recon abl-decoder ABL stage characterization.
T0 bios_apcb_audit recon apcb Audit APCB against AMD baseline; detect stripped groups (CCXG/GNBG silicon-segmentation signal) + count post-Robin5 CBS Token-Pair records.
T0 bios_apcb_diff recon apcb Diff two APCBs with per-group annotation. Useful for Robin1/3/5 version-skew, BIOS-vs-chip_now identity, population fingerprinting.
T0 bios_apcb_info recon apcb Parse APCB header + list groups + verify checksum.
T0 bios_extract recon extract Pull PSP firmware-directory entries from a BIOS image (list or extract by type).
T0 bios_extract_fw recon extract-bios-fw PSP firmware-directory parser ($PS1, BHD) → extract blobs.
T0 bios_ps1_envelope recon ps1-envelope Decode signed $PS1 envelope.
T0 bios_ps1_repack recon ps1-repack Repack $PS1 envelope (in-memory bytes only — no flash write).
T0 bios_uefi recon uefi UEFI Firmware Volume + FFS parser + SMM-surface scanner. Inventories PEIMs/DXE drivers in AGESA.fv for AGESA pre-boot analysis.

board/ — board-level reads (PCIe, I2C, PMBus, hwmon, sensors)

Tier MCP probe CLI subcommand Description
T0 board_debug_survey (MCP only) Static UART/JTAG survey from atlas yaml — does NOT probe.
T1 board_hwmon_snapshot (MCP only) Always-safe hwmon snapshot — preferred over chip_gpu_metrics during workload.
T1 board_i2c_adapters (MCP only) Visible i2c adapters incl. amdgpu-exposed.
T2 board_i2c_walk (MCP only) i2cdetect -y -r address probe (read-only quick).
T0 board_pcie_inspect (MCP only) PCIe topology / config (read-only) / AER counters.
T2 board_pmbus (MCP only) PMBus identify + telemetry register reads.
T0 board_sensors_inventory (MCP only) lm_sensors registered hwmon devices.
T1 board_smi_cmd_port (MCP only) Real SW-SMI command port from FADT SMI_CMD (BC-250 = 0xB0, NOT 0xB2).

chip/ — live chip reads (SMN, PSP MP9, GPU metrics)

Tier MCP probe CLI subcommand Description
T2 chip_nvar_read (MCP only) Resolve & read an AMI NVAR (UEFI) variable's current value from flash via SMM.
T7 chip_nvar_set (MCP only) Set a byte in an AMI NVAR variable via SMM (NVAR-append) — writes the store; gated.
T2 chip_smiflash_read (MCP only) Read SPI flash at a chip offset via SMM (no external programmer).
T7 chip_smiflash_write (MCP only) Write SPI flash via SMM — BRICK-CLASS; classifier-refused without override.
T2 chip_smn_read (MCP only) Single SMN read at vetted addr (tier varies by addr).

docs/ — README auto-generation from the ProbeSpec registry

Tier MCP probe CLI subcommand Description
T0 docs_check recon docs CI guard: exit non-zero if README's AUTO-GENERATED tool-index block is stale relative to the registry.
T0 docs_sync recon docs Rewrite README.md AUTO-GENERATED tool-index block from the ProbeSpec registry. Run after adding/removing probes.

doctor/ — host health check

Tier MCP probe CLI subcommand Description
T0 doctor recon doctor Health check (deps + target reachable + atlas schema valid).

fw/ — firmware static analysis (PSP/SMU/ABL disasm, strings, callers)

Tier MCP probe CLI subcommand Description
T0 fw_annotate recon annotate Annotate disasm with pool literals and branch targets.
T0 fw_disasm recon disasm Annotated Thumb-2/ARM32 disasm at addr.
T0 fw_disasm_fn recon disasm-fn Single-function disasm; stops at epilogue.
T0 fw_dump recon dump Full-firmware disasm corpus.
T0 fw_dump_strings recon dump-strings Printable-ASCII extraction.
T0 fw_find_abs_writer recon find-abs-writer Absolute-address writer detector.
T0 fw_find_bl recon find-bl BL/BLX call sites to a target address.
T0 fw_find_callers recon find-callers BL/BLX caller chain up from a target (detects boot-init-only handlers).
T0 fw_find_imm recon find-imm Every insn carrying a given immediate.
T0 fw_find_stride_writer recon find-stride-writer Strided writer detector.
T0 fw_find_svc recon find-svc SVC sites (omit ID to enumerate all).
T0 fw_find_writer recon find-writer Funcs writing target value to kernel addr - PSP handler call-chain analysis.
T0 fw_map recon map Fold scan outputs into research-map.{json,md}.
T0 fw_psp_ring_handlers recon ring-cmd-triage Ring-cmd handler LIVE/DEAD classification.
T0 fw_psp_svc_dispatch recon dump-svc-table Static PSP SVC dispatch table extract.
T0 fw_psp_tbb_table recon dump-tbb-table PSP TBB (Trusted Boot Block) jump-table extract.
T0 fw_scan recon scan Full scanner audit + bridges + MMIO snapshot. Creates runs//.
T0 fw_scope_dispatcher recon scope-dispatcher USR scope dispatcher analysis.
T0 fw_scope_handler recon scope-handler USR scope handler classification.
T0 fw_strings recon strings Printable-string sweep over a run/profile.
T0 fw_ta_scan recon ta-scan Caller-dest write-path scanner: find PSP SVC handlers that write to a USR-r0/1/2/3-derived kernel address. Supports PSP handler research. Subcommands: run, analyze.
T0 fw_target recon target Rank next-step findings (P1/P2/P3).
T0 fw_trace_svc_names recon trace-svc-names Auto-identify PSP/AGESA SVC numbers from Svc_* log strings via ADR back-walk. Emits name -> SVC# mapping.

memory/ — memory tools (researcher memory reorg)

Tier MCP probe CLI subcommand Description
T0 memory_reorg (MCP only) Fold researcher's claude-memory into ariel-memory under BC-250 tree.

profiles/ — known firmware profiles registry

Tier MCP probe CLI subcommand Description
T0 profiles_list recon profiles Known firmware profiles.

safety/ — safety oracle (probe classifier, liveness, rules)

Tier MCP probe CLI subcommand Description
T0 safety_classify_probe recon classify-probe The planning oracle. Returns tier/refused/safer_alternatives for a candidate probe.
T0 safety_list_probes recon list-probes Filterable view of all registered probes — backed by recon.registry.filter_by.
T0 safety_liveness_check recon liveness ssh + hwmon responsive sentinel against a target host.

spi/ — SPI trace analysis (TOCTOU windows, Mode B simulation)

Tier MCP probe CLI subcommand Description
T0 spi_trace recon spi-trace Baseline classifier / TOCTOU surfacer / Mode B dry-run for pico2 SPI traces.

Subcommand cheat sheet (hand-curated, flag-level)

The auto-generated table above is the source of truth for which probes exist. The cheat sheet below adds CLI flag-level usage notes; refer to recon <cmd> --help for the authoritative flag set.

Per-firmware analysis

Subcommand Purpose
scan Run full scanner audit + bridges + MMIO snapshot. Creates runs/<profile>/<ts>/. Flags: --profile, --fw, --svcs, --no-mmio, --audit-arg (repeatable).
map Fold scan outputs into research-map.json + research-map.md.
target Rank next-step findings (P1 boot-only MMIO publishers, P2 high-fanin convergence, P3 unannotated crypto hits). --write-back patches findings into the map.
query Point lookup: query func 0x031f8, query mmio MP0_C2PMSG_64, query site 0x11920, query find aes. JSON or text.
diff Diff two research-maps (a b, run dirs or research-map.json files).
disasm Annotated Thumb-2/ARM32 disasm at an address (--len, --arm). Resolves pool literals + branch targets, marks SVCs + writes.
disasm-fn Single-function disasm (--input, --addr, `--mode thumb
dump Full-firmware disassembly corpus (--gaps includes scanner-gap regions, --raw adds linear-sweep).
dump-strings Printable-ASCII extraction (--min-len, --max-len, --dotted, --json).
strings Printable-strings sweep over a run/profile (--min, --grep).
find-bl BL/BLX call sites to a target address.
find-imm Every insn carrying a given immediate.
find-svc SVC sites (omit ID to enumerate all).
find-callers Trace BL/BLX caller chain up from a target (--depth, default 6). Detects boot-init-only handlers (zero-caller chain ends).
find-writer Functions writing a target value to a kernel address (--any-value, --usr-dst for USR-arg-derived destinations). PSP handler call-chain analysis.
find-abs-writer Writes to a specific absolute address. Searches pool literals, movw+movt, indirect writes via base+offset (--addr, --offset, --mode thumb,arm).
find-stride-writer Writes at offset N of a stride-indexed table base (--base, --stride, --offset, --value).
annotate Persistent annotation sidecar (annotations/<profile>.json). Subcommands: func, const, svc, slot, show, path.
profiles Inspect firmware-target registry. Subcommands: list, show NAME.
doctor Health checks (profiles, scanner, run state, firmware availability, kernel match). --deep adds default-firmware + extra probes. --check-tools audits module → CLI → MCP coverage. --json for CI.
tools Categorized index of every registered probe (CLI + MCP). Filters: --ns, --grep, --cli, --tier, --summary, --explain-tiers, --json.
docs README auto-generation from the ProbeSpec registry. Subcommands: sync (rewrite the AUTO-GENERATED block), check (CI guard against drift), print (emit block to stdout).

Chip-wide atlas

Subcommand Purpose
atlas Build chip-wide hardware schematic. See recon atlas for the full flag surface.

SPI MITM analysis

Subcommand Purpose
spi-trace Classify SPI flash trace blobs vs BIOS layout, surface TOCTOU re-reads, simulate Mode B firmware, emit C / CDC target tables, diff against baseline. See recon spi-trace.

PSP triage

Subcommand Purpose
ta-scan Caller-dest write-path scanner; finds SVC handlers that write to USR-controlled kernel addrs. Subcommands: run (sweep), analyze (classify hits in existing scan dir). Wired to the PSPEMU harness via PSPEMU_HOME + PSP_HARNESS_DIR.
ring-cmd-triage LIVE/DEAD triage of PSP ring-buffer cmd handlers (--tbb-addr, default 0x1057e for BC-250; --count, default 37; --scan bytes per worker).
scope-dispatcher Bulk LIVE/DEAD triage across every entry of a dispatch table (--tbb-addr or --svc-table, --count, --no-follow-stubs).
scope-handler Single-function deep scope (SVCs, BL targets, writes, pool loads, ADR string refs, gate calls, LIVE/DEAD verdict).
trace-svc-names Auto-identify SVC numbers from Svc_* log strings via ADR back-walk; emits name → SVC# mapping.
dump-svc-table Decode PC-relative SVC dispatch jump table (--table, --count, --base-svc).
dump-tbb-table Decode Thumb-2 TBB/TBH dispatch table or --auto find all (--tbh for halfword).

BIOS / envelope tooling

Subcommand Purpose
extract-bios-fw Parse AMD PSP firmware directories from a BIOS image; list and optionally extract each entry (--extract DIR).
ps1-envelope Decode AMD $PS1 signed-firmware envelopes; extract body (--body PATH); optionally --try-decompress.
ps1-repack Rebuild a $PS1 envelope around a modified body. Preserves the 0x100-byte header + 0x100-byte trailer. Accepts --attacker-body (raw replacement body) or --decompressed-body (auto-zlib-compress at levels 9-1).
abl-decoder One-shot ABL{0..N} stage characterization: extract from BIOS, $PS1-decode, decompress, dump strings, classify role. --validate-attacker runs a pre-flash sanity check comparing a modified image against the original.
apcb APCB v3 parser + checksum-preserving editor + group audit + cross-revision diff. Subcommands: info, verify, groups, extract, set-memclk, find-u16, audit, diff. Used to detect Sony's CCXG/GNBG strip on BC-250 / 4800S.
extract Pull PSP firmware-directory entries from a BIOS image; list (default) or extract by type regex (--type, optional --decrypt --uncompress).
uefi UEFI Firmware Volume / FFS parser + SMM-surface scanner. Subcommands: info, list, extract, scan-smm-handlers, scan-swsmi-handlers, find-protocol, scan-spi-wp. Inventories PEIMs/DXE drivers in AGESA.fv for AGESA pre-boot analysis.

recon atlas — chip-wide hardware schematic

Reads curated chip data from data/atlas/<chip>/*.json plus prior per-firmware research-maps and emits a unified artifact.

recon atlas                              # JSON + MD with 10 Mermaid diagrams
recon atlas --html                       # standalone interactive HTML (sidebar nav)
recon atlas --probe                      # add live silicon snapshot (SSH+ioctl)
recon atlas --watch SECONDS              # continuous --probe with diff alerts
recon atlas --snapshot                   # versioned snapshot to snapshots/<chip>/<ts>.json
recon atlas --history                    # snapshot timeline + per-field change frequency
recon atlas --history-detailed           # … plus full per-snapshot diffs
recon atlas --publish-wiki               # upload atlas.md to GitLab wiki
recon atlas --wiki-project-id 5 --wiki-slug BC250-Hardware-Atlas
recon atlas --list-liberation            # prioritized MMIO/feature to-do list (P1..P4)
recon atlas --diff RUN_A RUN_B           # diff two atlas runs
recon atlas --compare bc250 vangogh renoir   # cross-chip msgid mining
recon atlas --query-smn 0xC180           # resolve SMN address → named register
recon atlas --validate                   # JSON-Schema validation against data/atlas/schema.json
recon atlas --psp-ta-scan                # PSP MP9 TA registry analyzer
recon atlas --gen-patch SERIES_ID        # generate kernel patch from atlas data

Output per run (in runs/<ts>-atlas-<chip>/):

  • atlas.json — machine-readable hardware tree (schema v1).
  • atlas.md — Markdown with 10 Mermaid diagrams + per-IP tables + msgid catalog + feature-mask decode + patch-series tracker + live state.
  • atlas.html — standalone HTML with sidebar nav (when --html given).

The 10 Mermaid diagrams

  1. Chip topology (IP blocks clustered by GPU/Memory/MCU/NB-IO)
  2. Mailbox graph (host driver → SMN window → queues → owner IP)
  3. Firmware → IP block map
  4. Driver gates by IP block (pie)
  5. Driver gates by type (ring-emit-skip, tlb-path-skip, ...)
  6. Clock + power tree (rails + domains + SMU actuator hub, DS state colour-coded)
  7. SMN address space (IP-base timeline)
  8. Msgid distribution per queue (pie)
  9. SMU feature mask state (pie: enabled / disabled / unknown)
  10. Feature bits by category (pie: DeepSleep / Throttle / Power / CPU / DPM / …)

A _mermaid_patch_series_status() diagram tracks readiness across the patch-series registry too.

Patch-series codegen

--gen-patch <id> reads data/atlas/<chip>/patch-series.json and emits a real unified-diff .patch. Series registry on BC-250:

ID Name Status Risk
1 message_map expansion (16 MSG_MAP entries from mailbox-msgids.json) verified, built end-to-end, chip post-patch returns expected SMU responses low
2 deep-sleep + GFXOFF wiring pending medium
3 real DPM table pending medium
4 BACO + S3 + GFXOFF callbacks pending high
5 CPU DPM via SetSoftMin/MaxCclk pending low
6 researcher's Q3 surface pending medium
7 IP block enumeration completeness pending low
8 VCN re-enable investigation medium
9 promote MMIO liberation to amdgpu init blocked (WREG32_SOC15 ordering vs RLC/GC/KIQ) high
B1..B6 BAPM/CACW track (sysfs, profiles, baseline, userspace daemon, telemetry learning, upstream wiring) various various

Live-state probing

--probe SSHes to $RECON_BC250_HOST (default project-ariel.local) as $RECON_BC250_USER and reads: PMFW heartbeat (0x3B1054C ~1 kHz tick), PSP debug magic (0xC180), feature mask (0xC71C), MP1 event counter + status, Q0 last cmd/arg, PMFW version, CLK DS state per instance. Output matches the live-state.json schema.

recon spi-trace - SPI boot-trace analyser

Inputs a pico2-spi-tap CSV (timestamp_us,opcode,addr,length,sha256_first16) plus a BIOS image. Cross-references each read against the PSP-directory blob layout from extract-bios-fw and classifies per-blob:

  • SINGLE_READ - read once, no re-read window.
  • VERIFY_THEN_USE - 2+ reads with consistent hash, re-read window present.
  • VERIFY_THEN_USE_INCONSISTENT - 2+ reads with different hashes (substitution active or trace corrupted).
  • CHUNKED_FULL_LOAD - 95%+ coverage via fragments; chunked-load pattern (BC-250 PSP_BL style).
  • PARTIAL - incomplete blob load captured.
  • NEVER_READ - blob present in BIOS but absent from trace.
recon spi-trace --trace boot1.csv --bios $BIOS                       # baseline classify
recon spi-trace --trace boot1.csv --bios $BIOS --rereads             # widest-gap TOCTOU first
recon spi-trace --trace boot1.csv --bios $BIOS --rereads --rereads-min-gap-ms 1.0
recon spi-trace --trace boot1.csv --bios $BIOS --rereads --rereads-region 0x800000:0xac0000
recon spi-trace --trace boot1.csv --bios $BIOS --bus-stats           # PROCEED / PROCEED_RISKY / ABORT
recon spi-trace --trace boot1.csv --bios $BIOS --simulate-mitm --mitm-mask 0x1 --simulate-target ABL0
recon spi-trace --trace boot1.csv --bios $BIOS --analyze-chunks      # per-blob irregular-chunk surfacing
recon spi-trace --trace new.csv   --bios $BIOS --diff-baseline baseline.csv
recon spi-trace --bios $BIOS --synthetic 32 --synthetic-pattern verify_then_use   # offline self-test
recon spi-trace --trace boot1.csv --bios $BIOS --target-table c      # C source for mitm_state.c
recon spi-trace --trace boot1.csv --bios $BIOS --target-table cdc    # USB CDC paste-into-picocom commands

--simulate-mitm dry-runs the Mode B firmware logic against the trace so you can validate --mitm-mask (default 0x1 = use-then-verify pattern; 0x2 = verify-then-use; 0xffffffff = always substitute) and --simulate-target blob filter before flashing pico2.

--diff-baseline is the post-modification verification step: capture a baseline before Mode B goes live, capture again after, diff. Per-blob output: UNCHANGED / READS_COUNT_CHANGED / HASHES_CHANGED / TIMING_CHANGED / NEW_BLOB / MISSING_BLOB. HASHES_CHANGED on your target = strong signal Mode B served different bytes.

--synthetic generates a trace without hardware (verify_then_use, single_read, or mixed patterns) for offline self-test and CI.

Reference traces ship at recon/data/spi-traces/2026-05-25/: boot7-cold.csv, boot8-warm.csv, boot9-cold.csv, boot11-cold-dryrun.csv (~1144 lines total, real BC-250 boots).

Library modules

Importable without going through the CLI:

  • recon.apcb - APCB v3 parser + checksum-preserving editor (matches coreboot apcb_v3_edit.py semantics). Functions: parse_header(), verify_checksum(), recompute_checksum_byte(), find_groups(), parse_groups(), find_u16_le(), set_memclk(), extract_bhd_body_from_bios(). Used to build modified APCB images for Mode B firmware substitution (e.g. MCLK overrides).
  • recon.uefi — FV / FFS / section parser. parse_fv_header(), parse_ffs_files(), parse_ffs_sections(), find_ui_name(), guid_str(). Used by AGESA + BIOS firmware analysis.
  • recon.paths — Hub layout resolver. find_recon_root(), reset_cache(); exports RECON_ROOT, RUNS_DIR, EXTRACTS_DIR, PROFILES_DIR.
  • recon.profiles — Profile loader. list_profiles(), load_profile(name).

Curated chip data

data/atlas/ ships chip-specific JSON sources. JSON-Schema v1 at data/atlas/schema.json (kind: chip-atlas).

  • data/atlas/bc250/ — primary target, 103 JSON files. Core: chip.json, ip-blocks.json, mailboxes.json, mailbox-msgids.json (144 msgids across Q0..Q4), feature-mask.json (64-bit decode), pmfw-tables.json, cacw-surface.json, clock-power-tree.json, smn-registers.json (48 named addresses), patch-series.json (12-series recovery roadmap), driver-gates.json, live-state.json. Per-investigation closed-finding snapshots cover BAPM, MGCG, AVFS, fuse audit, PSP TA registry, build-pipeline forensics, ACPI methods, DCN/DCE display engine audit, KFD compute pipes, microcode introspection, SVI2 voltage surface, DIDT subsystem inventory, GMC/MMHUB/GFXHUB audit, IP-discovery live comparison, MP1 + MP9 SMN region sweeps, CPU MSR snapshot, cross-chip msgid comparison, tier-1 IFR empirical failure, ring-emit-skips audit, gfx-off surface, VCN firmware gap, transfer table SMU↔DRAM probe.
  • data/atlas/vangogh/ — Steam Deck APU sibling. 4 files (chip.json, mailbox-msgids.json with 77 Q0 msgids, ip-blocks.json with 17 IPs, feature-mask.json with 60 bits).
  • data/atlas/renoir/ — Ryzen 4000U/H APU sibling. 2 files (chip.json, mailbox-msgids.json with 56 Q0 msgids).
  • data/atlas/sienna_cichlid/ — RDNA2 discrete-GPU sibling reference. chip.json skeleton only.

Captured / reference data

  • recon/data/spi-traces/2026-05-25/ — 4 pico2-spi-tap reference traces from real BC-250 boots (cold + warm + dryrun).
  • tests/fixtures/sample_mode_a_trace.csv + fixture README; drives test_toctou_pipeline.py.
  • snapshots/bc250/ — timestamped atlas --snapshot outputs for drift detection.
  • profiles/ — firmware-target profile JSONs (bc250-r14.json, psp_tos.json).
  • runs/ — versioned per-run output dirs (gitignored).
  • extracts/extract-bios-fw --extract DIR output staging (gitignored, operator-populated).
  • annotations/ — persistent sidecar (<profile>.json) populated by recon annotate.

Layout

recon/
  bin/recon                          # CLI launcher (delegates to recon.cli:main)
  recon/                             # 64 python modules (including subpackages)
    cli.py                           # subcommand dispatch
    atlas.py                         # chip-wide schematic builder
    spi_trace.py                     # SPI boot-trace analyser
    scan.py / map.py / target.py     # per-firmware workflow
    doctor.py / profiles.py / paths.py
    disasm.py / disasm_fn.py / dump.py
    dump_strings.py / dump_svc_table.py / dump_tbb_table.py
    annotate.py / strings.py / query.py / diff.py
    find_bl.py / find_imm.py / find_svc.py
    find_callers.py / find_writer.py / find_abs_writer.py / find_stride_writer.py
    extract.py / extract_bios_fw.py
    abl_decoder.py
    ps1_envelope.py / ps1_repack.py
    ring_cmd_triage.py
    scope_dispatcher.py / scope_handler.py
    trace_svc_names.py
    ta_scan.py
    apcb.py                          # APCB v3 parser + checksum-preserving editor
    uefi.py                          # FV / FFS / section parser
    data/spi-traces/<date>/          # captured pico2-spi-tap reference traces
  data/
    atlas/<chip>/*.json              # curated chip data (bc250, vangogh, renoir, sienna_cichlid)
    atlas/schema.json                # atlas.json JSON-Schema v1
  tools/share/                       # operator-runnable scripts (5 scripts)
  docs/spec.md                       # original wiki spec (archived)
  profiles/                          # per-firmware profile JSONs
  runs/                              # versioned run dirs (gitignored)
  snapshots/                         # per-chip --snapshot output (gitignored)
  tests/                             # 27 test files, 457 tests
  Makefile / pyproject.toml / .pre-commit-config.yaml / .gitlab-ci.yml

Profiles

Each firmware target lives in profiles/<name>.json. Currently registered: bc250-r14 (PSP_TOS R14 with full board context), psp_tos (generic). Adding a target = drop a JSON file + register a Profile entry in recon/profiles.py referencing _EXTRACTS_P3 / "..." paths.

recon profiles                       # list
recon profiles show bc250-r14        # pretty-print JSON
recon scan --profile bc250-r14       # use it

Tests

457 tests across 27 files. Headline (top 15 by count):

File Tests Coverage
test_atlas.py 67 end-to-end atlas build, diff, compare, patch-series codegen, JSON-Schema validation, snapshot history, HTML / wiki emit
test_imports.py 45 collection-time import smoke pass — every cli.DISPATCH target imports cleanly (auto-grows with new subcommands)
test_toctou_pipeline.py 31 end-to-end BIOS → extract → $PS1 decode → decompress → spi-trace analysis
test_safety.py 28 safety classifier rules + budget + liveness
test_doctor.py 25 health-check scenarios (incl. --check-tools coverage audit)
test_query.py 22 research-map lookups (func, mmio, site, find, annotation fusion)
test_disasm.py 19 Thumb / ARM disasm
test_target.py 18 finding ranking
test_map.py 18 scan-output folding
test_uefi.py 17 UEFI FV/FFS parser + SMM handler scan
test_apcb.py 15 APCB v3 parser + editor, BHD extraction, MCLK override, group audit + cross-revision diff
test_registry.py 15 ProbeSpec registry + tier filtering
mcp/test_server.py 15 MCP server JSON-RPC round-trip + tool registration
test_dump.py 14 full-firmware dumps
test_annotate.py 14 sidecar CRUD

Remaining 12 files cover scan, paths, cli, strings, profiles, find_svc, find_imm, diff, probes/{chip_smn,board}, mcp/dispatch_argparse, and docs drift-guard.

make test                                # all 457 tests
pytest tests/test_atlas.py -v
pytest tests/test_toctou_pipeline.py -v
pytest tests/test_apcb.py -v

Atlas outputs are deterministic (bit-identical across runs modulo the generated timestamp + live-probe values). Determinism guards plus content-correctness tests verify the curated data (feature decode against bitmask, known SMN addresses, MSG_MAP cross-resolution).

Operator tools (tools/share/)

  • atlas-live-probe.sh — probe chip-state claims (feature mask Q0 0x3D, SetCoreEnableMask handler, MP1/PMFW telemetry, gfx state) against atlas baseline; validates DLV-A14, DLV-A52, live-state.json.
  • bc250-checkpoint.sh — comprehensive single-shot BC-250 state capture (Q0 msgid probes, MP1 + PSP SMN telemetry, amdgpu_pm_info, CPU MSRs, hwmon, ip_discovery). Pre/post-liberation diff source.
  • verify-setcoreenable-q0.sh — independently verify SetCoreEnableMask (0x2C) is a HANDLER on BC-250 Q0; safe (arg=0 no-op); reproduces DLV-A52.
  • smn-telemetry-probe.py — SMN-register polling via the AMD MP1 PCI config backdoor (0xB8/0xBC); read-only; reads PMFW heartbeat, MP1 event counter, Q0/Q3 mailbox snapshots.
  • build-and-test-bc250-patch-series.sh — fetch a patch from GitLab MR, rebuild amdgpu out-of-tree, module-swap with auto-rollback, live checkpoint before + after.

Environment

  • RECON_ROOT — override hub directory (default: walk-up to find Makefile + recon/__init__.py).
  • RECON_BC250_HOST — target host for atlas --probe / --watch / --snapshot (default project-ariel.local).
  • RECON_BC250_USER — SSH user for probe commands.
  • GITLAB_URL / GITLAB_TOKEN — for atlas --publish-wiki (read from ~/.config/recon/secrets.env if unset).
  • PSP_INPUTS_DIR — extracted PSP firmware blobs for atlas --psp-ta-scan byte-grep and for ta-scan.
  • PSPEMU_HOME — PSPEMU build root (used by doctor + ta-scan).
  • PSP_HARNESS_DIR — PSP svc-fuzz harness directory (used by ta-scan).
  • BC250_BIOS_DIR — BIOS image directory for extract-bios-fw / spi-trace --bios.
  • PICO_SDK_PATH — pico SDK 2.x for building the pico2 firmware (sources on the share-bc250-patch-build-script branch).

On-ramp: BIOS → atlas

# 1. Extract every interesting entry from a stock BIOS
bin/recon extract-bios-fw \
  --bios $BC250_BIOS_DIR/Robin1.00/Robin1.00 \
  --extract /tmp/bc250-extracts

# 2. Register a Profile in recon/profiles.py pointing at <name>_body.bin

# 3. Scan / map / target / disasm
bin/recon scan   --profile <name>
bin/recon map    --profile <name>
bin/recon target --profile <name>

# 4. Atlas integrates per-firmware research-maps
bin/recon atlas --chip bc250

On-ramp: SPI boot-trace analysis (software side)

# 0. Capture a boot trace with pico2-spi-tap. Wire pico2 GP2..GP5
#    to BC-250 BIOS flash CS#/CLK/MOSI/MISO. Cold-boot BC-250 while
#    `cat /dev/ttyACM0 > boot1.csv` runs on the host.

# 1. Confirm coverage + classify blobs
recon spi-trace --trace boot1.csv --bios $BIOS --bus-stats

# 2. Find re-read windows
recon spi-trace --trace boot1.csv --bios $BIOS --rereads --rereads-min-gap-ms 1.0

# 3. Build a modified firmware image (APCB-mod example) via recon.apcb library
python3 -c 'from recon.apcb import parse_groups, set_memclk; ...'

# 4. Wrap it back into a $PS1 envelope
recon ps1-repack --original ABL0.bin --decompressed-body modified_body.bin --out ABL0_modified.bin

# 5. Dry-run Mode B firmware logic against the trace
recon spi-trace --trace boot1.csv --bios $BIOS --simulate-mitm \
                --mitm-mask 0x1 --simulate-target ABL0

# 6. Emit C target table for the pico2 firmware
recon spi-trace --trace boot1.csv --bios $BIOS --target-table c

# 7. Post-modification verification
recon spi-trace --trace post.csv --bios $BIOS --diff-baseline pre.csv

On-ramp: PSP handler research

# 1. Find SVC handlers that write to USR-controlled kernel addrs
recon ta-scan run --profile bc250-r14

# 2. Triage candidates
recon ta-scan analyze --scan-dir runs/<ts>-ta-scan/

# 3. Drill into a specific handler
recon scope-handler --input <fw> --addr 0x114b8

# 4. Confirm with a focused write-locator
recon find-writer 0x<kernel_addr> 0x<target_value> --usr-dst

On-ramp: PSP dispatch-table triage

# 1. Enumerate the SVC dispatch table
recon dump-svc-table --table 0x45e4 --count 128 --base-svc 0x51

# 2. Auto-find every TBB/TBH table in the firmware
recon dump-tbb-table --auto

# 3. Bulk LIVE/DEAD classify a specific dispatcher
recon scope-dispatcher --input <fw> --tbb-addr 0x1057e --count 37

# 4. Recover SVC names from log strings
recon trace-svc-names --input <fw>

History

  • 2026-05-05 — Original recon codebase lost in forge crash (lived at <workdir>/<path>, never in git). Wiki spec survived; extract.py recovered via decompyle++ (docs/decompiled-extract.py`).
  • 2026-05-06..2026-05-19 — Phase 1.3: per-firmware workflow rebuilt from spec, module-by-module.
  • 2026-05-21 — Phase 2: recon atlas chip-wide hardware schematic shipped over 14 MRs. 10 Mermaid renderers, live-state probing, snapshot / history / diff, JSON-Schema validation, atlas-driven kernel patch generation, wiki publishing, cross-chip msgid mining. Series 1 (message_map expansion) generated + applied + built end-to-end against BC-250.
  • 2026-05-22..2026-05-23 — BC-250 kernel-callers + BAPM + sdpm patch series landed (MRs !11..!27): 23 msgids wired, 25 debugfs entries, 40-CU MMIO restored (+65.6% FP32). MGCG / BAPM compute deadlock characterised + parked. ~30 new closed-finding atlas JSONs.
  • 2026-05-24 - Phase 3 kickoff: in-band PSP handler analysis fully exhausted (10-iter loop closed every field_0 / caller_id path). PSP triage tooling shipped (ta-scan, ring-cmd-triage, scope-dispatcher, scope-handler, trace-svc-names, disasm-fn, find-{callers,writer,abs-writer,stride-writer}, dump-{strings,svc-table,tbb-table}). Pivot to hardware-side SPI boot-trace track.
  • 2026-05-25 - Re-read window for BHD verify-then-use confirmed empirically (12.1s gap between verify-read and use-read of $BHD@0xab1000; sniffer SHA + FIFO fix enabled the finding). spi-trace, extract-bios-fw, abl-decoder, ps1-envelope / ps1-repack, apcb (parser + editor), and uefi (FV / FFS parser) shipped. 31-test test_toctou_pipeline.py covers the spi-trace pipeline end-to-end. Reference boot traces archived at recon/data/spi-traces/2026-05-25/.

References

  • Spec: docs/spec.md
  • AMD PSP documentation: AMD PPR for Family 17h processors
  • SPI boot-trace methodology: based on pAMDora research (39C3)

About

BC-250 firmware analysis toolkit - single CLI + curated chip data for hardware research

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages