MCPcopy Index your code
hub / github.com/Impalabs/applevisor

github.com/Impalabs/applevisor @v1.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.0.0 ↗ · + Follow
202 symbols 305 edges 7 files 78 documented · 39%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

APPLEVISOR

Safe Rust bindings for the Apple Silicon Hypervisor.framework.

Table of contents

Getting Started

Starting a New Project

Create a Rust project and add Applevisor as a dependency in Cargo.toml. You can either pull it from crates.io ...

```toml,no_run

Check which version is the latest, this part of the README might not be updated

in future releases.

applevisor = "1.0"


... or directly from the [GitHub repository](https://github.com/impalabs/applevisor).

```toml,no_run
applevisor = { git="https://github.com/impalabs/applevisor", branch="master" }

MacOS Versions and Features

Since the Hypervisor.Framework is still evolving, depending on your macOS version (and those you want to support), some methods won't be available.

The following features can be used to determine the API available to your project:

  • macos-26-0: all methods available up to MacOS 26.0 (current default feature);
  • macos-15-2: all methods available up to MacOS 15.2;
  • macos-15-0: all methods available up to MacOS 15.0;
  • macos-13-0: all methods available up to MacOS 13.0;
  • macos-12-1: all methods available up to MacOS 12.1;

If you only want the base methods introduced before MacOS 12.1, you must disable default-features when declaring applevisor as a dependency:

```toml,no_run applevisor = {version = "x.x.x", default-features = false}


Refer to the [Hypervisor.Framework API](#hypervisorframework-api) section to get the list of available methods per macOS versions.

### Compilation Workflow

To be able to reach the Hypervisor Framework, a binary executable has to have been granted the [hypervisor entitlement](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_hypervisor). There are multiple entitlements you can add, which are documented by Apple, but the most important one is `com.apple.security.hypervisor`.

Create a file called `entitlements.txt` in the project's root directory and add the following:

```xml,no_run
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.hypervisor</key>
    <true/>
</dict>
</plist>

Build your project, and then sign the binary with your entitlements:

```console,no_run cargo build --release codesign --sign - --entitlements entitlements.xml --deep --force target/release/${PROJECT_NAME}


You can now run your program:

```console,no_run
target/release/${PROJECT_NAME}

Documentation

The documentation is available online at the following address: https://docs.rs/applevisor

Alternatively, you can generate the documentation using cargo:

```console,no_run cargo doc --open


## Example

The following example:

 * creates a virtual machine for the current process;
 * creates a virtual CPU;
 * enables the hypervisor's debug features to be able to use breakpoints later on;
 * creates a physical memory mapping of 0x1000 bytes and maps it at address 0x4000 with RWX
   permissions;
 * writes the instructions `mov x0, #0x42; brk #0;` at address 0x4000;
 * sets PC to 0x4000;
 * starts the vCPU and runs our program;
 * returns when it encounters the breakpoint.

```rust,no_run
use applevisor::prelude::*;

fn main() -> Result<()> {
    // Creates a new virtual machine. There can be one, and only one, per process. Operations
    // on the virtual machine remains possible as long as this object is valid.
    let vm = VirtualMachine::new()?;

    // Creates a new virtual CPU. This object abstracts operations that can be performed on
    // CPUs, such as starting and stopping them, changing their registers, etc.
    let vcpu = vm.vcpu_create()?;

    // Enables debug features for the hypervisor. This is optional, but it might be required
    // for certain features to work, such as breakpoints.
    vcpu.set_trap_debug_exceptions(true)?;
    vcpu.set_trap_debug_reg_accesses(true)?;

    // Creates a mapping object that represents a 0x1000-byte physical memory range.
    let mut mem = vm.memory_create(0x1000)?;

    // This mapping needs to be mapped to effectively allocate physical memory for the guest.
    // Here we map the region at address 0x4000 and set the permissions to Read-Write-Execute.
    mem.map(0x4000, MemPerms::RWX)?;
    // Writes a `mov x0, #0x42` instruction at address 0x4000.
    mem.write_u32(0x4000, 0xd2800840)?;
    // Writes a `brk #0` instruction at address 0x4004.
    mem.write_u32(0x4004, 0xd4200000)?;

    // Sets PC to 0x4000.
    vcpu.set_reg(Reg::PC, 0x4000)?;

    // Starts the Vcpu. It will execute our mov and breakpoint instructions before stopping.
    vcpu.run()?;

    // The *exit information* can be used to used to retrieve different pieces of
    // information about the CPU exit status (e.g. exception type, fault address, etc.).
    let exit_info = vcpu.get_exit_info();

    // If everything went as expected, the value in X0 is 0x42...
    assert_eq!(vcpu.get_reg(Reg::X0), Ok(0x42));
    // ... the vcpu has stopped because of an exception ...
    assert_eq!(exit_info.reason, ExitReason::EXCEPTION);
    // ... and the exception syndrome corresponds to a breakpoint exception (which would
    // have been a different value without the call to `set_trap_debug_exceptions()`).
    assert_eq!(exit_info.exception.syndrome >> 26, 0b111100);

    Ok(())
}

Tests and Coverage

Running the tests

To run tests using the Makefile provided with the project, you'll first need to install jq. You can do so using brew:

```console,no_run brew install jq


You can then run the tests with the provided `Makefile` using the following command:

```console,no_run
# To run all tests
make tests-all

# To run stable-only tests
make tests-stable-all

# To run nightly-only tests
make tests-nightly-all

Gather Coverage

To get the tests coverage, make sure LLVM is installed, and llvm-cov and llvm-profdata are in your PATH.

You can then get the coverage with the provided Makefile using the following command:

```console,no_run

Coverage for the latest macos version

make coverage-macos-26-0

Other targets are available in the Makefile to get the coverage for previous macos versions.

make coverage-macos-$(major)-$(minor) ```

Hypervisor.Framework API

Core symbols most depended-on inside this repo

Shape

Method 125
Function 40
Enum 22
Class 15

Languages

Rust100%

Modules by API surface

src/vcpu.rs63 symbols
src/vm.rs50 symbols
src/gic.rs33 symbols
src/memory.rs29 symbols
applevisor-sys/src/lib.rs22 symbols
src/error.rs4 symbols
src/lib.rs1 symbols

For agents

$ claude mcp add applevisor \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page