AMFI Bypass Mechanism in vphone-cli: How Unsigned Code Runs in Virtual iOS

vphone-cli neutralizes Apple Mobile File Integrity (AMFI) by patching four distinct kernel gates—launch constraints, trust-cache validation, execve kill paths, and post-validation compares—to allow unsigned binaries to execute inside the virtual iPhone.

The vphone-cli project runs a virtual iPhone inside macOS using Apple’s Virtualization.framework, requiring the neutralization of AMFI code-signing enforcement so that custom firmware (CFW) and unsigned IPAs can boot and execute. This AMFI bypass mechanism is implemented entirely within the kernel-patching layer located in sources/FirmwarePatcher/Kernel, using semantic pattern matching to locate and rewrite critical ARM64 instructions in the iOS kernel image.

How AMFI Blocks Unsigned Code in iOS

Apple Mobile File Integrity (AMFI) is the kernel subsystem responsible for enforcing code-signing policies, launch constraints, and trust-cache validation on iOS. When a process attempts to execute, AMFI verifies that its CDHash exists in the system trust cache and that the binary satisfies the current launch-constraint policy. If any check fails, the kernel immediately terminates the process or rejects the execution attempt, preventing unsigned or modified binaries from running.

The Four AMFI Gates Patched by vphone-cli

The vphone-cli AMFI bypass targets four specific enforcement points in the kernel. Each patch replaces the original logic with a stub that forces success, effectively disabling the security check for the virtual machine environment.

Launch-Constraint Gate (_proc_check_launch_constraints)

The original _proc_check_launch_constraints function returns a non-zero error when the kernel’s launch-constraint policy rejects a process. According to the source code in sources/FirmwarePatcher/Kernel/Patches/KernelPatchLaunchConstraints.swift, the patch rewrites the function entry point to mov w0,#0; ret, forcing the function to return success (zero) regardless of the actual policy evaluation. This allows processes that violate launch constraints—such as those with modified entitlements—to start normally.

Trust-Cache Gate (AMFIIsCDHashInTrustCache)

This gate checks whether a binary’s CDHash is present in the AMFI trust cache, returning 0 (reject) for unknown hashes. In sources/FirmwarePatcher/Kernel/JBPatches/KernelJBPatchAmfiTrustcache.swift, the patcher locates the unique AMFI function body using a semantic instruction pattern rather than hard-coded offsets. It then overwrites the first four instructions with a stub that stores 1 (true) and returns immediately, causing the kernel to treat all hashes as trusted.

Execve Kill Path (Disabled)

The AMFI subsystem hooks execve and uses a MOV W0,#1 instruction to signal a kill (reject) for binaries that fail policy checks. While sources/FirmwarePatcher/Kernel/JBPatches/KernelJBPatchAmfiExecve.swift contains a patch to replace this with MOV W0,#0 (turning the kill into an allow), this specific bypass is currently disabled in the codebase.

Post-Validation Compare Gate

After AMFI’s SHA-256 validation, a cmp w0,#imm; b.ne instruction sequence can still reject binaries that pass the hash check but fail other policy validations. The patch in sources/FirmwarePatcher/Kernel/Patches/KernelPatchPostValidation.swift replaces the compare with cmp w0,w0, which is always equal and therefore neutralizes the conditional branch that would otherwise terminate the process.

Kernel Patching Implementation

