Table of contents
This library can be used to build Rust applications leveraging the Hypervisor framework on Apple Silicon. It was mainly built for Hyperpom, but it can serve more general purposes.
Getting Started
Self-Signed Binaries and Hypervisor Entitlement
To be able to reach the Hypervisor Framework, a binary executable has to have been granted the hypervisor entitlement.
Certificate Chain
To add this entitlement to your project, you'll first need a certificate chain to sign your binaries, which can be created by following the instructions below.
- Open the Keychain Access application.
- Go to Keychain Access > Certificate Assistant > Create a Certificate.
- Fill out the Name field, this value will be used later on to identify the certificate we want to sign with and will be referred to as
${CERT_NAME}. - Set Identity Type to
Self-Signed Root. - Set Certificate Type to
Code Signing. - Click on Create.
You can now sign binaries and add entitlements using the following command:
codesign --entitlements entitlements.xml -s ${CERT_NAME} /path/to/binary
Note: The entitlements.xml file is available at the root of the Applevisor repository.
Compilation Workflow
Create a Rust project and add Applevisor as a dependency in Cargo.toml. You can either pull it from crates.io ...
# Check which version is the latest, this part of the README might not be updated
# in future releases.
= "0.1.2"
... or directly from the GitHub repository.
= { ="https://github.com/impalabs/applevisor", ="master" }
Create a file called entitlements.txt in the project's root directory and add the following:
com.apple.security.hypervisor
Write code and then build the project.
cargo build --release
Sign the binary and grant the hypervisor entitlement.
codesign --entitlements entitlements.xml -s ${CERT_NAME} target/release/${PROJECT_NAME}
Run the binary.
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:
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 0x10000 with RWX permissions;
- writes the instructions
mov x0, #0x42; brk #0;at address 0x10000; - sets PC to 0x10000;
- starts the vCPU and runs our program;
- returns when it encounters the breakpoint.
use *;
Feel free to also have a look at the Hyperpom project's source code for a real-life example of how these bindings are used.
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:
brew install jq
You can then run the tests with the provided Makefile using the following command:
CERT_KEYCHAIN=${CERT_NAME} make tests