Expand description
Apple Silicon hypervisor-based fuzzer for ARM64 binaries.
Disclaimer
The idea behind this project was to create an efficient and fast fuzzer that would leverage Apple Silicon’s features. However, at this stage, while the fuzzer works, it is still mostly a proof of concept and requires tons of enhancement to provide better features, usability and performances.
It might be enough for your use cases, but keep in mind that you might encounter limitations that weren’t factored in while designing the project. In any case, feel free to open an issue and we’ll try to address your problem.
Hyperpom Internals & Usage
If you want an in-depth guide on how to use this fuzzer, you can directly jump to the
chapter about the Loader
, which provides different examples.
Otherwise, if you want a better understanding of the fuzzer’s implementation and the interactions between its components, it is recommended to read the documentation in the following order.
- Memory Management
- Exception Handling
- Cache Maintenance
- Hooks
- Coverage
- Tracing
- Corpus
- Mutator
- Fuzzer’s Core
- Config
- Loader
Getting Started
Prerequisites
- Install Rust and
rustup
using the official guide. - Install the nightly channel.
rustup toolchain install nightly
-
To use this channel when compiling you can either:
- set it as default using
rustup default nightly
; - or add
+nightly
everytime you compile a binary withcargo
.
- set it as default using
-
Install Cmake, using
brew
for example:
brew install cmake
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
Hyperpom repository.
Compilation Workflow
Create a Rust project and add Hyperpom as a dependency in Cargo.toml
. You can either pull it
from crates.io …
hyperpom = "0.1.0"
… or directly from the GitHub repository.
hyperpom = { git="https://github.com/impalabs/hyperpom", branch="master" }
Create a file called entitlements.txt
in the project’s root directory and add the following:
<?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>
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}
Examples
Four examples are provided to give you a better understanding of how the framework operates and get you started:
- simple_executor:
showcases how to run arbitrary code in a VM using an
Executor
. - simple_tracer: runs a program while tracing its instructions.
- simple_fuzzer: fuzzes a simple program.
- upng_fuzzer: fuzzer for the uPNG library.
You can also have a look at the tests.
Re-exports
pub extern crate applevisor;
Modules
Macros
applevisor::PAGE_SIZE
.VIRT_PAGE_SIZE
.applevisor::PAGE_SIZE
.VIRT_PAGE_SIZE
.