All AMFI patches are applied through the KernelJBPatcher (jailbreak variant) or KernelPatcher (regular variant) classes during the custom firmware generation process. The patching workflow implemented in the CFW builder scripts (scripts/patchers/cfw_*.py) follows this sequence:

  1. Load the decrypted kernel image into a mutable buffer.
  2. Use semantic function matching—searching for characteristic ARM64 instruction sequences rather than static memory addresses—to locate the exact AMFI routines.
  3. Emit new instruction encodings (mov x0,#1, cbz x2,+8, str x0,[x2], ret, etc.) at the identified offsets.
  4. Write the patched binary back to disk for the VM to boot.

This pattern-based approach ensures the patches remain functional across different iOS versions and firmware builds without requiring version-specific offset tables.

Swift Code Example: Applying the AMFI Trust-Cache Patch

The following Swift snippet demonstrates how the vphone-cli patcher programmatically applies the trust-cache bypass:

import Foundation

// Assume `kernelBuffer` is a pre-loaded binary image and `patcher` is a KernelJBPatcher.
let patcher = KernelJBPatcher(buffer: kernelBuffer)

// Apply the AMFI trust-cache bypass (returns true on success).
if patcher.patchAmfiCdhashInTrustcache() {
    print("[+] AMFI trust-cache gate successfully bypassed")
} else {
    print("[-] Failed to locate or patch AMFI trust-cache function")
}

// Similarly, the launch-constraint stub can be applied:
if patcher.patchLaunchConstraints() {
    print("[+] Launch-constraint gate stubbed")
}

These methods are invoked internally by Python-based CFW builder scripts such as cfw_patch_xpc_lwcr.py when the jailbreak variant is selected during firmware generation.

Prerequisites and Security Implications

The AMFI bypass mechanism requires System Integrity Protection (SIP) and AMFI disabled on the host macOS, as documented in sources/vphone-cli/VPhoneError.swift and enforced by the preflight script scripts/boot_host_preflight.sh. The VM runs with private entitlements; without neutralizing these kernel gates, the iOS virtual machine would instantly reject any unsigned or re-signed code, preventing IPA installation, dynamic library loading, and developer-mode debugging features. This bypass is strictly limited to the virtualized environment and does not persist on physical devices.

Summary

  • Four AMFI gates are patched: launch constraints (_proc_check_launch_constraints), trust-cache validation (AMFIIsCDHashInTrustCache), execve kill paths, and post-validation compares.
  • Semantic pattern matching locates functions by instruction sequences rather than static offsets, ensuring compatibility across iOS versions.
  • KernelJBPatcher and KernelPatcher classes in sources/FirmwarePatcher/Kernel/ implement the ARM64 instruction rewriting in Swift.
  • Host prerequisites require SIP and AMFI disabled on macOS for the virtual iPhone to boot the patched custom firmware.
  • Unsigned code execution becomes possible inside the VM, enabling IPA sideloading and dynamic library injection that standard iOS security policies would otherwise block.

Frequently Asked Questions

What is AMFI and why does vphone-cli need to bypass it?

Apple Mobile File Integrity (AMFI) is the iOS kernel subsystem that enforces code-signing and trust-cache validation. vphone-cli must bypass AMFI because the virtual iPhone runs custom firmware and unsigned IPAs that lack valid Apple signatures; without neutralizing these checks, the kernel would terminate any non-system binary immediately upon execution.

Is the AMFI bypass in vphone-cli persistent across iOS updates?

Yes, because the patches rely on semantic function matching (identifying unique instruction patterns) rather than hard-coded memory offsets. As implemented in KernelJBPatchAmfiTrustcache.swift and related files, the patcher searches for characteristic ARM64 sequences to locate AMFI routines dynamically, allowing the mechanism to adapt to new kernel builds without manual offset updates.

Does the AMFI bypass require disabling SIP on the host Mac?

Yes. According to sources/vphone-cli/VPhoneError.swift and the startup routine in scripts/boot_host_preflight.sh, both System Integrity Protection (SIP) and AMFI must be disabled on the host macOS for the virtual iPhone to boot and execute unsigned code. This is a strict prerequisite for the kernel-patching strategy to function safely within the virtualized environment.

Can the AMFI bypass be used on physical iOS devices?

No. The bypass mechanism in vphone-cli is designed specifically for the virtualized environment created by Apple’s Virtualization.framework on macOS. The patches target kernel images loaded into memory buffers for VM booting and are not applicable to physical device boot chains, which use entirely different secure boot and hardware-backed signature verification mechanisms.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →