How IDA Patch-Chain Reports Cross-Check Dynamic Patches in vphone-cli
IDA patch-chain reports cross-check dynamic patches by comparing static metadata (virtual addresses and method names) generated by IDA Pro against runtime verification logs captured during VM execution, ensuring every kernel patch is applied at the correct memory location.
The vphone-cli project employs a deterministic verification pipeline to validate jailbreak firmware patches. By integrating IDA Pro's static analysis with runtime dynamic patch verification, the toolchain confirms that patches applied during the build process actually manifest when the kernel boots in a virtual machine.
The Dual-Stage Patching Architecture
vphone-cli constructs its jailbreak firmware through a hybrid approach that patches the kernel both statically and at runtime. This methodology requires rigorous verification to prevent silent failures from upstream kernel changes.
The architecture separates concerns into two distinct phases:
- Static patch discovery – Patcher scripts in
scripts/patchers/(e.g.,scripts/patchers/cfw_patch_vm_map_protect.py) locate semantic anchors using string literals, local control-flow graph shapes, or unique instruction patterns. These scripts generate patch-point records containing the virtual address (VA), patch method identifier, and size. - Runtime verification – The
make jb_verify_runtimetarget executes the patched kernel on a VM, monitors every memory write operation, and producesruntime_verification_report.jsoncontaining the actual locations where patches were applied.
Generating Static Patch-Chain Reports
An IDA-MCP session analyzes the kernel image to produce comprehensive static maps of intended patch locations. This process generates two critical artifacts in research/kernel_patch_jb/runtime_verification/:
ida_patch_chain_report.md– A human-readable markdown file listing every function containing a patch point, the associated patch method name, the exact VA (e.g.,0xFFFFFE0007BD09A8), and the callers/callees relationships.ida_runtime_patch_points.json– A machine-readable JSON file containing structured patch-point metadata used for automated cross-checking.
The static report captures the ground truth of where patches should reside based on binary analysis before runtime execution.
Runtime Patch Capture and Verification
The runtime verification phase validates that the static expectations match actual kernel behavior. Executing make jb_verify_runtime with appropriate parameters boots the kernel in a controlled VM environment:
make jb_verify_runtime KERNEL_PATH=./vm/kernelcache.research.vphone600 WORKERS=8
During execution, the verifier records every location where the patcher actually wrote bytes. The output file runtime_verification_report.json contains entries with the patch method name, the actual VA, and a status field indicating "ok" or "miss".
Cross-Checking Logic: Ensuring Patch-Chain Integrity
The cross-checking mechanism performs a deterministic comparison between static IDA reports and runtime verification logs to establish patch-chain integrity.
Key Identifier Matching
Both reports use the patch method name (e.g., patch_vm_map_protect, patch_task_for_pid) as the primary key for correlation. This naming convention ensures that semantic patch identities persist across build and runtime environments.
Address Validation
The cross-checker compares the expected VA from ida_runtime_patch_points.json against the recorded VA in runtime_verification_report.json. A mismatch (e.g., 0xFFFFFE0007BD09A8 vs a different address) immediately flags potential drift from upstream kernel modifications.
Call-Graph Sanity Checks
IDA supplies the static call-graph context, identifying which functions call into the patched region. The runtime verifier confirms that these same callers successfully invoke the patched function after the VM boots, ensuring the patch resides within the expected execution path.
Status Flag Verification
Each runtime entry contains a "status" field. The cross-check script flags any entry marked "miss" or any IDA-generated entry lacking a corresponding runtime record, preventing incomplete patch applications from reaching production firmware.
Practical Implementation: Automating Verification
Developers automate the cross-checking process using a Python helper script that loads both JSON files and performs the correlation logic:
#!/usr/bin/env python3
# cross_check_patches.py – compare IDA static patches with runtime-verified patches
import json, sys, pathlib
def load_json(p): return json.load(open(p, "r"))
ida = load_json("research/kernel_patch_jb/runtime_verification/ida_runtime_patch_points.json")
runtime = load_json("research/kernel_patch_jb/runtime_verification/runtime_verification_report.json")
# Index by (method, va) for quick lookup
runtime_index = {(e["patch_method"], e["patch_va"]): e for e in runtime["patches"]}
errors = 0
for entry in ida["patches"]:
key = (entry["patch_method"], entry["patch_va"])
if key not in runtime_index:
print(f"❌ Missing runtime verification for {entry['patch_method']} @ {entry['patch_va']}")
errors += 1
else:
r = runtime_index[key]
if r["status"] != "ok":
print(f"⚠️ Runtime status not OK for {entry['patch_method']} @ {entry['patch_va']}: {r['status']}")
errors += 1
print(f"\nCross-check completed – {errors} issue(s) found.")
sys.exit(errors)
Running the verification workflow requires executing the make target followed by the cross-check script:
python3 cross_check_patches.py
Creating New Static Patches
When developing new patches, scripts like scripts/patchers/cfw_patch_vm_map_protect.py follow a standardized pattern to ensure compatibility with the verification system:
def patch_vm_map_protect(chunks_dir, *, dry_run=False):
"""
Locate the `vm_map_protect` gate that clears VM_PROT_WRITE.
Uses the string "VM_PROT_WRITE" + a local CBZ pattern as the anchor.
"""
# 1️⃣ Resolve the function VMA via the recovered symbol table
vm_map_protect_vma = _resolve_local_symbol(chunks_dir, "__ZL13vm_map_protect")
# 2️⃣ Scan for the unique pattern
patch_va = find_pattern(vm_map_protect_vma, b"\xD2\x1F\x00\x00\x71\x44\x00\x00") # and w20, #0xfffffffb
# 3️⃣ Record the patch point for both IDA and runtime reports
_record_patch("patch_vm_map_protect", patch_va, dry_run=dry_run)
This pattern ensures that new patches automatically integrate into both the static IDA reports and the runtime verification pipeline.
Summary
- Static analysis via IDA Pro produces
ida_runtime_patch_points.json, mapping expected patch locations by VA and method name. - Runtime verification via
make jb_verify_runtimegeneratesruntime_verification_report.json, confirming where patches were actually applied during VM execution. - Cross-checking logic uses the patch method name as a primary key to correlate static expectations with runtime results, validating address accuracy and execution path integrity.
- Status flags (
"ok"vs"miss") immediately highlight discrepancies caused by upstream kernel changes or patch application failures. - The system ensures patch-chain integrity, allowing developers to catch address drift and execution mismatches before bundling kernels into final CFW images.
Frequently Asked Questions
What triggers a patch-chain mismatch report?
A mismatch occurs when the virtual address (VA) recorded in ida_runtime_patch_points.json differs from the VA captured in runtime_verification_report.json for the same patch method name, or when a patch reports a "miss" status during runtime verification. This typically indicates upstream kernel changes have shifted code locations, requiring anchor adjustments in the patcher scripts.
How does the runtime verifier capture dynamic patch locations?
The runtime verifier executes the kernel in a virtual machine environment created by the jb_verify_runtime make target. It monitors memory write operations during the boot sequence, recording every byte modification along with its exact VA. These captures are serialized into runtime_verification_report.json for later comparison against static IDA analysis.
Can I run the cross-check without IDA Pro?
No, the ida_patch_chain_report.md and ida_runtime_patch_points.json files require IDA Pro analysis to generate the static ground truth of expected patch locations. However, once generated, these files can be distributed to team members who only need to run the runtime verification and cross-check script without requiring IDA licenses.
What does the "miss" status indicate in runtime reports?
The "miss" status in runtime_verification_report.json indicates that the patcher attempted to apply a patch at a specific location but failed to write the expected bytes, or that the target memory region was never accessed during VM execution. This flags potential issues with patch anchors, kernel memory protection, or incompatible upstream kernel revisions that prevent the patch from landing correctly.
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 →