mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-09-02 02:34:29 +00:00
The 26.5 implementation embedded multiple build-specific values: - a hardcoded byte offset 1056 to find `_sSourceList` - a hardcoded stack-frame offset (#576) in the per-source filter scan - hardcoded ivar offsets 0x08/0x18/0x10/0x18/0x48 on BWFigCaptureDevice / BWFigCaptureStream - hardcoded image VMAs 0x1ae6ff05c, 0x1ae2bd414, 0x1ae2c353c for three error-suppression byte-patches - two `#if 0` blocks pinning more 0x1ae* VMAs Refactor every site to a runtime-resolved equivalent. 1. _sSourceList: structural ARM64 anchor chain rooted at the exported FigCaptureSourceServerStart symbol — every link is a stable pattern that survives DSC byte-offset shifts, stub-call layout changes, and LC_SYMTAB local-symbol stripping: FigCaptureSourceServerStart (exported, retained on every build) walk for `cmn x?, #0x1 ; b.ne <wrapper>` (onceToken check) wrapper (single-insn `bl <cold.1>` site) cold.1 (static helper; 5-6 instructions) `adrp x1, ... ; add x1, x1, #imm` (block-constant addr) block constant (struct __Block_literal in __DATA_CONST) +0x10 = invoke pointer (PAC-stripped) = dispatch_once body init block-invoke walk for `bl <X> ; adrp + str x0, [Xn, #imm]` pairs (each "store fn result into a static global") pick the first slot whose stored value is a heap CFArray (filters the lock-store at #0 — that's a void* mutex handle, not an array) LC_SYMTAB is still consulted first as a fast deterministic path for builds that happen to retain `_sSourceList` as a regular nlist entry; the structural chain is what actually fires on stock 26.1/26.3.1/26.5 DSCs (which strip static data symbols). 2. Per-source filter LDR x2 anchor: mask the imm12, accepting any sp-relative 64-bit load into x2 regardless of the compiler-chosen stack-frame slot. 3. BWFigCaptureDevice / BWFigCaptureStream ivar offsets: resolved at synth-class init via class_getInstanceVariable + ivar_getOffset on the parent class. Required ivars (deviceID, portType, uniqueID) abort class registration on miss; the streaming BOOL is optional (skip the YES poke instead of aborting). New vcc_resolve_ivar helper walks a NULL-terminated candidate-name list to tolerate underscore-prefix convention differences. 4. -[FigCaptureCameraSourcePipeline requiresMasterClock] prologue: resolved via LC_SYMTAB by name (two underscore-prefix variants), PAC-stripped, gated on a `pacibsp` insn1 sanity anchor before rewriting to `mov w0, #0 ; ret`. The function isn't in the ObjC method table on observed builds (so class_replaceMethod won't intercept) — the byte-patch is the only working path. 5. _cs_addObjectToStreamsAttributes and -[BWFigVideoCaptureStream initWithCaptureStream:…] -12783 bail sites: both prepare the OSStatus via MOVN encodings (0x12863dd4 for w20, 0x12863dc8 for w8). The new vcc_scan_and_patch helper finds every occurrence of each encoding in __text and rewrites it to MOVZ #0. -12783 is a capture-specific OSStatus and the daemon's only consumer in the VM is the synth source, so over-application is benign. Validator fixes (kept from the original 26.1/26.5 work): - arm64e ISA class-pointer mask: 0x00007FFFFFFFFFF8 (44-bit class field, bits 3-46) per libobjc's ISA_MASK. The previous mask captured bit 47 (magic-signature region), so two pointers to the same class produced different masked values when bit 47 differed. - Pointer dereferences during slot validation gated by `malloc_zone_from_ptr` so a stale/bogus heap pointer in a candidate slot can't trap the daemon during init. (vm_read / vm_read_overwrite were considered but cameracaptured's sandbox returns KERN_DENIED on intra-task vm_read on iOS 26.x.) Helpers in scripts/vcamcaptured/libvcamcaptured.m: vcc_safe_read_ptr pointer-read wrapper vcc_slot_value_is_cfarray malloc_zone + ISA-class check vcc_collect_call_then_store_globals walk a function body for "BL <X>; adrp + str x0, [Xn, #imm]" pairs vcc_resolve_ivar class_getInstanceVariable wrapper with candidate-name list vcc_scan_and_patch __text scan + per-occurrence vcc_patch_word wrapper VCC_ISA_CLASS_MASK arm64e 44-bit class-pointer mask The two dead `#if 0` byte-patch blocks (referencing 0x1ae2b5284 and 0x1ae2b4c90, with the captureSession_buildGraphWithConfiguration thumbnail / preview-sink bail-bypass commentary) are removed along with their explanatory comments. scripts/cfw_install_exp.sh's comment that mistakenly described a non-existent "Patch #6" inside _captureSourceServer_handleCopySourcesMessage is rewritten to describe the actual DSC patches (NU short-circuit + AVF authorization, both already version-agnostic via `ipsw dyld symaddr`). Validated end-to-end on: iOS 26.1 build 23B85 iOS 26.3.1 iOS 26.5 build 23F77 All three return the same `vphone:vcam:0` synthetic camera as the default video device and deliver real JPEG frames through the modern AVCapturePhoto delegate path in continuitycaptured / Camera.app. Co-Authored-By: Claude Opus 4.7 <[email protected]>