diff options
| author | Peter Geissler <peter@haxx.in> | 2026-09-22 11:14:57 +0200 |
|---|---|---|
| committer | Peter Geissler <peter@haxx.in> | 2026-09-22 11:14:57 +0200 |
| commit | 649992b26c75eb13ace40c6eec499895a69a1132 (patch) | |
| tree | 09bfb3ac77a3cc3462d9e2972a678da246cefeb4 /psp_out/guard_sweep.py | |
| download | amd-psp-re-649992b26c75eb13ace40c6eec499895a69a1132.tar.gz amd-psp-re-649992b26c75eb13ace40c6eec499895a69a1132.tar.xz amd-psp-re-649992b26c75eb13ace40c6eec499895a69a1132.zip | |
Initial import: AMD PSP reverse engineering, emulator and vulnerability research
Split out of a tinygrad working tree, where all of this lived untracked.
tinygrad remains a dependency for hardware-facing scripts only.
Contents:
psp_emu/ Unicorn-based PSP emulator that boots the real signed firmware from
the ARM reset vector: sOS -> SYS_DRV -> HDCP/DTM/RAS TAs, with a CCP
crypto device model faithful enough to run the firmware's own
drivers (RSA-PSS/SHA-256 container verification passes 5/5 with
5/5 negatives rejected). A simulated host drives the real
mailbox/ring path through to TA_InvokeCommandEntryPoint.
psp_out/ Static analysis: six PSP modules fully named (asd 1562, sys_drv
1141, sos 527, ras 119, hdcp 109, dtm 14) plus SMU 1033, a
cross-version diffing pipeline over 34+ builds, per-handler
annotated analysis and ~125 findings documents.
Deliberately not tracked: AMD firmware images, the Hex-Rays decompilation
derived from them, and IDA databases. data/MANIFEST.sha256 pins the SHA-256 of
all 301 blobs results were derived from, so findings remain traceable to their
inputs without redistributing AMD code. 6 MB tracked instead of 315 MB.
Verified from the new location: test_smoke 5/5, ccp_selftest 11/11,
verify_real_image 5/5 + 5/5 negatives, fuzz_ta_invoke controls passing and
host-driven TA invoke working (0.73s per invoke).
Diffstat (limited to 'psp_out/guard_sweep.py')
| -rw-r--r-- | psp_out/guard_sweep.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/psp_out/guard_sweep.py b/psp_out/guard_sweep.py new file mode 100644 index 0000000..4148782 --- /dev/null +++ b/psp_out/guard_sweep.py @@ -0,0 +1,50 @@ +"""Full corrected added-guard sweep across every module's version chain. + +High-signal filter: only COMPARISON instructions (cmp/cmn/tst), and only +constants that go 0 -> N (newly introduced), which is the strongest evidence of +an added check. Alignment-aware decode (linear sweep misaligns Thumb). + +Validated against ground truth: must rediscover the sOS CCP guard +(cmp #0xcb00000, 0 -> 1, at .51 -> .52). +""" +from capstone import * +import glob,os,collections,sys +md=Cs(CS_ARCH_ARM,CS_MODE_THUMB) +CMPS={'cmp','cmp.w','cmn','cmn.w','tst','tst.w'} +def census(path): + d=open(path,'rb').read() + c=collections.Counter() + for off in range(0,len(d)-4,2): + ins=list(md.disasm(d[off:off+4],off)) + if not ins: continue + i=ins[0] + if i.mnemonic not in CMPS or '#' not in i.op_str: continue + try: v=int(i.op_str.rsplit('#',1)[1],0) + except Exception: continue + if v<0x40: continue # skip small loop/flag constants + c[v]+=1 + return c +def chain_report(name, ordered): + print("="*84); print("%s (%d builds)"%(name,len(ordered))); print("="*84) + prev=None; prevlbl=None + for lbl,p in ordered: + cur=census(p) + if prev is not None: + new=[(v,cur[v]) for v in cur if prev.get(v,0)==0 and cur[v]>0] + new.sort(key=lambda t:-t[0]) + if new: + print(" %s -> %s : %d newly-introduced comparison constant(s)"%(prevlbl,lbl,len(new))) + for v,n in new[:10]: + star=" <<<" if v>=0x10000 else "" + print(" cmp #%-12s x%d%s"%(hex(v),n,star)) + else: + print(" %s -> %s : none"%(prevlbl,lbl)) + prev=cur; prevlbl=lbl + print() +# sOS chain (includes the newly recovered .52) +sos=[('.37','versions/sos_0.49.0.37_b4f5f2ea.bin'),('.41','versions/sos_0.49.0.41_6504d3cc.bin'), + ('.47','versions/sos_0.49.0.47_3be1d3af.bin'),('.48','versions/sos_0.49.0.48_d725e285.bin'), + ('.49','versions/sos_0.49.0.49_fc2d5fa0.bin'),('.50','versions/sos_0.49.0.50_e4bc4b17.bin'), + ('.51','versions/sos_0.49.0.51_14039a1f.bin'), + ('.52*','versions_lfw/sos_3fd1d56b0467c5ea_98944.bin'),('.54','versions/sos_0.49.0.54_3dcb63e8.bin')] +chain_report("sOS", sos) |
