# What Are the EXP-Only Research Patches Applied by KernelEXPPatcher?

> Discover how KernelEXPPatcher uses EXP-only research patches to rename the hv_vmm_present sysctl OID, effectively masking virtualization for vPhone-CLI and enabling bare-metal presentation with VM acceleration.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: deep-dive
- Published: 2026-08-31

---

**The KernelEXPPatcher applies a single, specialized kernel modification—renaming the `hv_vmm_present` sysctl OID—that masks virtualization detection in the EXP (Experimental) variant of vPhone-CLI, allowing the system to present as bare-metal hardware while retaining VM acceleration capabilities.**

The **EXP-only research patches** are exclusively documented in the [`research/0_binary_patch_comparison.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/0_binary_patch_comparison.md) file within the Lakr233/vphone-cli repository. These modifications are orchestrated by `KernelEXPPatcher`, a Swift-based firmware patcher that executes after the generic `KernelPatcher` and before jailbreak-specific patches during the firmware installation pipeline.

## Understanding the Experimental (EXP) Variant

The **Experimental (EXP)** build of vPhone-CLI introduces kernel-level modifications that are **not applied** when building the regular or standard jailbreak (JB) variants. According to the research documentation, `KernelEXPPatcher` inherits from `KernelJBPatcherBase` and activates only when the EXP flag is enabled during the build process. This isolation ensures that virtualization-masking behaviors do not interfere with standard jailbreak operations or stock firmware restoration.

## The Core EXP-Only Kernel Patch: `hv_vmm_present` Rename

The only kernel-level method introduced by `KernelEXPPatcher` is the **`patch_hv_vmm_rename`** operation (designated as **EXP-01, Group B**). This patch consists of two complementary stages that modify the string `"kern.hv_vmm_present"` throughout the kernel and user-space boundaries.

### Part A – Sysctl OID String Modification

`KernelEXPPatcher` locates the sysctl registration table within the kernel binary and modifies the OID string in-place. The patch overwrites the sixth character (byte 5) of the C-string, changing `'h'` to `'X'`, transforming `"kern.hv_vmm_present"` into `"kern.Xv_vmm_present"`.

```swift
// Conceptual implementation from KernelEXPPatchHvVmmRename.swift
func patchSysctlTable(in kernelData: inout Data) {
    let targetString = "kern.hv_vmm_present"
    let replacementIndex = 5 // Position of 'h'
    
    if let range = kernelData.range(of: targetString.data(using: .utf8)!) {
        kernelData[range.lowerBound + replacementIndex] = UInt8(ascii: "X")
    }
}

```

After this modification, direct calls to `sysctlbyname("kern.hv_vmm_present")` return `ENOENT` (not found), while queries to `"kern.Xv_vmm_present"` return the actual virtualization state (typically `1`).

### Part B – In-Kernel Reference Mangling

To maintain internal consistency, `KernelEXPPatcher` applies the same byte-level transformation to every in-kernel occurrence of the original string literal. This ensures that internal components—**AMFI**, **IO Crypto**, **Sandbox profile tokens**, and **APFS**—continue to reference the renamed OID correctly without crashing.

```swift
// Kernel-level string literal patching
func mangleKernelStrings(in kernelData: inout Data) {
    let original = "kern.hv_vmm_present".data(using: .utf8)!
    var searchStart = kernelData.startIndex
    
    while let range = kernelData[searchStart...].range(of: original) {
        let absolutePos = range.lowerBound
        kernelData[absolutePos + 5] = UInt8(ascii: "X")
        searchStart = range.upperBound
    }
}

```

### DSC-Level Consistency

During post-restore firmware patching, the companion script [`cfw_patch_hv_vmm_dsc.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_hv_vmm_dsc.py) applies an equivalent mangling to every dylib within the **dyld shared cache (DSC)**. This ensures that user-space daemons querying the sysctl see the same renamed OID.

```python

# From scripts/patchers/cfw_patch_hv_vmm_dsc.py

def patch_dsc_sysctl(dsc_path, whitelist=None):
    with open(dsc_path, 'r+b') as f:
        content = bytearray(f.read())
        original = b"kern.hv_vmm_present"
        renamed = b"kern.Xv_vmm_present"
        
        # Replace all occurrences except whitelisted binaries

        content = content.replace(original, renamed)
        f.seek(0)
        f.write(content)

```

## EXP-Only Firmware Modifications Dependent on the Kernel Patch

Several additional EXP-only modifications rely on the `hv_vmm_present` rename having been established by `KernelEXPPatcher`:

