diff options
| author | user <user@clank> | 2026-10-09 16:11:31 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-10-09 16:11:31 +0200 |
| commit | bc43149d914325e15dc0490dee9d982e21287623 (patch) | |
| tree | a632cf70de742d5a60d01c9c0d806bf5b9257538 /fw/verify_gcp_loggates_fault.py | |
| parent | GCP->ASD 0x403: ASD-internal chain PROVEN end-to-end in emulator (real handlers) (diff) | |
| download | amd-psp-re-main.tar.gz amd-psp-re-main.tar.xz amd-psp-re-main.zip | |
Diffstat (limited to 'fw/verify_gcp_loggates_fault.py')
| -rw-r--r-- | fw/verify_gcp_loggates_fault.py | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/fw/verify_gcp_loggates_fault.py b/fw/verify_gcp_loggates_fault.py new file mode 100644 index 0000000..05a376e --- /dev/null +++ b/fw/verify_gcp_loggates_fault.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Offline check of preserved log-gate fault frame against signed GCP .77. + +No hardware access. This identifies word2 as the faulting instruction; word0 +is a known build-specific constant, not the program counter of this fault. +""" +from pathlib import Path +import struct + +from capstone import CS_ARCH_ARM, CS_MODE_ARM, Cs + +ELF = Path(__file__).resolve().parents[1] / 'psp_out/versions_win/elf_all/gcp_22.0.0.77_7c426e7f.elf' +FRAME = (0x4055D8, 0x25031016, 0x4011D8, 0x867, 0x42CFA0, 0, 0x8DA7463D) + + +def file_offset(image: bytes, va: int) -> int: + assert image[:6] == b'\x7fELF\x01\x01' + phoff = struct.unpack_from('<I', image, 28)[0] + size, count = struct.unpack_from('<HH', image, 42) + for i in range(count): + typ, off, base, _, length, _, flags, _ = struct.unpack_from( + '<8I', image, phoff + size * i) + if typ == 1 and flags & 1 and base <= va < base + length: + return off + va - base + raise ValueError(f'VA 0x{va:x} is not in an executable file-backed PT_LOAD') + + +def main() -> None: + image = ELF.read_bytes() + pc, fsr, far = FRAME[2:5] + off = file_offset(image, pc) + ins = next(Cs(CS_ARCH_ARM, CS_MODE_ARM).disasm(image[off:off+4], pc, count=1)) + assert (ins.address, ins.mnemonic, ins.op_str) == ( + pc, 'stmmi', 'r0!, {r3, r4}'), (hex(ins.address), ins.mnemonic, ins.op_str) + status = (fsr & 0xf) | (((fsr >> 10) & 1) << 4) + assert status == 7 and fsr & (1 << 11) and far == 0x42CFA0 + print(f'word2=0x{pc:08x}: {ins.mnemonic} {ins.op_str}; ' + f'DFSR FS={status} (translation), write=1, FAR=0x{far:08x}') + print(f'word0=0x{FRAME[0]:08x}: build constant, NOT this faulting PC') + + +if __name__ == '__main__': + main() |
