Kernel Patching Tools in vphone-cli: Capstone, Keystone, and pyimg4 Explained
vphone-cli relies on Capstone for ARM64 disassembly, Keystone for instruction assembly, and pyimg4 for IMG4 container manipulation to safely locate, modify, and repackage iOS kernel images.
vphone-cli is an open-source virtualization tool for iPhone hardware that requires surgical modifications to iOS firmware components. According to the Lakr233/vphone-cli source code, the project performs kernel patching through Python utilities located in the scripts/patchers/ directory, leveraging specialized binary analysis libraries to handle ARM64 machine code and Apple's proprietary IMG4 container format.
Core Kernel Patching Libraries
Capstone Disassembler for ARM64 Analysis
The patching system uses Capstone to disassemble ARM64 binaries and locate stable anchors within the kernel. In scripts/patchers/cfw_asm.py, the tool initializes a Capstone instance with Cs(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN) to decode existing instructions and determine precise patch locations 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_asm.py#L44-L53】.
Keystone Assembler for Instruction Generation
After determining necessary modifications, Keystone assembles new ARM64 instructions into machine code. The same cfw_asm.py module creates a Keystone engine using Ks(KS_ARCH_ARM64, KS_MODE_LE) and exposes helper functions asm() and asm_at() for injecting replacement code 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_asm.py#L57-L69】.
pyimg4 for Container Manipulation
To handle iOS firmware packaging, pyimg4 reads and modifies IMG4 containers—the format enclosing kernelcache images. The module scripts/patchers/cfw_patch_post_restore_dt.py demonstrates this by parsing the kernel image, extracting the device tree (DT), modifying it, and rebuilding valid IMG4 structures after modification 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_patch_post_restore_dt.py#L50-L57】.
The Kernel Patching Workflow
The toolchain operates in three distinct phases to ensure reliable modifications:
-
Pattern Matching with Capstone: The disassembler examines kernel regions to find anchor instructions that mark patchable locations, providing the instruction-level view needed to locate targets.
-
Code Generation with Keystone: The assembler converts replacement instructions (such as
nopsleds or branch redirects) into correct ARM64 opcodes for injection. -
Container Rebuilding with pyimg4: The library extracts the Mach-O payload from the IMG4 wrapper, applies raw binary patches, and reconstitutes the container with proper cryptographic headers.
Key Source Files and Implementation Details
The patching infrastructure centers on scripts/patchers/cfw_asm.py, which provides unified assembly and disassembly primitives used throughout the system. Individual patch implementations like cfw_patch_hv_vmm_rootfs.py and cfw_patch_iomfb_swapend.py import these helpers to apply specific fixes using standard Python utilities such as struct, os, and shutil for binary data management.
For IMG4 operations, scripts/patchers/cfw_patch_post_restore_dt.py shows the complete workflow: opening the kernelcache via pyimg4.IMG4(data), extracting the IM4P payload, modifying the binary content, and reconstructing the container with pyimg4.IM4P(new_payload) 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_patch_post_restore_dt.py#L245-L283】.
Dependencies for these tools are specified in requirements.txt, which lists capstone, keystone-engine, and pyimg4 as essential components of the patching pipeline 【/cache/repos/github.com/Lakr233/vphone-cli/main/requirements.txt】.
Practical Code Examples
Disassembling kernel regions to inspect instructions before patching 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_asm.py#L84-L87】:
from scripts.patchers.cfw_asm import disasm_at
insns = disasm_at(kernel_bytes, file_offset, count=5)
for i in insns:
print(f"0x{i.address:x}: {i.mnemonic} {i.op_str}")
Assembling replacement instructions for injection 【/cache/repos/github.com/Lakr233/vphone-cli/main/scripts/patchers/cfw_asm.py#L71-L73】:
from scripts.patchers.cfw_asm import asm
# Generate NOP instruction bytes: b'\x1f\x20\x03\xd5'
patched = asm("nop")
Manipulating IMG4 containers to extract and modify kernel payloads:
import pyimg4
img4 = pyimg4.IMG4(data)
im4p = pyimg4.IM4P(data)
# Modify the kernel payload...
new_im4p = pyimg4.IM4P(new_payload)
new_img4 = pyimg4.IMG4(im4p=new_im4p, im4m=img4.im4m, im4r=img4.im4r)
Summary
- vphone-cli uses Capstone to disassemble ARM64 kernel code and locate precise patch points via pattern matching.
- Keystone assembles new machine instructions for injection into the binary, ensuring correct ARM64 encoding.
- pyimg4 handles the proprietary IMG4 container format, ensuring patched kernels remain valid for iOS installation.
- The
scripts/patchers/directory contains the core logic, withcfw_asm.pyproviding unified assembly/disassembly interfaces. - Standard Python utilities like
structandosmanage binary data and temporary file operations during the patching process.
Frequently Asked Questions
What architecture does vphone-cli target for kernel patching?
The tooling specifically targets ARM64 (AArch64), initializing both Capstone and Keystone with CS_ARCH_ARM64 and KS_ARCH_ARM64 constants along with little-endian mode flags. This matches the processor architecture of modern iOS devices that vphone-cli virtualizes.
Where are the kernel patching utilities located in the repository?
All patching tools reside in the scripts/patchers/ directory. The file cfw_asm.py contains the core assembly and disassembly helpers, while various cfw_patch_*.py modules (such as cfw_patch_post_restore_dt.py) implement specific kernel modifications using these primitives.
How does vphone-cli ensure patched kernels remain bootable?
By using pyimg4 to parse and reconstruct IMG4 containers, the tool preserves cryptographic headers and container structure. After modifying the Mach-O payload extracted from the IM4P object, it rebuilds the container with pyimg4.IM4P and reassembles the complete IMG4 image with original manifest (im4m) and restore parameters (im4r) intact.
Can these tools patch non-iOS ARM64 binaries?
While Capstone and Keystone work with any ARM64 binary for general disassembly and assembly, the pyimg4 integration is specific to Apple's IMG4 firmware format. For general ARM64 patching outside iOS, you could adapt the cfw_asm.py utilities, but the container handling would require replacement for other firmware packaging formats.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →