Skip to content

Commit 00d836b

Browse files
committed
first commit
0 parents  commit 00d836b

File tree

334 files changed

+17743
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

334 files changed

+17743
-0
lines changed

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
debug/
4+
target/
5+
6+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
8+
Cargo.lock
9+
10+
# These are backup files generated by rustfmt
11+
**/*.rs.bk
12+
13+
# MSVC Windows builds of rustc generate these, which store debugging information
14+
*.pdb
15+
16+
**/.DS_Store

Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "hyperpom"
3+
version = "0.1.0"
4+
authors = ["lyte <hyperpom@impalabs.fr>"]
5+
edition = "2021"
6+
description = "AArch64 fuzzing library based on the Apple Silicon hypervisor"
7+
documentation = "https://docs.rs/hyperpom"
8+
readme = "README.md"
9+
repository = "https://github.com/impalabs/hyperpom"
10+
license = "GPL-3.0-or-later"
11+
keywords = ["fuzzing", "hypervisor", "apple", "security", "aarch64"]
12+
categories = ["virtualization", "hardware-support", "testing"]
13+
14+
[dependencies]
15+
applevisor = "0.1.1"
16+
bitfield = "0.13.2"
17+
rhexdump="0.1.1"
18+
capstone = "0.11.0"
19+
regex = "1"
20+
time = { version = "0.3.9", features = ["local-offset", "formatting"] }
21+
22+
[dependencies.keystone-engine]
23+
git = "https://github.com/impalabs/keystone-bindings"
24+
branch = "master"
25+
version = "0.1.0"
26+
default-features = false
27+
features = ["build-from-src"]
28+
29+
[package.metadata.docs.rs]
30+
targets = ["x86_64-apple-darwin", "aarch64-apple-darwin"]

LICENSE.md

Lines changed: 675 additions & 0 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
CODESIGN := codesign
2+
CARGO := cargo +nightly
3+
4+
TARGET := hyperpom
5+
TARGET_DEBUG := target/debug/$(TARGET)
6+
TARGET_RELEASE := target/release/$(TARGET)
7+
8+
TMP_DIR := ./tmp
9+
CORPUS_DIR := "$(TMP_DIR)/corpus"
10+
WORK_DIR := "$(TMP_DIR)/work"
11+
12+
KEYCHAIN := $(CERT_KEYCHAIN)
13+
14+
build-debug:
15+
$(CARGO) fmt
16+
$(CARGO) build
17+
$(CODESIGN) --entitlements entitlements.xml -f -s "$(KEYCHAIN)" "$(TARGET_DEBUG)"
18+
19+
build-release:
20+
$(CARGO) fmt
21+
$(CARGO) build --release
22+
$(CODESIGN) --entitlements entitlements.xml -f -s "$(KEYCHAIN)" "$(TARGET_RELEASE)"
23+
24+
build-test:
25+
$(CARGO) test --no-run
26+
$(CODESIGN) --entitlements entitlements.xml -f -s "$(KEYCHAIN)" \
27+
$(shell $(CARGO) test --no-run --message-format=json | \
28+
jq -r "select(.profile.test == true) | .filenames[]")
29+
30+
build-test-release:
31+
$(CARGO) test --no-run --release
32+
$(CODESIGN) --entitlements entitlements.xml -f -s "$(KEYCHAIN)" \
33+
$(shell $(CARGO) test --no-run --release --message-format=json | \
34+
jq -r "select(.profile.test == true) | .filenames[]")
35+
36+
tmp-dirs:
37+
mkdir -p $(CORPUS_DIR)
38+
mkdir -p $(WORK_DIR)
39+
40+
test: clean-dirs tmp-dirs build-test
41+
$(CARGO) test $(filter-out $@,$(MAKECMDGOALS)) -- --nocapture --test-threads=1
42+
43+
tests: clean-dirs tmp-dirs build-test
44+
$(CARGO) test --tests -- --nocapture --test-threads=1
45+
46+
tests-release: build-test-release
47+
$(CARGO) test --release --tests -- --nocapture --test-threads=1
48+
49+
tests-threads: build-test
50+
$(CARGO) test --tests -- --nocapture
51+
52+
clean-dirs:
53+
rm -rf $(CORPUS_DIR)
54+
rm -rf $(WORK_DIR)
55+
56+
clean: clean-dirs clean-target
57+
$(CARGO) clean

