Refactoring of qemu_systemmode fuzzers (#1980)
* Added backdoors to portable header file. * fix arm macros. * copy `libafl_qemu.h` in target directory. * Merged all qemu_systemmode examples into one, settable with features. Automatic building using `Makefile.toml` * fix typo. * added test of QEMU systemmode fuzzers. * replace test by build for now.
This commit is contained in:
parent
0cafa5c72d
commit
50e0f80d1e
2
.github/workflows/build_and_test.yml
vendored
2
.github/workflows/build_and_test.yml
vendored
@ -373,7 +373,7 @@ jobs:
|
|||||||
directory: ${{ runner.temp }}/llvm
|
directory: ${{ runner.temp }}/llvm
|
||||||
version: 17
|
version: 17
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt update && sudo apt install nasm ninja-build gcc-arm-linux-gnueabi g++-arm-linux-gnueabi gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils libz3-dev
|
run: sudo apt update && sudo apt install nasm ninja-build gcc-arm-linux-gnueabi g++-arm-linux-gnueabi gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils libz3-dev qemu-utils
|
||||||
- name: pip install
|
- name: pip install
|
||||||
run: python3 -m pip install msgpack jinja2 find_libpython
|
run: python3 -m pip install msgpack jinja2 find_libpython
|
||||||
# Note that nproc needs to have coreutils installed on macOS, so the order of CI commands matters.
|
# Note that nproc needs to have coreutils installed on macOS, so the order of CI commands matters.
|
||||||
|
@ -5,9 +5,13 @@ authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenuk
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std", "classic"]
|
||||||
std = []
|
std = []
|
||||||
|
|
||||||
|
classic = [] # The classic way to interact with LibAFL QEMU, with direct calls to QEMU's functions
|
||||||
|
breakpoint = [] # Uses the command system, with breakpoints
|
||||||
|
sync_exit = [] # Uses the command system, with sync exit.
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
incremental = true
|
incremental = true
|
||||||
debug = true
|
debug = true
|
||||||
|
181
fuzzers/qemu_systemmode/Makefile.toml
Normal file
181
fuzzers/qemu_systemmode/Makefile.toml
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
[env]
|
||||||
|
PROFILE = { value = "release", condition = {env_not_set = ["PROFILE"]} }
|
||||||
|
TARGET_DIR = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/${FEATURE}"
|
||||||
|
|
||||||
|
[tasks.target_dir]
|
||||||
|
condition = { files_not_exist = [ "${TARGET_DIR}" ] }
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
mkdir -p ${TARGET_DIR}
|
||||||
|
'''
|
||||||
|
|
||||||
|
[tasks.image]
|
||||||
|
dependencies = ["target_dir"]
|
||||||
|
condition = { files_not_exist = [ "${TARGET_DIR}/dummy.qcow2" ] }
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
qemu-img create -f qcow2 ${TARGET_DIR}/dummy.qcow2 32M
|
||||||
|
'''
|
||||||
|
|
||||||
|
[tasks.target]
|
||||||
|
dependencies = ["target_dir", "build_fuzzer"]
|
||||||
|
condition = { env_set = [ "TARGET_DEFINE" ] }
|
||||||
|
command = "arm-none-eabi-gcc"
|
||||||
|
args = [
|
||||||
|
"-ggdb",
|
||||||
|
"-ffreestanding",
|
||||||
|
"-nostartfiles",
|
||||||
|
"-lgcc",
|
||||||
|
"-T", "${CARGO_MAKE_WORKING_DIRECTORY}/example/mps2_m3.ld",
|
||||||
|
"-mcpu=cortex-m3",
|
||||||
|
"${CARGO_MAKE_WORKING_DIRECTORY}/example/main.c",
|
||||||
|
"${CARGO_MAKE_WORKING_DIRECTORY}/example/startup.c",
|
||||||
|
"-D", "${TARGET_DEFINE}",
|
||||||
|
"-I", "${TARGET_DIR}/${PROFILE}/include",
|
||||||
|
"-o", "${TARGET_DIR}/example.elf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.build_fuzzer]
|
||||||
|
condition = { env_set = [ "FEATURE" ] }
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"build",
|
||||||
|
"--profile",
|
||||||
|
"${PROFILE}",
|
||||||
|
"--no-default-features",
|
||||||
|
"--features", "std,${FEATURE}",
|
||||||
|
"--target-dir", "${TARGET_DIR}",
|
||||||
|
"-vv",
|
||||||
|
]
|
||||||
|
dependencies = ["image"]
|
||||||
|
|
||||||
|
[tasks.run_fuzzer]
|
||||||
|
env = { "KERNEL" = "${TARGET_DIR}/example.elf" }
|
||||||
|
command = "${TARGET_DIR}/${PROFILE}/qemu_systemmode"
|
||||||
|
args = [
|
||||||
|
"-icount", "shift=auto,align=off,sleep=off",
|
||||||
|
"-machine", "mps2-an385",
|
||||||
|
"-monitor", "null",
|
||||||
|
"-kernel", "${TARGET_DIR}/example.elf",
|
||||||
|
"-serial", "null",
|
||||||
|
"-nographic",
|
||||||
|
"-snapshot",
|
||||||
|
"-drive", "if=none,format=qcow2,file=${TARGET_DIR}/dummy.qcow2",
|
||||||
|
"-S",
|
||||||
|
]
|
||||||
|
dependencies = ["build_fuzzer", "target"]
|
||||||
|
|
||||||
|
[tasks.test_fuzzer]
|
||||||
|
condition = { env_set = [ "FEATURE" ] }
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
TMP_DIR=$(mktemp -d)
|
||||||
|
|
||||||
|
cargo make build_$FEATURE
|
||||||
|
timeout 15s cargo make ${FEATURE} | tee $TMP_DIR/fuzz.log 2>&1 || true
|
||||||
|
|
||||||
|
if [ -z "$(grep 'Objective' $TMP_DIR/fuzz.log)" ]; then
|
||||||
|
echo "Fuzzer did not find the objective in $TMP_DIR/fuzz.log"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Objective found."
|
||||||
|
fi
|
||||||
|
'''
|
||||||
|
|
||||||
|
[tasks.build_classic]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=classic",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_CLASSIC",
|
||||||
|
"build_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.test_classic]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=classic",
|
||||||
|
"test_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.build_breakpoint]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=breakpoint",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_BREAKPOINT",
|
||||||
|
"build_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.test_breakpoint]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=breakpoint",
|
||||||
|
"test_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.build_sync_exit]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=sync_exit",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_SYNC_EXIT",
|
||||||
|
"build_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.test_sync_exit]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=sync_exit",
|
||||||
|
"test_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.classic]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=classic",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_CLASSIC",
|
||||||
|
"run_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.breakpoint]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=breakpoint",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_BREAKPOINT",
|
||||||
|
"run_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.sync_exit]
|
||||||
|
command = "cargo"
|
||||||
|
args = [
|
||||||
|
"make",
|
||||||
|
"-e", "FEATURE=sync_exit",
|
||||||
|
"-e", "TARGET_DEFINE=TARGET_SYNC_EXIT",
|
||||||
|
"run_fuzzer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tasks.test]
|
||||||
|
clear = true
|
||||||
|
run_task = { name = ["build"] }
|
||||||
|
# run_task = { name = ["test_classic", "test_breakpoint", "test_sync_exit"] }
|
||||||
|
|
||||||
|
[tasks.build]
|
||||||
|
clear = true
|
||||||
|
run_task = { name = ["build_classic", "build_breakpoint", "build_sync_exit"] }
|
||||||
|
|
||||||
|
[tasks.run]
|
||||||
|
alias="classic"
|
||||||
|
|
||||||
|
[tasks.clean]
|
||||||
|
clear = true
|
||||||
|
script_runner="@shell"
|
||||||
|
script='''
|
||||||
|
rm -rf ${CARGO_MAKE_CRATE_TARGET_DIRECTORY}
|
||||||
|
cargo clean
|
||||||
|
'''
|
@ -2,25 +2,28 @@
|
|||||||
|
|
||||||
This folder contains an example fuzzer for the qemu systemmode, using LLMP for fast multi-process fuzzing and crash detection.
|
This folder contains an example fuzzer for the qemu systemmode, using LLMP for fast multi-process fuzzing and crash detection.
|
||||||
|
|
||||||
## Build
|
It comes in three flavours (can be set through features):
|
||||||
|
|
||||||
To build this example, run
|
-`classic`: The low-level way to interact with QEMU.
|
||||||
|
-`breakpoint`: Interaction with QEMU using the command system, leveraging breakpoints.
|
||||||
```bash
|
-`sync_exit`: Interaction with QEMU using the command system, leveraging sync exits.
|
||||||
cargo build --release
|
|
||||||
cd example; sh build.sh; cd ..
|
|
||||||
```
|
|
||||||
|
|
||||||
This will build the the fuzzer (src/fuzzer.rs) and a small example binary based on FreeRTOS, which can run under a qemu emulation target.
|
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
Since the instrumentation is based on snapshtos QEMU needs a virtual drive (even if it is unused...).
|
|
||||||
Create on and then run the fuzzer:
|
|
||||||
```bash
|
```bash
|
||||||
# create an image
|
cargo make run
|
||||||
qemu-img create -f qcow2 dummy.qcow2 32M
|
|
||||||
# run the fuzzer
|
|
||||||
KERNEL=./example/example.elf target/release/qemu_systemmode -icount shift=auto,align=off,sleep=off -machine mps2-an385 -monitor null -kernel ./example/example.elf -serial null -nographic -snapshot -drive if=none,format=qcow2,file=dummy.qcow2 -S
|
|
||||||
```
|
```
|
||||||
Currently the ``KERNEL`` variable is needed because the fuzzer does not parse QEMUs arguments to find the binary.
|
|
||||||
|
It is also possible to run the fuzzer with the other features:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo make <feature>
|
||||||
|
```
|
||||||
|
|
||||||
|
With feature being `classic`, `breakpoint` or `sync_exit`.
|
||||||
|
|
||||||
|
This will build the desired fuzzer (src/fuzzer_<feature>.rs) and a small example binary based on FreeRTOS, which can run under a qemu emulation target.
|
||||||
|
Since the instrumentation is based on snapshots, QEMU needs a virtual drive (even if it is unused...).
|
||||||
|
Thus, the makefile creates a dummy QCOW2 image `dummy.qcow2` (can be found in the `target directory`).
|
||||||
|
Currently the ``KERNEL`` variable is needed because the fuzzer does not parse QEMUs arguments to find the binary.
|
||||||
|
It is automatically set in the build script.
|
15
fuzzers/qemu_systemmode/build.rs
Normal file
15
fuzzers/qemu_systemmode/build.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#[macro_export]
|
||||||
|
macro_rules! assert_unique_feature {
|
||||||
|
() => {};
|
||||||
|
($first:tt $(,$rest:tt)*) => {
|
||||||
|
$(
|
||||||
|
#[cfg(all(not(any(doc, feature = "clippy")), feature = $first, feature = $rest))]
|
||||||
|
compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together"));
|
||||||
|
)*
|
||||||
|
assert_unique_feature!($($rest),*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_unique_feature!("classic", "breakpoint", "sync_exit");
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
arm-none-eabi-gcc -ggdb -ffreestanding -nostartfiles -lgcc -T mps2_m3.ld -mcpu=cortex-m3 main.c startup.c -o example.elf
|
|
@ -1,8 +1,15 @@
|
|||||||
|
#ifdef TARGET_SYNC_EXIT
|
||||||
|
#include "libafl_qemu.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int __attribute__((noinline)) BREAKPOINT() {
|
int __attribute__((noinline)) BREAKPOINT() {
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
|
int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
|
||||||
|
#ifdef TARGET_SYNC_EXIT
|
||||||
|
LIBAFL_EXIT_START_PHYS((unsigned int) Data, Size);
|
||||||
|
#endif
|
||||||
if (Data[3] == 0) {
|
if (Data[3] == 0) {
|
||||||
while (1) {}
|
while (1) {}
|
||||||
} // cause a timeout
|
} // cause a timeout
|
||||||
@ -19,6 +26,9 @@ int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef TARGET_SYNC_EXIT
|
||||||
|
LIBAFL_EXIT_END(LIBAFL_EXIT_END_OK);
|
||||||
|
#endif
|
||||||
return BREAKPOINT();
|
return BREAKPOINT();
|
||||||
}
|
}
|
||||||
unsigned int FUZZ_INPUT[] = {
|
unsigned int FUZZ_INPUT[] = {
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
//! A libfuzzer-like fuzzer using qemu for binary-only coverage
|
//! A libfuzzer-like fuzzer using qemu for binary-only coverage
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(all(target_os = "linux", feature = "classic"))]
|
||||||
mod fuzzer;
|
mod fuzzer_classic;
|
||||||
|
|
||||||
|
#[cfg(all(target_os = "linux", feature = "breakpoint"))]
|
||||||
|
mod fuzzer_breakpoint;
|
||||||
|
|
||||||
|
#[cfg(all(target_os = "linux", feature = "sync_exit"))]
|
||||||
|
mod fuzzer_sync_exit;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
fuzzer::fuzz();
|
#[cfg(feature = "classic")]
|
||||||
|
fuzzer_classic::fuzz();
|
||||||
|
|
||||||
|
#[cfg(feature = "breakpoint")]
|
||||||
|
fuzzer_breakpoint::fuzz();
|
||||||
|
|
||||||
|
#[cfg(feature = "sync_exit")]
|
||||||
|
fuzzer_sync_exit::fuzz();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
@ -1 +0,0 @@
|
|||||||
*.qcow2
|
|
@ -1,21 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "qemu_systemmode_breakpoints"
|
|
||||||
version = "0.11.1"
|
|
||||||
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenukk@gmail.com>", "Romain Malmain <romain.malmain@pm.me>"]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["std"]
|
|
||||||
std = []
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
incremental = true
|
|
||||||
debug = true
|
|
||||||
lto = "fat"
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
libafl = { path = "../../libafl/" }
|
|
||||||
libafl_bolts = { path = "../../libafl_bolts/" }
|
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"] }
|
|
||||||
env_logger = "*"
|
|
@ -1,26 +0,0 @@
|
|||||||
# Qemu systemmode with launcher
|
|
||||||
|
|
||||||
This folder contains an example fuzzer for the qemu systemmode, using LLMP for fast multi-process fuzzing and crash detection.
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
To build this example, run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build --release
|
|
||||||
cd example; sh build.sh; cd ..
|
|
||||||
```
|
|
||||||
|
|
||||||
This will build the the fuzzer (src/fuzzer.rs) and a small example binary based on FreeRTOS, which can run under a qemu emulation target.
|
|
||||||
|
|
||||||
## Run
|
|
||||||
|
|
||||||
Since the instrumentation is based on snapshtos QEMU needs a virtual drive (even if it is unused...).
|
|
||||||
Create on and then run the fuzzer:
|
|
||||||
```bash
|
|
||||||
# create an image
|
|
||||||
qemu-img create -f qcow2 dummy.qcow2 32M
|
|
||||||
# run the fuzzer
|
|
||||||
KERNEL=./example/example.elf target/release/qemu_systemmode -icount shift=auto,align=off,sleep=off -machine mps2-an385 -monitor null -kernel ./example/example.elf -serial null -nographic -snapshot -drive if=none,format=qcow2,file=dummy.qcow2 -S
|
|
||||||
```
|
|
||||||
Currently the ``KERNEL`` variable is needed because the fuzzer does not parse QEMUs arguments to find the binary.
|
|
@ -1 +0,0 @@
|
|||||||
<1F>y¯»Jv•<>ֵָ
l<>ֵp†אZGײ…rֶs‚Yֿס‘ֻ—CMRױ÷}קS7;Iֹo¿7ָ6זlע1<D7A2>˜1R¯¬ף׳ָ^־<>p¬ד¯>G÷&_¬<5F>˜|1½¾;ג¥ינװסr<D7A1>ח<EFBFBD>o4ג¼ֶ¯ֽU<D6BD>ׁE<`ש÷²÷ּLע"<22>ף6Vֶ·k<1D>4/³"–<>צtכקֺf7ײF¯°ְ<C2B0><D6B0>d]<5D>®%ץ|8•#wµוּNU›ƒnש‹8€<>%¼4ַo־<6F>ֻ—–
|
|
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
arm-none-eabi-gcc -ggdb -ffreestanding -nostartfiles -lgcc -T mps2_m3.ld -mcpu=cortex-m3 main.c startup.c -o example.elf
|
|
@ -1,33 +0,0 @@
|
|||||||
int __attribute__((noinline)) BREAKPOINT() {
|
|
||||||
for (;;) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
|
|
||||||
if (Data[3] == 0) {
|
|
||||||
while (1) {}
|
|
||||||
} // cause a timeout
|
|
||||||
for (int i = 0; i < Size; i++) {
|
|
||||||
// if (Data[i] > 0xFFd0 && Data[i] < 0xFFFF) {return 1;} // cause qemu to
|
|
||||||
// crash
|
|
||||||
for (int j = i + 1; j < Size; j++) {
|
|
||||||
if (Data[j] == 0) { continue; }
|
|
||||||
if (Data[j] > Data[i]) {
|
|
||||||
int tmp = Data[i];
|
|
||||||
Data[i] = Data[j];
|
|
||||||
Data[j] = tmp;
|
|
||||||
if (Data[i] <= 100) { j--; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return BREAKPOINT();
|
|
||||||
}
|
|
||||||
unsigned int FUZZ_INPUT[] = {
|
|
||||||
101, 201, 700, 230, 860, 234, 980, 200, 340, 678, 230, 134, 900,
|
|
||||||
236, 900, 123, 800, 123, 658, 607, 246, 804, 567, 568, 207, 407,
|
|
||||||
246, 678, 457, 892, 834, 456, 878, 246, 699, 854, 234, 844, 290,
|
|
||||||
125, 324, 560, 852, 928, 910, 790, 853, 345, 234, 586,
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
LLVMFuzzerTestOneInput(FUZZ_INPUT, 50);
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* FreeRTOS V202112.00
|
|
||||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* https://www.FreeRTOS.org
|
|
||||||
* https://github.com/FreeRTOS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 4M
|
|
||||||
/* Originally */
|
|
||||||
/* FLASH (xr) : ORIGIN = 0x00000000, LENGTH = 4M */
|
|
||||||
/* RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4M */
|
|
||||||
}
|
|
||||||
ENTRY(Reset_Handler)
|
|
||||||
|
|
||||||
_Min_Heap_Size = 0x300000 ; /* Required amount of heap. */
|
|
||||||
_Min_Stack_Size = 0x4000 ; /* Required amount of stack. */
|
|
||||||
M_VECTOR_RAM_SIZE = (16 + 48) * 4;
|
|
||||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
|
|
||||||
.isr_vector :
|
|
||||||
{
|
|
||||||
__vector_table = .;
|
|
||||||
KEEP(*(.isr_vector))
|
|
||||||
. = ALIGN(4);
|
|
||||||
} > RAM /* FLASH */
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.text*)
|
|
||||||
KEEP (*(.init))
|
|
||||||
KEEP (*(.fini))
|
|
||||||
KEEP(*(.eh_frame))
|
|
||||||
*(.rodata*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_etext = .;
|
|
||||||
} > RAM /* FLASH */
|
|
||||||
|
|
||||||
.ARM.extab :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >RAM /* FLASH */
|
|
||||||
|
|
||||||
.ARM :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
__exidx_start = .;
|
|
||||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
||||||
__exidx_end = .;
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >RAM /* FLASH */
|
|
||||||
|
|
||||||
.interrupts_ram :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
__VECTOR_RAM__ = .;
|
|
||||||
__interrupts_ram_start__ = .;
|
|
||||||
. += M_VECTOR_RAM_SIZE;
|
|
||||||
. = ALIGN(4);
|
|
||||||
__interrupts_ram_end = .;
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
_sidata = LOADADDR(.data);
|
|
||||||
|
|
||||||
.data : /* AT ( _sidata ) */
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sdata = .;
|
|
||||||
*(.data*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_edata = .;
|
|
||||||
} > RAM /* RAM AT > FLASH */
|
|
||||||
|
|
||||||
.uninitialized (NOLOAD):
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
__uninitialized_start = .;
|
|
||||||
*(.uninitialized)
|
|
||||||
KEEP(*(.keep.uninitialized))
|
|
||||||
. = ALIGN(32);
|
|
||||||
__uninitialized_end = .;
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.bss :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sbss = .;
|
|
||||||
__bss_start__ = _sbss;
|
|
||||||
*(.bss*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_ebss = .;
|
|
||||||
__bss_end__ = _ebss;
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
.heap :
|
|
||||||
{
|
|
||||||
. = ALIGN(8);
|
|
||||||
PROVIDE ( end = . );
|
|
||||||
PROVIDE ( _end = . );
|
|
||||||
_heap_bottom = .;
|
|
||||||
. = . + _Min_Heap_Size;
|
|
||||||
_heap_top = .;
|
|
||||||
. = . + _Min_Stack_Size;
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
/* Set stack top to end of RAM, and stack limit move down by
|
|
||||||
* size of stack_dummy section */
|
|
||||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
|
||||||
__StackLimit = __StackTop - _Min_Stack_Size;
|
|
||||||
PROVIDE(__stack = __StackTop);
|
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds RAM limit */
|
|
||||||
ASSERT(__StackLimit >= _heap_top, "region RAM overflowed with stack")
|
|
||||||
}
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* FreeRTOS V202112.00
|
|
||||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* https://www.FreeRTOS.org
|
|
||||||
* https://github.com/FreeRTOS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
|
|
||||||
extern int main();
|
|
||||||
|
|
||||||
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;
|
|
||||||
|
|
||||||
/* Prevent optimization so gcc does not replace code with memcpy */
|
|
||||||
__attribute__((optimize("O0"))) __attribute__((naked)) void Reset_Handler(
|
|
||||||
void) {
|
|
||||||
/* set stack pointer */
|
|
||||||
__asm volatile("ldr r0, =_estack");
|
|
||||||
__asm volatile("mov sp, r0");
|
|
||||||
|
|
||||||
/* copy .data section from flash to RAM */
|
|
||||||
// Not needed for this example, see linker script
|
|
||||||
// for( uint32_t * src = &_sidata, * dest = &_sdata; dest < &_edata; )
|
|
||||||
// {
|
|
||||||
// *dest++ = *src++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* zero out .bss section */
|
|
||||||
for (uint32_t *dest = &_sbss; dest < &_ebss;) {
|
|
||||||
*dest++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* jump to board initialisation */
|
|
||||||
void _start(void);
|
|
||||||
_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t *isr_vector[] __attribute__((section(".isr_vector"))) = {
|
|
||||||
(uint32_t *)&_estack,
|
|
||||||
(uint32_t *)&Reset_Handler, /* Reset -15 */
|
|
||||||
0, /* NMI_Handler -14 */
|
|
||||||
0, /* HardFault_Handler -13 */
|
|
||||||
0, /* MemManage_Handler -12 */
|
|
||||||
0, /* BusFault_Handler -11 */
|
|
||||||
0, /* UsageFault_Handler -10 */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved -6 */
|
|
||||||
0, /* SVC_Handler -5 */
|
|
||||||
0, /* DebugMon_Handler -4 */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* PendSV handler -2 */
|
|
||||||
0, /* SysTick_Handler -1 */
|
|
||||||
0, /* uart0 receive 0 */
|
|
||||||
0, /* uart0 transmit */
|
|
||||||
0, /* uart1 receive */
|
|
||||||
0, /* uart1 transmit */
|
|
||||||
0, /* uart 2 receive */
|
|
||||||
0, /* uart 2 transmit */
|
|
||||||
0, /* GPIO 0 combined interrupt */
|
|
||||||
0, /* GPIO 2 combined interrupt */
|
|
||||||
0, /* Timer 0 */
|
|
||||||
0, /* Timer 1 */
|
|
||||||
0, /* Dial Timer */
|
|
||||||
0, /* SPI0 SPI1 */
|
|
||||||
0, /* uart overflow 1, 2,3 */
|
|
||||||
0, /* Ethernet 13 */
|
|
||||||
};
|
|
||||||
|
|
||||||
__attribute__((naked)) void exit(__attribute__((unused)) int status) {
|
|
||||||
/* Force qemu to exit using ARM Semihosting */
|
|
||||||
__asm volatile(
|
|
||||||
"mov r1, r0\n"
|
|
||||||
"cmp r1, #0\n"
|
|
||||||
"bne .notclean\n"
|
|
||||||
"ldr r1, =0x20026\n" /* ADP_Stopped_ApplicationExit, a clean exit */
|
|
||||||
".notclean:\n"
|
|
||||||
"movs r0, #0x18\n" /* SYS_EXIT */
|
|
||||||
"bkpt 0xab\n"
|
|
||||||
"end: b end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _start(void) {
|
|
||||||
main();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
//! A libfuzzer-like fuzzer using qemu for binary-only coverage
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod fuzzer;
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn main() {
|
|
||||||
fuzzer::fuzz();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
pub fn main() {
|
|
||||||
panic!("qemu-user and libafl_qemu is only supported on linux!");
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
*.qcow2
|
|
@ -1,21 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "qemu_systemmode_sync_backdoor"
|
|
||||||
version = "0.11.1"
|
|
||||||
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenukk@gmail.com>", "Romain Malmain <romain.malmain@pm.me>"]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["std"]
|
|
||||||
std = []
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
incremental = true
|
|
||||||
debug = true
|
|
||||||
lto = "fat"
|
|
||||||
codegen-units = 1
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
libafl = { path = "../../libafl/" }
|
|
||||||
libafl_bolts = { path = "../../libafl_bolts/" }
|
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"] }
|
|
||||||
env_logger = "*"
|
|
@ -1,26 +0,0 @@
|
|||||||
# Qemu systemmode with launcher
|
|
||||||
|
|
||||||
This folder contains an example fuzzer for the qemu systemmode, using LLMP for fast multi-process fuzzing and crash detection.
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
To build this example, run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build --release
|
|
||||||
cd example; sh build.sh; cd ..
|
|
||||||
```
|
|
||||||
|
|
||||||
This will build the the fuzzer (src/fuzzer.rs) and a small example binary based on FreeRTOS, which can run under a qemu emulation target.
|
|
||||||
|
|
||||||
## Run
|
|
||||||
|
|
||||||
Since the instrumentation is based on snapshtos QEMU needs a virtual drive (even if it is unused...).
|
|
||||||
Create on and then run the fuzzer:
|
|
||||||
```bash
|
|
||||||
# create an image
|
|
||||||
qemu-img create -f qcow2 dummy.qcow2 32M
|
|
||||||
# run the fuzzer
|
|
||||||
KERNEL=./example/example.elf target/release/qemu_systemmode -icount shift=auto,align=off,sleep=off -machine mps2-an385 -monitor null -kernel ./example/example.elf -serial null -nographic -snapshot -drive if=none,format=qcow2,file=dummy.qcow2 -S
|
|
||||||
```
|
|
||||||
Currently the ``KERNEL`` variable is needed because the fuzzer does not parse QEMUs arguments to find the binary.
|
|
@ -1 +0,0 @@
|
|||||||
<1F>y¯»Jv•<>ֵָ
l<>ֵp†אZGײ…rֶs‚Yֿס‘ֻ—CMRױ÷}קS7;Iֹo¿7ָ6זlע1<D7A2>˜1R¯¬ף׳ָ^־<>p¬ד¯>G÷&_¬<5F>˜|1½¾;ג¥ינװסr<D7A1>ח<EFBFBD>o4ג¼ֶ¯ֽU<D6BD>ׁE<`ש÷²÷ּLע"<22>ף6Vֶ·k<1D>4/³"–<>צtכקֺf7ײF¯°ְ<C2B0><D6B0>d]<5D>®%ץ|8•#wµוּNU›ƒnש‹8€<>%¼4ַo־<6F>ֻ—–
|
|
Binary file not shown.
@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
arm-none-eabi-gcc -ggdb -ffreestanding -nostartfiles -lgcc -T mps2_m3.ld -mcpu=cortex-m3 -I../../../libafl_qemu/runtime main.c startup.c -o example.elf
|
|
@ -1,37 +0,0 @@
|
|||||||
#include "libafl_exit.h"
|
|
||||||
|
|
||||||
int __attribute__((noinline)) BREAKPOINT() {
|
|
||||||
for (;;) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
|
|
||||||
LIBAFL_EXIT_START_PHYS((unsigned int) Data, Size);
|
|
||||||
// if (Data[3] == 0) {
|
|
||||||
// while (1) {}
|
|
||||||
// } // cause a timeout
|
|
||||||
for (int i = 0; i < Size; i++) {
|
|
||||||
// if (Data[i] > 0xFFd0 && Data[i] < 0xFFFF) {return 1;} // cause qemu to
|
|
||||||
// crash
|
|
||||||
for (int j = i + 1; j < Size; j++) {
|
|
||||||
if (Data[j] == 0) { continue; }
|
|
||||||
if (Data[j] > Data[i]) {
|
|
||||||
int tmp = Data[i];
|
|
||||||
Data[i] = Data[j];
|
|
||||||
Data[j] = tmp;
|
|
||||||
if (Data[i] <= 100) { j--; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LIBAFL_EXIT_END(LIBAFL_EXIT_END_OK);
|
|
||||||
return BREAKPOINT();
|
|
||||||
}
|
|
||||||
unsigned int FUZZ_INPUT[] = {
|
|
||||||
101, 201, 700, 230, 860, 234, 980, 200, 340, 678, 230, 134, 900,
|
|
||||||
236, 900, 123, 800, 123, 658, 607, 246, 804, 567, 568, 207, 407,
|
|
||||||
246, 678, 457, 892, 834, 456, 878, 246, 699, 854, 234, 844, 290,
|
|
||||||
125, 324, 560, 852, 928, 910, 790, 853, 345, 234, 586,
|
|
||||||
};
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
LLVMFuzzerTestOneInput(FUZZ_INPUT, 50);
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* FreeRTOS V202112.00
|
|
||||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* https://www.FreeRTOS.org
|
|
||||||
* https://github.com/FreeRTOS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
RAM (xrw) : ORIGIN = 0x00000000, LENGTH = 4M
|
|
||||||
/* Originally */
|
|
||||||
/* FLASH (xr) : ORIGIN = 0x00000000, LENGTH = 4M */
|
|
||||||
/* RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4M */
|
|
||||||
}
|
|
||||||
ENTRY(Reset_Handler)
|
|
||||||
|
|
||||||
_Min_Heap_Size = 0x300000 ; /* Required amount of heap. */
|
|
||||||
_Min_Stack_Size = 0x4000 ; /* Required amount of stack. */
|
|
||||||
M_VECTOR_RAM_SIZE = (16 + 48) * 4;
|
|
||||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
|
|
||||||
.isr_vector :
|
|
||||||
{
|
|
||||||
__vector_table = .;
|
|
||||||
KEEP(*(.isr_vector))
|
|
||||||
. = ALIGN(4);
|
|
||||||
} > RAM /* FLASH */
|
|
||||||
|
|
||||||
.text :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.text*)
|
|
||||||
KEEP (*(.init))
|
|
||||||
KEEP (*(.fini))
|
|
||||||
KEEP(*(.eh_frame))
|
|
||||||
*(.rodata*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_etext = .;
|
|
||||||
} > RAM /* FLASH */
|
|
||||||
|
|
||||||
.ARM.extab :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >RAM /* FLASH */
|
|
||||||
|
|
||||||
.ARM :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
__exidx_start = .;
|
|
||||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
||||||
__exidx_end = .;
|
|
||||||
. = ALIGN(4);
|
|
||||||
} >RAM /* FLASH */
|
|
||||||
|
|
||||||
.interrupts_ram :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
__VECTOR_RAM__ = .;
|
|
||||||
__interrupts_ram_start__ = .;
|
|
||||||
. += M_VECTOR_RAM_SIZE;
|
|
||||||
. = ALIGN(4);
|
|
||||||
__interrupts_ram_end = .;
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
_sidata = LOADADDR(.data);
|
|
||||||
|
|
||||||
.data : /* AT ( _sidata ) */
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sdata = .;
|
|
||||||
*(.data*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_edata = .;
|
|
||||||
} > RAM /* RAM AT > FLASH */
|
|
||||||
|
|
||||||
.uninitialized (NOLOAD):
|
|
||||||
{
|
|
||||||
. = ALIGN(32);
|
|
||||||
__uninitialized_start = .;
|
|
||||||
*(.uninitialized)
|
|
||||||
KEEP(*(.keep.uninitialized))
|
|
||||||
. = ALIGN(32);
|
|
||||||
__uninitialized_end = .;
|
|
||||||
} > RAM
|
|
||||||
|
|
||||||
.bss :
|
|
||||||
{
|
|
||||||
. = ALIGN(4);
|
|
||||||
_sbss = .;
|
|
||||||
__bss_start__ = _sbss;
|
|
||||||
*(.bss*)
|
|
||||||
*(COMMON)
|
|
||||||
. = ALIGN(4);
|
|
||||||
_ebss = .;
|
|
||||||
__bss_end__ = _ebss;
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
.heap :
|
|
||||||
{
|
|
||||||
. = ALIGN(8);
|
|
||||||
PROVIDE ( end = . );
|
|
||||||
PROVIDE ( _end = . );
|
|
||||||
_heap_bottom = .;
|
|
||||||
. = . + _Min_Heap_Size;
|
|
||||||
_heap_top = .;
|
|
||||||
. = . + _Min_Stack_Size;
|
|
||||||
. = ALIGN(8);
|
|
||||||
} >RAM
|
|
||||||
|
|
||||||
/* Set stack top to end of RAM, and stack limit move down by
|
|
||||||
* size of stack_dummy section */
|
|
||||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
|
||||||
__StackLimit = __StackTop - _Min_Stack_Size;
|
|
||||||
PROVIDE(__stack = __StackTop);
|
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds RAM limit */
|
|
||||||
ASSERT(__StackLimit >= _heap_top, "region RAM overflowed with stack")
|
|
||||||
}
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* FreeRTOS V202112.00
|
|
||||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* https://www.FreeRTOS.org
|
|
||||||
* https://github.com/FreeRTOS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
|
|
||||||
extern int main();
|
|
||||||
|
|
||||||
extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss;
|
|
||||||
|
|
||||||
/* Prevent optimization so gcc does not replace code with memcpy */
|
|
||||||
__attribute__((optimize("O0"))) __attribute__((naked)) void Reset_Handler(
|
|
||||||
void) {
|
|
||||||
/* set stack pointer */
|
|
||||||
__asm volatile("ldr r0, =_estack");
|
|
||||||
__asm volatile("mov sp, r0");
|
|
||||||
|
|
||||||
/* copy .data section from flash to RAM */
|
|
||||||
// Not needed for this example, see linker script
|
|
||||||
// for( uint32_t * src = &_sidata, * dest = &_sdata; dest < &_edata; )
|
|
||||||
// {
|
|
||||||
// *dest++ = *src++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* zero out .bss section */
|
|
||||||
for (uint32_t *dest = &_sbss; dest < &_ebss;) {
|
|
||||||
*dest++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* jump to board initialisation */
|
|
||||||
void _start(void);
|
|
||||||
_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t *isr_vector[] __attribute__((section(".isr_vector"))) = {
|
|
||||||
(uint32_t *)&_estack,
|
|
||||||
(uint32_t *)&Reset_Handler, /* Reset -15 */
|
|
||||||
0, /* NMI_Handler -14 */
|
|
||||||
0, /* HardFault_Handler -13 */
|
|
||||||
0, /* MemManage_Handler -12 */
|
|
||||||
0, /* BusFault_Handler -11 */
|
|
||||||
0, /* UsageFault_Handler -10 */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* reserved -6 */
|
|
||||||
0, /* SVC_Handler -5 */
|
|
||||||
0, /* DebugMon_Handler -4 */
|
|
||||||
0, /* reserved */
|
|
||||||
0, /* PendSV handler -2 */
|
|
||||||
0, /* SysTick_Handler -1 */
|
|
||||||
0, /* uart0 receive 0 */
|
|
||||||
0, /* uart0 transmit */
|
|
||||||
0, /* uart1 receive */
|
|
||||||
0, /* uart1 transmit */
|
|
||||||
0, /* uart 2 receive */
|
|
||||||
0, /* uart 2 transmit */
|
|
||||||
0, /* GPIO 0 combined interrupt */
|
|
||||||
0, /* GPIO 2 combined interrupt */
|
|
||||||
0, /* Timer 0 */
|
|
||||||
0, /* Timer 1 */
|
|
||||||
0, /* Dial Timer */
|
|
||||||
0, /* SPI0 SPI1 */
|
|
||||||
0, /* uart overflow 1, 2,3 */
|
|
||||||
0, /* Ethernet 13 */
|
|
||||||
};
|
|
||||||
|
|
||||||
__attribute__((naked)) void exit(__attribute__((unused)) int status) {
|
|
||||||
/* Force qemu to exit using ARM Semihosting */
|
|
||||||
__asm volatile(
|
|
||||||
"mov r1, r0\n"
|
|
||||||
"cmp r1, #0\n"
|
|
||||||
"bne .notclean\n"
|
|
||||||
"ldr r1, =0x20026\n" /* ADP_Stopped_ApplicationExit, a clean exit */
|
|
||||||
".notclean:\n"
|
|
||||||
"movs r0, #0x18\n" /* SYS_EXIT */
|
|
||||||
"bkpt 0xab\n"
|
|
||||||
"end: b end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _start(void) {
|
|
||||||
main();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
//! A libfuzzer-like fuzzer using qemu for binary-only coverage
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod fuzzer;
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub fn main() {
|
|
||||||
fuzzer::fuzz();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
pub fn main() {
|
|
||||||
panic!("qemu-user and libafl_qemu is only supported on linux!");
|
|
||||||
}
|
|
@ -14,10 +14,12 @@ pub fn build() {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let libafl_qemu_hdr_name = "libafl_qemu.h";
|
||||||
|
|
||||||
let build_libqasan = cfg!(all(feature = "build_libqasan", not(feature = "hexagon")));
|
let build_libqasan = cfg!(all(feature = "build_libqasan", not(feature = "hexagon")));
|
||||||
|
|
||||||
let exit_hdr_dir = PathBuf::from("runtime");
|
let exit_hdr_dir = PathBuf::from("runtime");
|
||||||
let exit_hdr = exit_hdr_dir.join("libafl_exit.h");
|
let libafl_qemu_hdr = exit_hdr_dir.join(libafl_qemu_hdr_name);
|
||||||
|
|
||||||
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
|
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
|
||||||
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
|
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
|
||||||
@ -72,6 +74,11 @@ pub fn build() {
|
|||||||
target_dir.pop();
|
target_dir.pop();
|
||||||
target_dir.pop();
|
target_dir.pop();
|
||||||
target_dir.pop();
|
target_dir.pop();
|
||||||
|
let include_dir = target_dir.join("include");
|
||||||
|
|
||||||
|
fs::create_dir_all(&include_dir).expect("Could not create include dir");
|
||||||
|
|
||||||
|
fs::copy(libafl_qemu_hdr.clone(), include_dir.join(libafl_qemu_hdr_name)).expect("Could not copy libafl_qemu.h to out directory.");
|
||||||
|
|
||||||
let binding_file = out_dir_path_buf.join("backdoor_bindings.rs");
|
let binding_file = out_dir_path_buf.join("backdoor_bindings.rs");
|
||||||
bindgen::Builder::default()
|
bindgen::Builder::default()
|
||||||
@ -83,7 +90,7 @@ pub fn build() {
|
|||||||
is_global: true,
|
is_global: true,
|
||||||
is_bitfield: true,
|
is_bitfield: true,
|
||||||
})
|
})
|
||||||
.header(exit_hdr.display().to_string())
|
.header(libafl_qemu_hdr.display().to_string())
|
||||||
.generate()
|
.generate()
|
||||||
.expect("Exit bindings generation failed.")
|
.expect("Exit bindings generation failed.")
|
||||||
.write_to_file(binding_file)
|
.write_to_file(binding_file)
|
||||||
|
@ -1,176 +0,0 @@
|
|||||||
#ifndef LIBAFL_EXIT_H
|
|
||||||
#define LIBAFL_EXIT_H
|
|
||||||
|
|
||||||
#define STRINGIFY(s) #s
|
|
||||||
#define XSTRINGIFY(s) STRINGIFY(s)
|
|
||||||
|
|
||||||
// Target Specific imports / definitions
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <intsafe.h>
|
|
||||||
|
|
||||||
typedef UINT64 libafl_word;
|
|
||||||
#define LIBAFL_CALLING_CONVENTION __fastcall
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __x86_64__
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef uint64_t libafl_word;
|
|
||||||
#define LIBAFL_CALLING_CONVENTION __attribute__(())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __arm__
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef uint32_t libafl_word;
|
|
||||||
#define LIBAFL_CALLING_CONVENTION __attribute__(())
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBAFL_EXIT_OPCODE 0x66f23a0f
|
|
||||||
#define LIBAFL_EXIT_VERSION_NUMBER 0111 // TODO: find a nice way to set it.
|
|
||||||
|
|
||||||
typedef enum LibaflExit {
|
|
||||||
LIBAFL_EXIT_START_VIRT = 0,
|
|
||||||
LIBAFL_EXIT_START_PHYS = 1,
|
|
||||||
LIBAFL_EXIT_INPUT_VIRT = 2,
|
|
||||||
LIBAFL_EXIT_INPUT_PHYS = 3,
|
|
||||||
LIBAFL_EXIT_END = 4,
|
|
||||||
LIBAFL_EXIT_SAVE = 5,
|
|
||||||
LIBAFL_EXIT_LOAD = 6,
|
|
||||||
LIBAFL_EXIT_VERSION = 7,
|
|
||||||
LIBAFL_EXIT_VADDR_FILTER_ALLOW = 8,
|
|
||||||
} LibaflExit;
|
|
||||||
|
|
||||||
typedef enum LibaflExitEndStatus {
|
|
||||||
LIBAFL_EXIT_END_UNKNOWN = 0,
|
|
||||||
LIBAFL_EXIT_END_OK = 1,
|
|
||||||
LIBAFL_EXIT_END_CRASH = 2,
|
|
||||||
} LibaflExitEndParams;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call0(libafl_word action);
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call1(libafl_word action,
|
|
||||||
libafl_word arg1);
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call2(libafl_word action,
|
|
||||||
libafl_word arg1,
|
|
||||||
libafl_word arg2);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call0(libafl_word action) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov %1, %%rax\n"
|
|
||||||
".dword " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %%rax, %0\n"
|
|
||||||
: "=g"(ret)
|
|
||||||
: "g"(action)
|
|
||||||
: "%rax"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call1(libafl_word action,
|
|
||||||
libafl_word arg1) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov %1, %%rax\n"
|
|
||||||
"mov %2, %%rdi\n"
|
|
||||||
".dword " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %%rax, %0\n"
|
|
||||||
: "=g"(ret)
|
|
||||||
: "g"(action), "g"(arg1)
|
|
||||||
: "%rax", "%rdi"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call2(libafl_word action,
|
|
||||||
libafl_word arg1,
|
|
||||||
libafl_word arg2) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov %1, %%rax\n"
|
|
||||||
"mov %2, %%rdi\n"
|
|
||||||
"mov %3, %%rsi\n"
|
|
||||||
".dword " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %%rax, %0\n"
|
|
||||||
: "=g"(ret)
|
|
||||||
: "g"(action), "g"(arg1), "g"(arg2)
|
|
||||||
: "%rax", "%rdi", "%rsi"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __arm__
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call0(libafl_word action) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov r0, %1\n"
|
|
||||||
".word " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %0, r0\n"
|
|
||||||
: "=r"(ret)
|
|
||||||
: "r"(action)
|
|
||||||
: "r0"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call1(libafl_word action,
|
|
||||||
libafl_word arg1) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov r0, %1\n"
|
|
||||||
"mov r1, %2\n"
|
|
||||||
".word " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %0, r0\n"
|
|
||||||
: "=r"(ret)
|
|
||||||
: "r"(action), "r"(arg1)
|
|
||||||
: "r0", "r1"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call2(libafl_word action,
|
|
||||||
libafl_word arg1,
|
|
||||||
libafl_word arg2) {
|
|
||||||
libafl_word ret;
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov r0, %1\n"
|
|
||||||
"mov r1, %2\n"
|
|
||||||
"mov r2, %3\n"
|
|
||||||
".word " XSTRINGIFY(LIBAFL_EXIT_OPCODE) "\n"
|
|
||||||
"mov %0, r0\n"
|
|
||||||
: "=r"(ret)
|
|
||||||
: "r"(action), "r"(arg1), "r"(arg2)
|
|
||||||
: "r0", "r1", "r2"
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIBAFL_EXIT_START_VIRT(buf_vaddr, max_len) \
|
|
||||||
_libafl_exit_call2(LIBAFL_EXIT_START_VIRT, buf_vaddr, max_len)
|
|
||||||
#define LIBAFL_EXIT_START_PHYS(buf_paddr, max_len) \
|
|
||||||
_libafl_exit_call2(LIBAFL_EXIT_START_PHYS, buf_paddr, max_len)
|
|
||||||
#define LIBAFL_EXIT_INPUT_VIRT(buf_vaddr, max_len) \
|
|
||||||
_libafl_exit_call2(LIBAFL_EXIT_INPUT_VIRT, buf_vaddr, max_len)
|
|
||||||
#define LIBAFL_EXIT_INPUT_PHYS(buf_paddr, max_len) \
|
|
||||||
_libafl_exit_call2(LIBAFL_EXIT_INPUT_PHYS, buf_paddr, max_len)
|
|
||||||
#define LIBAFL_EXIT_END(status) _libafl_exit_call1(LIBAFL_EXIT_END, status)
|
|
||||||
#define LIBAFL_EXIT_SAVE() _libafl_exit_call0(LIBAFL_EXIT_SAVE)
|
|
||||||
#define LIBAFL_EXIT_LOAD() _libafl_exit_call0(LIBAFL_EXIT_LOAD)
|
|
||||||
#define LIBAFL_EXIT_VERSION() _libafl_exit_call0(LIBAFL_EXIT_VERSION_NUMBER)
|
|
||||||
|
|
||||||
#endif
|
|
216
libafl_qemu/runtime/libafl_qemu.h
Normal file
216
libafl_qemu/runtime/libafl_qemu.h
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#ifndef LIBAFL_EXIT_H
|
||||||
|
#define LIBAFL_EXIT_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LibAFL QEMU header file.
|
||||||
|
*
|
||||||
|
* This file is a portable header file used to build target harnesses more
|
||||||
|
* conveniently. Its main purpose is to generate ready-to-use calls to
|
||||||
|
* communicate with the fuzzer. The list of commands is available at the bottom
|
||||||
|
* of this file. The rest mostly consists of macros generating the code used by
|
||||||
|
* the commands.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* === The private part starts here === */
|
||||||
|
|
||||||
|
/* This part should not be useful for most people. Callable commands are
|
||||||
|
* available at the end of this file. */
|
||||||
|
|
||||||
|
#define STRINGIFY(s) #s
|
||||||
|
#define XSTRINGIFY(s) STRINGIFY(s)
|
||||||
|
|
||||||
|
// Target Specific imports / definitions
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <intsafe.h>
|
||||||
|
|
||||||
|
typedef UINT64 libafl_word;
|
||||||
|
#define LIBAFL_CALLING_CONVENTION __fastcall
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uint64_t libafl_word;
|
||||||
|
#define LIBAFL_CALLING_CONVENTION __attribute__(())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __arm__
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uint32_t libafl_word;
|
||||||
|
#define LIBAFL_CALLING_CONVENTION __attribute__(())
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_OPCODE 0x66f23a0f
|
||||||
|
#define LIBAFL_BACKDOOR_OPCODE 0x44f23a0f
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_VERSION_NUMBER 0111 // TODO: find a nice way to set it.
|
||||||
|
|
||||||
|
typedef enum LibaflExit {
|
||||||
|
LIBAFL_EXIT_START_VIRT = 0,
|
||||||
|
LIBAFL_EXIT_START_PHYS = 1,
|
||||||
|
LIBAFL_EXIT_INPUT_VIRT = 2,
|
||||||
|
LIBAFL_EXIT_INPUT_PHYS = 3,
|
||||||
|
LIBAFL_EXIT_END = 4,
|
||||||
|
LIBAFL_EXIT_SAVE = 5,
|
||||||
|
LIBAFL_EXIT_LOAD = 6,
|
||||||
|
LIBAFL_EXIT_VERSION = 7,
|
||||||
|
LIBAFL_EXIT_VADDR_FILTER_ALLOW = 8,
|
||||||
|
} LibaflExit;
|
||||||
|
|
||||||
|
typedef enum LibaflExitEndStatus {
|
||||||
|
LIBAFL_EXIT_END_UNKNOWN = 0,
|
||||||
|
LIBAFL_EXIT_END_OK = 1,
|
||||||
|
LIBAFL_EXIT_END_CRASH = 2,
|
||||||
|
} LibaflExitEndParams;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call0(libafl_word action);
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call1(libafl_word action,
|
||||||
|
libafl_word arg1);
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_exit_call2(libafl_word action,
|
||||||
|
libafl_word arg1,
|
||||||
|
libafl_word arg2);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \
|
||||||
|
libafl_word action) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov %1, %%rax\n" \
|
||||||
|
".dword " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %%rax, %0\n" \
|
||||||
|
: "=g"(ret) \
|
||||||
|
: "g"(action) \
|
||||||
|
: "%rax" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \
|
||||||
|
libafl_word action, libafl_word arg1) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov %1, %%rax\n" \
|
||||||
|
"mov %2, %%rdi\n" \
|
||||||
|
".dword " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %%rax, %0\n" \
|
||||||
|
: "=g"(ret) \
|
||||||
|
: "g"(action), "g"(arg1) \
|
||||||
|
: "%rax", "%rdi" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \
|
||||||
|
libafl_word action, libafl_word arg1, libafl_word arg2) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov %1, %%rax\n" \
|
||||||
|
"mov %2, %%rdi\n" \
|
||||||
|
"mov %3, %%rsi\n" \
|
||||||
|
".dword " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %%rax, %0\n" \
|
||||||
|
: "=g"(ret) \
|
||||||
|
: "g"(action), "g"(arg1), "g"(arg2) \
|
||||||
|
: "%rax", "%rdi", "%rsi" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __arm__
|
||||||
|
#define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \
|
||||||
|
libafl_word action) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov r0, %1\n" \
|
||||||
|
".word " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %0, r0\n" \
|
||||||
|
: "=r"(ret) \
|
||||||
|
: "r"(action) \
|
||||||
|
: "r0" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \
|
||||||
|
libafl_word action, libafl_word arg1) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov r0, %1\n" \
|
||||||
|
"mov r1, %2\n" \
|
||||||
|
".word " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %0, r0\n" \
|
||||||
|
: "=r"(ret) \
|
||||||
|
: "r"(action), "r"(arg1) \
|
||||||
|
: "r0", "r1" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \
|
||||||
|
libafl_word action, libafl_word arg1, libafl_word arg2) { \
|
||||||
|
libafl_word ret; \
|
||||||
|
__asm__ volatile ( \
|
||||||
|
"mov r0, %1\n" \
|
||||||
|
"mov r1, %2\n" \
|
||||||
|
"mov r2, %3\n" \
|
||||||
|
".word " XSTRINGIFY(opcode) "\n" \
|
||||||
|
"mov %0, r0\n" \
|
||||||
|
: "=r"(ret) \
|
||||||
|
: "r"(action), "r"(arg1), "r"(arg2) \
|
||||||
|
: "r0", "r1", "r2" \
|
||||||
|
); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Generates sync exit functions
|
||||||
|
LIBAFL_DEFINE_FUNCTIONS(exit, LIBAFL_EXIT_OPCODE)
|
||||||
|
|
||||||
|
// Generates backdoor functions
|
||||||
|
LIBAFL_DEFINE_FUNCTIONS(backdoor, LIBAFL_BACKDOOR_OPCODE)
|
||||||
|
|
||||||
|
/* === The private part ends here === */
|
||||||
|
|
||||||
|
/* === The public part starts here === */
|
||||||
|
|
||||||
|
/* Commands */
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_START_VIRT(buf_vaddr, max_len) \
|
||||||
|
_libafl_exit_call2(LIBAFL_EXIT_START_VIRT, buf_vaddr, max_len)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_START_PHYS(buf_paddr, max_len) \
|
||||||
|
_libafl_exit_call2(LIBAFL_EXIT_START_PHYS, buf_paddr, max_len)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_INPUT_VIRT(buf_vaddr, max_len) \
|
||||||
|
_libafl_exit_call2(LIBAFL_EXIT_INPUT_VIRT, buf_vaddr, max_len)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_INPUT_PHYS(buf_paddr, max_len) \
|
||||||
|
_libafl_exit_call2(LIBAFL_EXIT_INPUT_PHYS, buf_paddr, max_len)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_END(status) _libafl_exit_call1(LIBAFL_EXIT_END, status)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_SAVE() _libafl_exit_call0(LIBAFL_EXIT_SAVE)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_LOAD() _libafl_exit_call0(LIBAFL_EXIT_LOAD)
|
||||||
|
|
||||||
|
#define LIBAFL_EXIT_VERSION() _libafl_exit_call0(LIBAFL_EXIT_VERSION_NUMBER)
|
||||||
|
|
||||||
|
/* === The public part ends here === */
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user