Skip to content

CoreDevice internals — research index

Status: verified — 2026-04-30

Topical roadmap through static disassembly, runtime probes, and empirical capture work on macOS CoreDevice.framework, CoreDeviceService.xpc, Mercury.framework, and the Xcode-side DVTCoreDeviceCore consumer.

These docs back up ADR-0009 §Decision (iosmux is a bridge that synthesises an iOS device — no native iOS Pair-Setup against the real device) and Phase D.6.6-impl in stage2.md. Every claim cites an artifact under ADR-0006.

Read order for new sessions

If you are landing here cold, follow this path:

  1. Connection architecture — runtime layout (iPhone, host, VM, tunneld, CDS inject); inject capability inventory; Phase D.6.6-impl backend self-bootstrap chain.
  2. ADR-0009 §Decision — three options A/B/C disposition; Option C (synthesise device, lockdown handler + Mercury Codable interceptor + service-socket interpose) is the path.
  3. Q-D66 research questions — open empirical questions catalog with Resolution log entries (Q-D66-1 through Q-D66-15). The single page that tracks every empirical follow-up.

GAMBIT — Mercury action interceptor (Phase D.6.6-impl sub-task 3)

The piece that intercepts Mercury action invocations from Xcode/devicectl to CDS and synthesises Codable replies for the 15-action allow-list per ADR-0009 §Consequences.

  • Mercury action interceptor design — hook target (CoreDeviceUtilities.invoke(anyOf:usingContentsOf:) at file offset 0xff50 x86_64), inline 13-byte trampoline pattern, reply construction, allow-list, failure-mode passthrough.
  • Mercury envelope empirical — two envelope shapes captured byte-exact: Codable event envelope ({mangledTypeName, value}) and action invocation envelope (flat dict with CoreDevice.actionIdentifier discriminator). Recv-side capture rig details + filter relax.
  • GAMBIT Pair Action schema — byte-level DeviceConnectionChangeResult Codable schema empirically derived through 17 click iterations on havoc. Type-form quirks (xpc_uuid vs xpc_string for UUIDs, xpc_int64 vs xpc_uint64, custom Codable named-key associated values).
  • GAMBIT action outputs + AFM mechanism — per-action Output schemas for the full 15-action allow-list (Phase 1 per-action dispatch); _VoidBox vs _CodableBox<T> vs _CodableBox<DeviceConnectionChangeResult> containers; AFM endpoint side-channel (xpc_endpoint_create / xpc_connection_create_from_endpoint); CDS-side preparedness pipeline; RDSUE event chain; DevicePreparedness OptionSet bits; ProgressUnit raw values.

AUA failure path (Q-D66-15 cosmetic-accept)

Why acquireDeviceUsageAssertion user-visible message says "Failed to acquire assertion" 9-13 ms after the synthetic success reply, even after GAMBIT Phase 1 deploy.

  • AUA side-channel mechanism — D21..D29 evidence chain: V2 verdict (post-reply peer/capability check), D22 corrections to D21 frame addresses, D23 P-1a deploy on ActionConnectionCache.removeCachedXPCConnection (CD+0xdbe0), D24 W4 funnel (assertionq dispatcher with multiple inputs), D25 FORGE plan, D26..D29 invalidation admonition (FORGE deferred indefinitely; cosmetic gap accepted).

Pair button + UI gates

How Xcode renders the Pair button vs. Connected vs. spinner on the device row, and which signals control which transition.

  • Pair button + CFNetwork_shadowUseAssertion.fulfilled gates the Pair button rendering; kvoCache_isPaired Bool ivar gates the spinner state; IDEDeviceSymbolsCoordinator asserts on non-empty osBuildUpdate.name. Two gates, not one.

Action interception — historical synthesis

  • Action interception full picture — pre-empirical research synthesis from three parallel sessions. Carries !!! warning admonitions where empirically falsified by later capture work (e.g. action invocation envelope IS keyed by CoreDevice.actionIdentifier, not the originally-claimed CoreDevice.featureIdentifier).

Stage S1 disassembly research

The disassembly trail that produced Stage S1.A through S1.D landings.

See also