Files
Snapintosh/tools/capture-exec-frame.py
T
Acelogic 1510d8c6ce Snapintosh public release
An EL2 monitor/hypervisor and toolchain that boots macOS 27 on the ASUS A16
(Snapdragon X2 Elite), with an Adreno Metal plug-in and IOGPU kext, and
air2ir3, an AIR to Mesa ir3 shader compiler.

MIT, with GPL-2.0 components listed in LICENSE and THIRD_PARTY_NOTICES.md.
No Apple, Qualcomm, ASUS or Microsoft binaries are included.
2026-10-21 21:26:36 -04:00

63 lines
3.4 KiB
Python
Executable File

#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
"""Read the stopped USER_EXEC request's frame, bound to its audited monitor."""
import argparse
import hashlib
import json
import runpy
from pathlib import Path
import struct
import sys
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/'probes'))
import run
def main():
ap=argparse.ArgumentParser(description=__doc__)
ap.add_argument('--device',required=True);ap.add_argument('--prefix',required=True)
args=ap.parse_args()
if not args.prefix or any(c not in 'abcdefghijklmnopqrstuvwxyz0123456789-' for c in args.prefix):
raise ValueError('invalid artifact prefix')
base=ROOT/'build'/args.prefix
audit=json.loads(Path(f'{base}-audit.json').read_text())
stop=json.loads(Path(f'{base}-cpu3-stop.json').read_text())
runtime=json.loads(Path(f'{base}-result.json').read_text())
registers={int(k):int(v,16) for k,v in stop['registers'].items()}
if (stop['cpu'],stop['pc'],registers[1],registers[2],registers[3])!=(
3,'0xfffffe000c22b3c8',11,14,0):raise ValueError('not the reached USER_EXEC request')
pa=registers[0];g=audit['geometry']
if pa&16383 or not g['alloc_low']<=pa<g['alloc_high']:raise ValueError('frame outside allocation')
proxy=run.connect(args.device,tries=1)
try:
info=proxy.bootinfo();blob=(ROOT/'build/xnuboot.bin').read_bytes()
def read(pa,size):
return b''.join(proxy.readmem(pa+i,min(65536,size-i),live=True)
for i in range(0,size,65536))
if hashlib.sha256(blob).hexdigest()!=audit['monitor_sha256'] or read(info['heap_base']+run.CODE_AT,len(blob))!=blob:
raise ValueError('resident monitor differs')
layout=runpy.run_path(str(ROOT/'tools/secondary-runtime.py'))
work, work_size = run.resident_work(proxy, info)
service=struct.unpack('<8Q',read(work+layout['SERVICES_OFFSET'],64))
if list(service)!=audit['service'] or service[1]!=0x100000004:
raise ValueError('CPU3 no longer owns the audited stop')
cpu=work+layout['VCPUS_OFFSET']+3*layout['VCPU_SIZE']
output=struct.unpack('<Q',read(cpu+8,8))[0]
if output&4095 or not work<=output<=work + work_size-4096:
raise ValueError('CPU3 output outside work area')
words=next(row['output_words'] for row in runtime['cpus'] if row['slot']==3)
if read(output,352)!=struct.pack('<44Q',*words):
raise ValueError('CPU3 stopped register snapshot changed')
metadata_pa=g['frame_map']+((pa-g['frame_low'])>>14)*16
metadata=read(metadata_pa,16);payload=read(pa,16384)
if metadata[2]!=11:raise ValueError('frame changed since refused request')
result=dict(cpu=3,pc=stop['pc'],pa=hex(pa),old_type=11,new_type=14,options=0,
monitor_sha256=audit['monitor_sha256'],metadata_pa=hex(metadata_pa),
metadata_hex=metadata.hex(),ro_refs=struct.unpack_from('<I',metadata,8)[0],
other_refs=struct.unpack_from('<I',metadata,12)[0],
payload_sha256=hashlib.sha256(payload).hexdigest(),prefix_hex=payload[:64].hex(),
intended_user_va=hex(registers[24]),candidate_pte=hex(registers[21]))
finally:proxy.link.close()
out=Path(f'{base}-exec-frame.json');out.write_text(json.dumps(result,indent=2)+'\n')
print(json.dumps(result));print(out)
if __name__=='__main__':main()