# How KernelEXPPatchHvVmmRename Evades VM-Detection Services in vPhone-CLI

> Discover how KernelEXPPatchHvVmmRename bypasses VM detection. Learn the specific sysctl OID edits that trick trusted services and blacklist callers in vPhone-CLI.

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

---

**KernelEXPPatchHvVmmRename evades VM-detection by performing single-byte surgical edits that rename the `hv_vmm_present` sysctl OID from `hv_vmm_present` to `Xv_vmm_present`, causing trusted kernel services to read the valid VM value (1) while blacklisted callers receive `ENOENT` and conclude they are not in a virtual machine.**

The EXP variant of vPhone-CLI ships with a sophisticated kernel-level countermeasure designed to bypass virtualization detection in iOS kernels. According to the `Lakr233/vphone-cli` source code, the `KernelEXPPatchHvVmmRename` patch manipulates the `kern.hv_vmm_present` sysctl at the binary level to create a split-view reality: critical system components like AMFI and the sandbox see a valid VM presence, while targeted detection services believe they are running on bare metal.

## The Two-Part Byte-Level Patching Strategy

The patch works through two coordinated single-byte modifications inside the kernelcache binary. Both changes flip the character `h` (hex `0x68`) to `X` (hex `0x58`) at specific offsets, creating a renamed sysctl OID that remains internally accessible but externally invisible.

### Part A: OID Rename (The String Mutation)

The first modification targets the NUL-delimited C-string that defines the sysctl's OID name. The patch locates the sequence `\0hv_vmm_present\0` and changes the `h` to `X`, resulting in `\0Xv_vmm_present\0`.