README.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<p align="center">
2+
<img width="300" height="300" src="./hyperpom.svg" alt="hyperpom logo" />
3+
</p>
4+
<p align="center">
5+
<b style="font-size: 2em">HYPERPOM</b>
6+
<br/>
7+
<span style="font-size: 1.5em">AArch64 fuzzing library based on the Apple Silicon hypervisor</b>
8+
</p>
9+
10+
<hr/>
11+
12+
<p align="center">
13+
<img src="https://img.shields.io/github/license/impalabs/hyperpom?style=for-the-badge&color=ff9901" alt="shields.io license" />
14+
<img src="https://img.shields.io/github/v/release/impalabs/hyperpom?style=for-the-badge&color=f38702" alt="shields.io version" />
15+
<img src="https://img.shields.io/badge/platform-MacOS%20on%20Apple%20Silicon-e77600?style=for-the-badge" alt="shields.io platform" />
16+
<br/>
17+
<img src="https://img.shields.io/badge/rust-nightly-da6500?style=for-the-badge" alt="shields.io rust version" />
18+
<a href="https://crates.io/crates/hyperpom"><img src="https://img.shields.io/crates/v/hyperpom?color=cd5300&style=for-the-badge" alt="shields.io crates.io" /></a>
19+
<a href="https://docs.rs/hyperpom"><img src="https://img.shields.io/badge/docs.rs-rustdoc-bf4200?style=for-the-badge" alt="shields.io crates.io" /></a>
20+
</p>
21+
22+
<hr/>
23+
24+
## Table of contents
25+
26+
* [Disclaimer](#warning-disclaimer)
27+
* [Getting Started](#getting-started)
28+
* [Prerequisites](#prerequisites)
29+
* [Self-Signed Binaries and Hypervisor Entitlement](#self-signed-binaries-and-hypervisor-entitlement)
30+
* [Compilation Workflow](#compilation-workflow)
31+
* [Documentation](#documentation)
32+
* [Examples](#examples)
33+
* [Running the Tests](#running-the-tests)
34+
* [Authors](#authors)
35+
36+
37+
Hyperpom is a coverage-guided mutation-based fuzzing framework built on top of the [Apple Silicon Hypervisor](https://developer.apple.com/documentation/hypervisor/apple_silicon). It has been designed to easily instrument and fuzz AArch64 userland binaries.
38+
39+
## :warning: Disclaimer
40+
41+
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.
42+
43+
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.
44+
45+
## Getting Started
46+
47+
### Prerequisites
48+
49+
1. Install Rust and `rustup` using the [official guide](https://www.rust-lang.org/tools/install).
50+
2. Install the [nightly channel](https://rust-lang.github.io/rustup/concepts/channels.html).
51+
52+
```
53+
rustup toolchain install nightly
54+
```
55+
56+
3. To use this channel when compiling you can either:
57+
58+
- set it as default using `rustup default nightly`;
59+
- or add `+nightly` everytime you compile a binary with `cargo`.
60+
61+
4. Install Cmake, using `brew` for example:
62+
63+
```console
64+
brew install cmake
65+
```
66+
67+
### Self-Signed Binaries and Hypervisor Entitlement
68+
69+
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).
70+
71+
#### Certificate Chain
72+
73+
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.
74+
75+
- Open the *Keychain Access* application.
76+
- Go to **Keychain Access** > **Certificate Assistant** > **Create a Certificate**.
77+
- 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}`.
78+
- Set **Identity Type** to `Self-Signed Root`.
79+
- Set **Certificate Type** to `Code Signing`.
80+
- Click on **Create**.
81+
82+
You can now sign binaries and add entitlements using the following command:
83+
84+
```
85+
codesign --entitlements entitlements.xml -s ${CERT_NAME} /path/to/binary
86+
```
87+
88+
**Note:** The `entitlements.xml` file is available at the root of the Hyperpom repository.
89+
90+
### Compilation Workflow
91+
92+
93+
Create a Rust project and add Hyperpom as a dependency in `Cargo.toml`. You can either pull it from [crates.io](https://crates.io/crates/hyperpom) ...
94+
95+
```toml
96+
# Check which version is the latest, this part of the README might not be updated
97+
# in future releases.
98+
hyperpom = "0.1.0"
99+
```
100+
101+
... or directly from the [GitHub repository](https://github.com/impalabs/hyperpom).
102+
103+
```toml
104+
hyperpom = { git="https://github.com/impalabs/hyperpom", branch="master" }
105+
```
106+
107+
Create a file called `entitlements.txt` in the project's root directory and add the following:
108+
109+
```xml
110+
<?xml version="1.0" encoding="UTF-8"?>
111+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
112+
<plist version="1.0">
113+
<dict>
114+
<key>com.apple.security.hypervisor</key>
115+
<true/>
116+
</dict>
117+
</plist>
118+
```
119+
120+
Write code and then build the project.
121+
122+
```
123+
cargo build --release
124+
```
125+
126+
Sign the binary and grant the hypervisor entitlement.
127+
128+
```
129+
codesign --entitlements entitlements.xml -s ${CERT_NAME} target/release/${PROJECT_NAME}
130+
```
131+
132+
Run the binary.
133+
134+
```
135+
target/release/${PROJECT_NAME}
136+
```
137+
138+
## Documentation
139+
140+
The documentation is available online at the following address: [https://docs.rs/hyperpom](https://docs.rs/hyperpom)
141+
142+
Alternatively, you can generate it using `cargo`:
143+
144+
```
145+
cargo doc --open
146+
```
147+
148+
The documentation contains information on using the framework and its internals. For an in-depth guide, have a look at the `Loader` chapter, which provides examples on how to use the fuzzer and harness your targets.
149+
150+
## Examples
151+
152+
Four examples are provided to give you a better understanding of how the framework operates and get you started:
153+
154+
* [simple_executor](examples/simple_executor): showcases how to run arbitrary code in a VM using an `Executor`.
155+
* [simple_tracer](examples/simple_tracer): runs a program while tracing its instructions.
156+
* [simple_fuzzer](examples/simple_fuzzer): fuzzes a simple program.
157+
* [upng_fuzzer](examples/upng_fuzzer): fuzzer for the [uPNG](https://github.com/elanthis/upng/) library.
158+
159+
You can also have a look at the [tests](tests/tests.rs).
160+
161+
## Running the Tests
162+
163+
To run tests using the `Makefile` provided with the project, you'll first need to install [`jq`](https://stedolan.github.io/jq/download/). You can do so using `brew`:
164+
165+
```
166+
brew install jq
167+
```
168+
169+
You can then run the tests with the provided `Makefile` using the following command:
170+
171+
```
172+
CERT_KEYCHAIN=${CERT_NAME} make tests
173+
```
174+
175+
## Authors
176+
177+
* [**Maxime Peterlin**](https://twitter.com/lyte__) - hyperpom@impalabs.com

entitlements.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.hypervisor</key>
6+
<true/>
7+
</dict>
8+
</plist>

examples/simple_executor/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "simple_executor"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
hyperpom = { path = "../../" }

examples/simple_executor/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
CODESIGN := codesign
2+
CARGO := cargo
3+
4+
EXECUTOR := simple_executor
5+
EXECUTOR_RELEASE := target/release/$(EXECUTOR)
6+
KEYCHAIN := $(CERT_KEYCHAIN)
7+
8+
.DEFAULT_GOAL := run
9+
10+
build:
11+
$(CARGO) fmt
12+
$(CARGO) clippy
13+
$(CARGO) build --release
14+
$(CODESIGN) --entitlements entitlements.xml -f -s "$(KEYCHAIN)" "$(EXECUTOR_RELEASE)"
15+
16+
run: build
17+
$(EXECUTOR_RELEASE)
18+
19+
clean:
20+
$(CARGO) clean

examples/simple_executor/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Simple Executor
2+
3+
This example showcases how an `Executor` object can be used to execute arbitrary AArch64 instructions and then retrieve the CPU and memory states.
4+
5+
## Running the Program
6+
7+
To run the program you can use the `Makefile` provided and simply do:
8+
9+
```
10+
CERT_KEYCHAIN=${CERT_NAME} make run
11+
```
12+
13+
If everything went as expected you should see the following input.
14+
15+
```console
16+
$ target/release/hyperpom_example
17+
X0 = 0x42
18+
```
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.hypervisor</key>
6+
<true/>
7+
</dict>
8+
</plist>

0 commit comments

Comments
 (0)