- **watchdogd surgical patch (EXP-JB-3.5)** – Re-attests the renamed OID through a two-instruction cache-slot rewrite
- **DeviceTree post-restore identity rewrite (EXP-JB-6)** – Adds new `/product/camera` nodes and eight additional identity properties that reference the masked virtualization state
- **SystemVersion.plist ProductBuildVersion rewrite (EXP-JB-7)** – Optionally changes the build identifier when `SPOOF_BUILD` is set, contingent on the kernel's masked VM state

These modifications are coordinated by [`scripts/cfw_install_exp.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install_exp.sh), which invokes `KernelEXPPatcher` at the `[EXP-JB-3.5]` stage of the firmware installation pipeline.

```bash

# From scripts/cfw_install_exp.sh

# [EXP-JB-3.5] Apply kernel EXP patches

echo "[*] Applying KernelEXPPatcher..."
KernelEXPPatcher "${EXP_KERNEL_CACHE}" "${Patched_KERNEL}"

```

## Source Code Structure and Implementation

The EXP-only patches are implemented across three critical files in the vPhone-CLI source tree:

- [`sources/FirmwarePatcher/Kernel/KernelEXPPatcher.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/Kernel/KernelEXPPatcher.swift) – Orchestrates the patch sequence and inherits from `KernelJBPatcherBase`
- [`sources/FirmwarePatcher/Kernel/EXPPatches/KernelEXPPatchHvVmmRename.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/Kernel/EXPPatches/KernelEXPPatchHvVmmRename.swift) – Contains the `patch_hv_vmm_rename` method implementing Parts A and B
- [`research/0_binary_patch_comparison.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/0_binary_patch_comparison.md) – Documents the complete EXP-01 patch specification and binary diff analysis

## Summary

- **KernelEXPPatcher** applies exactly one kernel-level EXP-only patch: the `hv_vmm_present` sysctl OID rename.
- The patch modifies byte 5 of the target string in both the sysctl table and all in-kernel references, changing `"kern.hv_vmm_present"` to `"kern.Xv_vmm_present"`.
- User-space consistency is maintained by [`cfw_patch_hv_vmm_dsc.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_hv_vmm_dsc.py), which patches the dyld shared cache equivalently.
- Additional EXP modifications (watchdogd, DeviceTree, SystemVersion) depend on this kernel patch but are applied separately during the `[EXP-JB-3.5]` through `[EXP-JB-7]` stages.
- These patches are exclusive to the Experimental variant and are not present in standard or JB builds.

## Frequently Asked Questions

### What is the difference between KernelEXPPatcher and the standard KernelPatcher?

**KernelEXPPatcher** runs exclusively during Experimental (EXP) builds and inherits from `KernelJBPatcherBase`, whereas the standard **KernelPatcher** handles generic kernel modifications for all variants. According to the source in [`sources/FirmwarePatcher/Kernel/KernelEXPPatcher.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/Kernel/KernelEXPPatcher.swift), the EXP patcher executes after the generic patcher and specializes in virtualization-masking behaviors that are too aggressive for standard jailbreak operations.

### Why does the EXP variant rename `hv_vmm_present` instead of simply returning 0?

Renaming the OID entirely (from `"kern.hv_vmm_present"` to `"kern.Xv_vmm_present"`) causes queries for the original name to return `ENOENT`, effectively hiding the VM's existence from detection tools. Simply returning `0` would still expose the sysctl's presence to sophisticated checks. This **string-level rename** ensures that legacy code paths expecting the non-existent OID behave as if running on bare-metal hardware, while the hypervisor can still query the renamed OID to confirm acceleration capabilities are active.

### Which system components are affected by the in-kernel string mangling?

The **Part B** mangling affects every kernel extension and subsystem that hardcodes the `"kern.hv_vmm_present"` string literal. The research documentation identifies **AMFI (Apple Mobile File Integrity)**, **IO Crypto**, **Sandbox profile token validation**, and **APFS** as critical components that continue functioning because their internal references are updated to point to `"kern.Xv_vmm_present"` instead of querying a non-existent sysctl.

### Are the EXP-only patches included in the regular jailbreak build?

No. The EXP-only research patches are **conditionally compiled** and executed only when building the Experimental variant. The [`scripts/cfw_install_exp.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install_exp.sh) script explicitly calls `KernelEXPPatcher` during the `[EXP-JB-3.5]` stage, while the standard jailbreak installation script ([`cfw_install_jb.sh`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_install_jb.sh)) omits this call entirely, preserving the stock `hv_vmm_present` behavior for compatibility with standard iOS security policies.