This rename has a critical effect: after the patch, direct lookups for `"kern.hv_vmm_present"` return `ENOENT` (No such file or directory), while lookups for `"kern.Xv_vmm_present"` resolve to the real OID with an integer value of `1`. As implemented in [`KernelEXPPatchHvVmmRename.swift`](https://github.com/Lakr233/vphone-cli/blob/main/KernelEXPPatchHvVmmRename.swift), this is the foundation of the evasion technique.

### Part B: Internal Caller Mangling (Synchronizing Trusted Components)

The second modification updates every internal kernel reference to ensure legitimate services remain synchronized with the renamed OID. The patch scans for two specific patterns:

- The full C-string `\0kern.hv_vmm_present\0`
- The sandbox token `kern.hv_vmm_present\x0f`

For each occurrence, the patch flips the fifth byte (`h` → `X`), transforming the strings to `kern.Xv_vmm_present`. This ensures that kernel code, AMFI, and the sandbox profile verifier query the renamed OID and receive the truthful value `1`, preventing VM detection panics. Blacklisted userland callers that use the original name receive `ENOENT`, triggering their "not-in-VM" defensive logic.

## Implementation Details in KernelEXPPatchHvVmmRename.swift

The core algorithm lives in [`sources/FirmwarePatcher/Kernel/EXPPatches/KernelEXPPatchHvVmmRename.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/Kernel/EXPPatches/KernelEXPPatchHvVmmRename.swift). The implementation is idempotent—re-running the patch detects already-patched bytes and skips them.

The Swift code performs byte-level searches using `Data` buffers:

```swift
// Part A: Rename the OID name itself
let needle = Data([0x00, 0x68, 0x76, 0x5f, 0x76, 0x6d, 0x6d, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x00])
if let offset = buffer.findAll(needle).first {
    emit(offset + 1, Data([0x58]), comment: "OID: h -> X")
}

// Part B: Mangle internal callers
let sites = [
    (needle: "\0kern.hv_vmm_present\0".data(using: .utf8)!, delta: 6, label: "cstr"),
    (needle: "kern.hv_vmm_present\x0f".data(using: .utf8)!, delta: 5, label: "tlv")
]

for (needle, delta, label) in sites {
    for offset in buffer.findAll(needle) {
        let mangle = offset + delta
        guard buffer.data[mangle] == 0x68 else { continue }
        emit(mangle, Data([0x58]), comment: "\(label): h -> X")
    }
}

```

The [`hv_vmm_present_xref.json`](https://github.com/Lakr233/vphone-cli/blob/main/hv_vmm_present_xref.json) file in the repository's research directory provides the offset maps for each kernel binary, ensuring the patch locates all occurrences without false positives.

## Practical Code Examples

### Applying the Patch

Invoke the patch through the `KernelEXPPatcher` coordinator class:

```swift
let expPatcher = KernelEXPPatcher(kernelcache: kernelBuffer)
if expPatcher.patchHvVmmRename() {
    print("[EXP] hv_vmm_present patch applied")
} else {
    print("[EXP] Patch already present or buffer not found")
}

```

### Querying the Sysctl Before Patching

On an unpatched virtual machine, querying the original name fails:

```swift
var value: Int32 = 0
var size = MemoryLayout.size(ofValue: value)
let rc = sysctlbyname("kern.hv_vmm_present", &value, &size, nil, 0)
// rc == ENOENT (2) - AMFI interprets this as "not a VM" and may panic

```

### Querying the Sysctl After Patching

After applying `KernelEXPPatchHvVmmRename`, trusted components query the renamed OID:

```swift
var value: Int32 = 0
var size = MemoryLayout.size(ofValue: value)
let rc = sysctlbyname("kern.Xv_vmm_present", &value, &size, nil, 0)
// rc == 0, value == 1 - AMFI sees VM presence as valid and continues safely

```

## Summary

- **KernelEXPPatchHvVmmRename** performs single-byte surgical edits (`0x68` → `0x58`) to rename the `hv_vmm_present` sysctl OID to `Xv_vmm_present`.
- The patch creates a split-view environment where `ENOENT` is returned to blacklisted callers while trusted kernel services receive the valid VM value `1`.
- Implementation spans [`KernelEXPPatchHvVmmRename.swift`](https://github.com/Lakr233/vphone-cli/blob/main/KernelEXPPatchHvVmmRename.swift) for the kernelcache and [`cfw_patch_hv_vmm_dsc.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_hv_vmm_dsc.py) for userland DSC dylibs.
- The technique is idempotent and relies on the [`hv_vmm_present_xref.json`](https://github.com/Lakr233/vphone-cli/blob/main/hv_vmm_present_xref.json) research data to locate all string occurrences.
- This evasion prevents AMFI and sandbox panics while allowing VM-detection services to conclude they are running on physical hardware.

## Frequently Asked Questions

### How does flipping a single byte from 'h' to 'X' evade detection?

The byte flip changes the sysctl's registered name from `hv_vmm_present` to `Xv_vmm_present` without altering its data structure. When blacklisted services query the original name `"kern.hv_vmm_present"`, the kernel returns `ENOENT` because that OID no longer exists. Meanwhile, internal kernel components query `"kern.Xv_vmm_present"` and receive value `1`, confirming the VM is present. This architectural split allows the system to lie to specific callers while maintaining internal consistency.

### Is KernelEXPPatchHvVmmRename safe to run multiple times?

Yes. According to the source code in [`KernelEXPPatchHvVmmRename.swift`](https://github.com/Lakr233/vphone-cli/blob/main/KernelEXPPatchHvVmmRename.swift), the patch is idempotent. During each run, the algorithm checks that the target byte equals `0x68` (the original 'h') before writing `0x58` ('X'). If the byte is already `0x58`, the patch skips that location, preventing double-patching or corruption of the kernelcache binary.

### Does this patch affect userland applications or only the kernel?

The patch primarily targets the kernelcache, but the evasion strategy extends to userland through [`scripts/patchers/cfw_patch_hv_vmm_dsc.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_hv_vmm_dsc.py). This companion script performs identical byte flips in the Dynamic Shared Cache (DSC) dylibs, ensuring that system libraries in user space maintain the same split-view behavior as the kernel. Without this coordination, userland detection services could still identify the VM environment.

### Which specific services are blacklisted versus whitelisted by this technique?

The whitelist includes critical system components that require VM awareness to function correctly: **AMFI** (Apple Mobile File Integrity) for its "No PMGR?" checks, the **sandbox** profile verifier, and graphics acceleration kexts. Blacklisted callers typically include sign-in libraries, DRM verification tools, and jailbreak detection frameworks that query `kern.hv_vmm_present` to trigger defensive logic when a VM is detected.