TinyInst Update (#968)
* tmp * more * save * TODO * fix * update to tinyinst on crates * dep * fmt * shmem done * cpp fmt * clp * fmt * why?? * ver * more makefile.toml * windows test * Update build_and_test.yml * fix * a * install * fmt * fix * only macos and win * more * The order matters * remove * fmt * chg * typo Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
parent
3b68399cc9
commit
fe51286586
9
.github/workflows/build_and_test.yml
vendored
9
.github/workflows/build_and_test.yml
vendored
@ -173,6 +173,9 @@ jobs:
|
||||
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
||||
- name: Add no_std toolchain
|
||||
run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
||||
- name: Install cxxbridge
|
||||
if: runner.os == 'macOS'
|
||||
run: cargo install cxxbridge-cmd
|
||||
- name: Install python (macOS)
|
||||
# Removing macOS things already installed in CI against failed linking
|
||||
if: runner.os == 'macOS'
|
||||
@ -255,10 +258,14 @@ jobs:
|
||||
- name: install cargo-make
|
||||
run: cargo install --force cargo-make
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: install cxx bridge
|
||||
run: cargo install cxxbridge-cmd
|
||||
- name: Build fuzzers/frida_libpng
|
||||
run: cd fuzzers/frida_libpng/ && cargo make test
|
||||
- name: Build fuzzers/frida_gdiplus
|
||||
run: cd fuzzers/frida_gdiplus/ && cargo make test
|
||||
- name: Build fuzzers/tinyinst_simple
|
||||
run: cd fuzzers/tinyinst_simple/ && cargo make test
|
||||
|
||||
macos:
|
||||
runs-on: macOS-latest
|
||||
@ -271,6 +278,8 @@ jobs:
|
||||
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
||||
- name: Install deps
|
||||
run: brew install z3 gtk+3
|
||||
- name: Install cxxbridge
|
||||
run: cargo install cxxbridge-cmd
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: MacOS Build
|
||||
|
@ -6,8 +6,8 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libafl = { version = "0.8.1", path = "../../libafl", features = ["tui"] }
|
||||
libafl_tinyinst = { version = "0.8.1", path = "../../libafl_tinyinst" }
|
||||
libafl = { version = "0.8.2", path = "../../libafl", features = ["introspection"] }
|
||||
libafl_tinyinst = { version = "0.8.2", path = "../../libafl_tinyinst" }
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
|
@ -1,8 +1,56 @@
|
||||
[tasks.build_test]
|
||||
command = "cl"
|
||||
args = ["./test/test.c", "-o", "./test/test.exe"]
|
||||
[tasks.unsupported]
|
||||
script_runner="@shell"
|
||||
script='''
|
||||
echo "Cargo-make not integrated yet on this"
|
||||
'''
|
||||
|
||||
# Harness
|
||||
[tasks.harness]
|
||||
linux_alias = "unsupported"
|
||||
mac_alias = "unsupported"
|
||||
windows_alias = "harness_windows"
|
||||
|
||||
[tasks.harness_windows]
|
||||
script='''
|
||||
cl test\test.cpp -o test.exe
|
||||
'''
|
||||
|
||||
# Fuzzer
|
||||
[tasks.fuzzer]
|
||||
linux_alias = "unsupported"
|
||||
mac_alias = "unsupported"
|
||||
windows_alias = "fuzzer_windows"
|
||||
|
||||
[tasks.fuzzer_windows]
|
||||
dependencies = ["harness"]
|
||||
command = "cargo"
|
||||
args = ["build", "--release"]
|
||||
|
||||
# Run the fuzzer
|
||||
[tasks.run]
|
||||
dependencies = ["build_test"]
|
||||
linux_alias = "unsupported"
|
||||
mac_alias = "unsupported"
|
||||
windows_alias = "run_windows"
|
||||
|
||||
[tasks.run_windows]
|
||||
dependencies = ["harness", "fuzzer"]
|
||||
command = "cargo"
|
||||
args = ["run", "--release"]
|
||||
|
||||
|
||||
# Run the fuzzer
|
||||
[tasks.test]
|
||||
linux_alias = "unsupported"
|
||||
mac_alias = "unsupported"
|
||||
windows_alias = "test_windows"
|
||||
|
||||
[tasks.test_windows]
|
||||
script_runner = "@shell"
|
||||
script='''
|
||||
copy .\target\release\tinyinst_simple.exe .
|
||||
start "" "tinyinst_simple.exe"
|
||||
#ping is for timeout
|
||||
ping -n 10 127.0.0.1>NUL && taskkill /im tinyinst_simple.exe /F
|
||||
>nul 2>nul dir /a-d "corpus_discovered\*" && (echo Files exist) || (exit /b 1337)
|
||||
'''
|
||||
dependencies = [ "harness", "fuzzer" ]
|
@ -1,3 +1,11 @@
|
||||
# Run Instruction
|
||||
# Tinyinst example
|
||||
This is a fuzzer example to show how libafl_tinyinst works
|
||||
|
||||
## How to build
|
||||
1. Build the harness with `cl test\test.cpp -o test.exe`
|
||||
2. Build the fuzzer with `cargo build --release`. The fuzzer is `target\release\tinyinst_simple.exe`
|
||||
|
||||
## Run with cargo-make
|
||||
Or, you can simple run it using cargo-make
|
||||
1. Open up developer powershell so that you have access to cl (Windows Default Compiler)
|
||||
2. Run `cargo make run` to run the fuzzer
|
@ -1,8 +1,13 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
use libafl::bolts::shmem::UnixShMemProvider;
|
||||
#[cfg(windows)]
|
||||
use libafl::bolts::shmem::Win32ShMemProvider;
|
||||
use libafl::{
|
||||
bolts::{
|
||||
rands::{RandomSeed, StdRand},
|
||||
shmem::ShMemProvider,
|
||||
tuples::tuple_list,
|
||||
},
|
||||
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus, Testcase},
|
||||
@ -17,17 +22,30 @@ use libafl::{
|
||||
state::StdState,
|
||||
Fuzzer, StdFuzzer,
|
||||
};
|
||||
use libafl_tinyinst::executor::TinyInstExecutor;
|
||||
use libafl_tinyinst::executor::TinyInstExecutorBuilder;
|
||||
static mut COVERAGE: Vec<u64> = vec![];
|
||||
|
||||
#[cfg(not(any(target_vendor = "apple", windows)))]
|
||||
fn main() {}
|
||||
|
||||
#[cfg(any(target_vendor = "apple", windows))]
|
||||
fn main() {
|
||||
// Tinyinst things
|
||||
let tinyinst_args = vec!["-instrument_module".to_string(), "test.exe".to_string()];
|
||||
|
||||
let args = vec![".\\test\\test.exe".to_string(), "@@".to_string()];
|
||||
// use shmem to pass testcases
|
||||
let args = vec!["test.exe".to_string(), "-m".to_string(), "@@".to_string()];
|
||||
|
||||
// use file to pass testcases
|
||||
// let args = vec!["test.exe".to_string(), "-f".to_string(), "@@".to_string()];
|
||||
|
||||
let observer = unsafe { ListObserver::new("cov", &mut COVERAGE) };
|
||||
let mut feedback = ListFeedback::with_observer(&observer);
|
||||
#[cfg(windows)]
|
||||
let mut shmem_provider = Win32ShMemProvider::new().unwrap();
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
let mut shmem_provider = UnixShMemProvider::new().unwrap();
|
||||
|
||||
let input = BytesInput::new(b"bad".to_vec());
|
||||
let rand = StdRand::new();
|
||||
@ -46,13 +64,15 @@ fn main() {
|
||||
|
||||
let mut mgr = SimpleEventManager::new(monitor);
|
||||
let mut executor = unsafe {
|
||||
TinyInstExecutor::new(
|
||||
&mut COVERAGE,
|
||||
tinyinst_args,
|
||||
args,
|
||||
5000,
|
||||
tuple_list!(observer),
|
||||
)
|
||||
TinyInstExecutorBuilder::new()
|
||||
.tinyinst_args(tinyinst_args)
|
||||
.program_args(args)
|
||||
.use_shmem()
|
||||
.persistent("test.exe".to_string(), "fuzz".to_string(), 1, 10000)
|
||||
.timeout(std::time::Duration::new(5, 0))
|
||||
.shmem_provider(&mut shmem_provider)
|
||||
.build(&mut COVERAGE, tuple_list!(observer))
|
||||
.unwrap()
|
||||
};
|
||||
let mutator = StdScheduledMutator::new(havoc_mutations());
|
||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||
|
@ -1,36 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void pass1(char *buf, int buf_size) {
|
||||
char target[0x10];
|
||||
if (buf[0] == 'b') {
|
||||
if (buf[1] == 'a') {
|
||||
if (buf[2] == 'd') {
|
||||
if (buf[3] == '1') {
|
||||
if (buf[4] == '2') {
|
||||
printf("You got me\n");
|
||||
memcpy(target, buf, 0x1000000);
|
||||
printf("GG\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *fp;
|
||||
char buf[0x1000];
|
||||
if (argc == 2) {
|
||||
fp = fopen(argv[1], "r");
|
||||
if (fp == NULL) {
|
||||
printf("File not found\n");
|
||||
printf("Received filename %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
fscanf(fp, "%s", buf);
|
||||
|
||||
pass1(buf, sizeof(buf));
|
||||
|
||||
} else {
|
||||
printf("there is nothing\n");
|
||||
}
|
||||
}
|
163
fuzzers/tinyinst_simple/test/test.cpp
Normal file
163
fuzzers/tinyinst_simple/test/test.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright 2020 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// shared memory stuff
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#define MAX_SAMPLE_SIZE 1000000
|
||||
#define SHM_SIZE (4 + MAX_SAMPLE_SIZE)
|
||||
unsigned char *shm_data;
|
||||
|
||||
bool use_shared_memory;
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
|
||||
|
||||
int setup_shmem(const char *name) {
|
||||
HANDLE map_file;
|
||||
|
||||
map_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, // read/write access
|
||||
FALSE, // do not inherit the name
|
||||
name); // name of mapping object
|
||||
|
||||
if (map_file == NULL) {
|
||||
printf("Error accessing shared memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
shm_data = (unsigned char *)MapViewOfFile(
|
||||
map_file, // handle to map object
|
||||
FILE_MAP_ALL_ACCESS, // read/write permission
|
||||
0, 0, SHM_SIZE);
|
||||
|
||||
if (shm_data == NULL) {
|
||||
printf("Error accessing shared memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int setup_shmem(const char *name) {
|
||||
int fd;
|
||||
|
||||
// get shared memory file descriptor (NOT a file)
|
||||
fd = shm_open(name, O_RDONLY, S_IRUSR | S_IWUSR);
|
||||
if (fd == -1) {
|
||||
printf("Error in shm_open\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// map shared memory to process address space
|
||||
shm_data =
|
||||
(unsigned char *)mmap(NULL, SHM_SIZE, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (shm_data == MAP_FAILED) {
|
||||
printf("Error in mmap\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// used to force a crash
|
||||
char *crash = NULL;
|
||||
|
||||
// ensure we can find the target
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
|
||||
#define FUZZ_TARGET_MODIFIERS __declspec(dllexport)
|
||||
#else
|
||||
#define FUZZ_TARGET_MODIFIERS __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
// actual target function
|
||||
|
||||
void FUZZ_TARGET_MODIFIERS fuzz(char *name) {
|
||||
char *sample_bytes = NULL;
|
||||
uint32_t sample_size = 0;
|
||||
|
||||
// read the sample either from file or
|
||||
// shared memory
|
||||
if (use_shared_memory) {
|
||||
sample_size = *(uint32_t *)(shm_data);
|
||||
if (sample_size > MAX_SAMPLE_SIZE) sample_size = MAX_SAMPLE_SIZE;
|
||||
sample_bytes = (char *)malloc(sample_size);
|
||||
memcpy(sample_bytes, shm_data + sizeof(uint32_t), sample_size);
|
||||
} else {
|
||||
FILE *fp = fopen(name, "rb");
|
||||
if (!fp) {
|
||||
printf("Error opening %s a\n", name);
|
||||
return;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
sample_size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
sample_bytes = (char *)malloc(sample_size);
|
||||
fread(sample_bytes, 1, sample_size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
// printf("sample_bytes: %s", sample_bytes);
|
||||
if (sample_size >= 4) {
|
||||
// check if the sample spells "test"
|
||||
if (*(uint32_t *)(sample_bytes) == 0x74736574) {
|
||||
// if so, crash
|
||||
crash[0] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sample_bytes) free(sample_bytes);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s <-f|-m> <file or shared memory name>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[1], "-m")) {
|
||||
use_shared_memory = true;
|
||||
} else if (!strcmp(argv[1], "-f")) {
|
||||
use_shared_memory = false;
|
||||
} else {
|
||||
printf("Usage: %s <-f|-m> <file or shared memory name>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// map shared memory here as we don't want to do it
|
||||
// for every operation
|
||||
if (use_shared_memory) {
|
||||
if (!setup_shmem(argv[2])) { printf("Error mapping shared memory\n"); }
|
||||
}
|
||||
|
||||
fuzz(argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
@ -254,7 +254,7 @@ where
|
||||
phantom: _,
|
||||
} => {
|
||||
// TODO: The monitor buffer should be added on client add.
|
||||
let client = &mut monitor.client_stats_mut()[0];
|
||||
let client = monitor.client_stats_mut_for(0);
|
||||
client.update_executions(*executions as u64, *time);
|
||||
client.update_introspection_monitor((**introspection_monitor).clone());
|
||||
monitor.display(event.name().to_string(), 0);
|
||||
|
@ -537,7 +537,7 @@ where
|
||||
.field("target", &self.target)
|
||||
.field("args", &self.args)
|
||||
.field("input_file", &self.input_file)
|
||||
.field("use_shmem_testcase", &self.uses_shmem_testcase)
|
||||
.field("uses_shmem_testcase", &self.uses_shmem_testcase)
|
||||
.field("forkserver", &self.forkserver)
|
||||
.field("observers", &self.observers)
|
||||
.field("map", &self.map)
|
||||
|
@ -17,7 +17,7 @@ libafl = { path = "../libafl", version = "0.8.0", features = [
|
||||
"std",
|
||||
"libafl_derive",
|
||||
] }
|
||||
tinyinst-rs = { git = "https://github.com/elbiazo/tinyinst-rs" }
|
||||
tinyinst = { git = "https://github.com/AFLplusplus/tinyinst-rs" }
|
||||
# tinyinst-rs = { path = "../../tinyinst-rs" }
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -1,3 +1,4 @@
|
||||
# Requirements
|
||||
- you need `Visual Studio 17 2022`, though it's not tested, it should work on older versions.
|
||||
- you need `cxxbridge-cmd` to generate bridge files between Rust and c++, you can install this via `cargo install cxxbridge-cmd`
|
||||
- `Visual Studio 17 2022`. It's not tested, it *should* work on older versions too.
|
||||
- `cxxbridge-cmd` to generate bridge files between Rust and c++, you can install this with `cargo install cxxbridge-cmd`.
|
||||
- `cmake` is needed to build tinyinst.
|
@ -1,27 +1,38 @@
|
||||
use core::marker::PhantomData;
|
||||
use std::time::Duration;
|
||||
|
||||
use libafl::{
|
||||
bolts::fs::{InputFile, INPUTFILE_STD},
|
||||
bolts::{
|
||||
fs::{InputFile, INPUTFILE_STD},
|
||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||
AsMutSlice, AsSlice,
|
||||
},
|
||||
executors::{Executor, ExitKind, HasObservers},
|
||||
inputs::{HasTargetBytes, UsesInput},
|
||||
observers::{ObserversTuple, UsesObservers},
|
||||
prelude::AsSlice,
|
||||
state::{State, UsesState},
|
||||
Error,
|
||||
};
|
||||
use tinyinst_rs::tinyinst::{litecov::RunResult, TinyInst};
|
||||
use tinyinst::tinyinst::{litecov::RunResult, TinyInst};
|
||||
|
||||
pub struct TinyInstExecutor<'a, S, OT> {
|
||||
/// Tinyinst executor
|
||||
pub struct TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
tinyinst: TinyInst,
|
||||
coverage: &'a mut Vec<u64>,
|
||||
timeout: u32,
|
||||
timeout: Duration,
|
||||
observers: OT,
|
||||
phantom: PhantomData<S>,
|
||||
cur_input: InputFile,
|
||||
use_stdin: bool,
|
||||
map: Option<<SP as ShMemProvider>::ShMem>,
|
||||
}
|
||||
|
||||
impl<'a, S, OT> std::fmt::Debug for TinyInstExecutor<'a, S, OT> {
|
||||
impl<'a, S, SP, OT> std::fmt::Debug for TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("TinyInstExecutor")
|
||||
.field("timeout", &self.timeout)
|
||||
@ -29,11 +40,12 @@ impl<'a, S, OT> std::fmt::Debug for TinyInstExecutor<'a, S, OT> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, EM, S, Z, OT> Executor<EM, Z> for TinyInstExecutor<'a, S, OT>
|
||||
impl<'a, EM, S, SP, OT, Z> Executor<EM, Z> for TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
EM: UsesState<State = S>,
|
||||
S: UsesInput,
|
||||
S::Input: HasTargetBytes,
|
||||
SP: ShMemProvider,
|
||||
Z: UsesState<State = S>,
|
||||
{
|
||||
#[inline]
|
||||
@ -44,9 +56,23 @@ where
|
||||
_mgr: &mut EM,
|
||||
input: &Self::Input,
|
||||
) -> Result<ExitKind, Error> {
|
||||
if !self.use_stdin {
|
||||
match &self.map {
|
||||
Some(_) => {
|
||||
// use shmem to pass testcase
|
||||
let shmem = unsafe { self.map.as_mut().unwrap_unchecked() };
|
||||
let target_bytes = input.target_bytes();
|
||||
let size = target_bytes.as_slice().len();
|
||||
let size_in_bytes = size.to_ne_bytes();
|
||||
// The first four bytes tells the size of the shmem.
|
||||
shmem.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE]
|
||||
.copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]);
|
||||
shmem.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
|
||||
.copy_from_slice(target_bytes.as_slice());
|
||||
}
|
||||
None => {
|
||||
self.cur_input.write_buf(input.target_bytes().as_slice())?;
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
let mut status = RunResult::OK;
|
||||
@ -66,53 +92,211 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S, OT> TinyInstExecutor<'a, S, OT>
|
||||
where
|
||||
OT: ObserversTuple<S>,
|
||||
S: UsesInput,
|
||||
{
|
||||
/// # Safety
|
||||
pub unsafe fn new(
|
||||
coverage: &'a mut Vec<u64>,
|
||||
/// Builder for `TinyInstExecutor`
|
||||
#[derive(Debug)]
|
||||
pub struct TinyInstExecutorBuilder<'a, SP> {
|
||||
tinyinst_args: Vec<String>,
|
||||
program_args: Vec<String>,
|
||||
timeout: u32,
|
||||
observers: OT,
|
||||
) -> Self {
|
||||
let mut use_stdin = true;
|
||||
timeout: Duration,
|
||||
shmem_provider: Option<&'a mut SP>,
|
||||
}
|
||||
|
||||
let program_args = program_args
|
||||
const MAX_FILE: usize = 1024 * 1024;
|
||||
const SHMEM_FUZZ_HDR_SIZE: usize = 4;
|
||||
|
||||
impl<'a> Default for TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
||||
/// Constructor
|
||||
#[must_use]
|
||||
pub fn new() -> TinyInstExecutorBuilder<'a, StdShMemProvider> {
|
||||
Self {
|
||||
tinyinst_args: vec![],
|
||||
program_args: vec![],
|
||||
timeout: Duration::new(3, 0),
|
||||
shmem_provider: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Argument for tinyinst instrumentation
|
||||
#[must_use]
|
||||
pub fn tinyinst_arg(mut self, arg: String) -> Self {
|
||||
self.tinyinst_args.push(arg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Arguments for tinyinst instrumentation
|
||||
#[must_use]
|
||||
pub fn tinyinst_args(mut self, args: Vec<String>) -> Self {
|
||||
for arg in args {
|
||||
self.tinyinst_args.push(arg);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// The module to instrument.
|
||||
#[must_use]
|
||||
pub fn instrument_module(mut self, module: Vec<String>) -> Self {
|
||||
for modname in module {
|
||||
self.tinyinst_args.push("-instrument_module".to_string());
|
||||
self.tinyinst_args.push(modname);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Use shmem
|
||||
#[must_use]
|
||||
pub fn use_shmem(mut self) -> Self {
|
||||
self.tinyinst_args.push("-delivery".to_string());
|
||||
self.tinyinst_args.push("shmem".to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Persistent mode
|
||||
#[must_use]
|
||||
pub fn persistent(
|
||||
mut self,
|
||||
target_module: String,
|
||||
target_method: String,
|
||||
nargs: usize,
|
||||
iterations: usize,
|
||||
) -> Self {
|
||||
self.tinyinst_args.push("-target_module".to_string());
|
||||
self.tinyinst_args.push(target_module);
|
||||
|
||||
self.tinyinst_args.push("-target_method".to_string());
|
||||
self.tinyinst_args.push(target_method);
|
||||
|
||||
self.tinyinst_args.push("-nargs".to_string());
|
||||
self.tinyinst_args.push(nargs.to_string());
|
||||
|
||||
self.tinyinst_args.push("-iterations".to_string());
|
||||
self.tinyinst_args.push(iterations.to_string());
|
||||
|
||||
self.tinyinst_args.push("-persist".to_string());
|
||||
self.tinyinst_args.push("-loop".to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Program arg
|
||||
#[must_use]
|
||||
pub fn program_arg(mut self, arg: String) -> Self {
|
||||
self.program_args.push(arg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Program args
|
||||
#[must_use]
|
||||
pub fn program_args(mut self, args: Vec<String>) -> Self {
|
||||
for arg in args {
|
||||
self.program_args.push(arg);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set timeout
|
||||
#[must_use]
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
/// Use this to enable shmem testcase passing.
|
||||
#[must_use]
|
||||
pub fn shmem_provider<SP: ShMemProvider>(
|
||||
self,
|
||||
shmem_provider: &'a mut SP,
|
||||
) -> TinyInstExecutorBuilder<'a, SP> {
|
||||
TinyInstExecutorBuilder {
|
||||
tinyinst_args: self.tinyinst_args,
|
||||
program_args: self.program_args,
|
||||
timeout: self.timeout,
|
||||
shmem_provider: Some(shmem_provider),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, SP> TinyInstExecutorBuilder<'a, SP>
|
||||
where
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
/// Build tinyinst executor
|
||||
pub fn build<OT, S>(
|
||||
&mut self,
|
||||
coverage: &'a mut Vec<u64>,
|
||||
observers: OT,
|
||||
) -> Result<TinyInstExecutor<'a, S, SP, OT>, Error> {
|
||||
let (map, shmem_id) = match &mut self.shmem_provider {
|
||||
Some(provider) => {
|
||||
// setup shared memory
|
||||
let mut shmem = provider.new_shmem(MAX_FILE + SHMEM_FUZZ_HDR_SIZE)?;
|
||||
let shmem_id = shmem.id();
|
||||
// println!("{:#?}", shmem.id());
|
||||
// shmem.write_to_env("__TINY_SHM_FUZZ_ID")?;
|
||||
|
||||
let size_in_bytes = (MAX_FILE + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes();
|
||||
shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]);
|
||||
|
||||
(Some(shmem), Some(shmem_id))
|
||||
}
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
let mut has_input = false;
|
||||
let program_args: Vec<String> = self
|
||||
.program_args
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|arg| {
|
||||
if arg == "@@" {
|
||||
println!("Not using stdin");
|
||||
use_stdin = false;
|
||||
INPUTFILE_STD.to_string()
|
||||
has_input = true;
|
||||
match shmem_id {
|
||||
Some(shmem_name) => shmem_name.to_string(),
|
||||
None => INPUTFILE_STD.to_string(),
|
||||
}
|
||||
} else {
|
||||
arg
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cur_input = InputFile::create(INPUTFILE_STD).expect("Unable to create cur_file");
|
||||
println!("post init");
|
||||
let tinyinst = TinyInst::new(tinyinst_args, program_args, timeout);
|
||||
if !has_input {
|
||||
return Err(Error::unknown(
|
||||
"No input file or shmem provided".to_string(),
|
||||
));
|
||||
}
|
||||
println!("tinyinst args: {:#?}", &self.tinyinst_args);
|
||||
|
||||
Self {
|
||||
let cur_input = InputFile::create(INPUTFILE_STD).expect("Unable to create cur_file");
|
||||
|
||||
let tinyinst = unsafe {
|
||||
TinyInst::new(
|
||||
&self.tinyinst_args,
|
||||
&program_args,
|
||||
self.timeout.as_millis() as u32,
|
||||
)
|
||||
};
|
||||
|
||||
Ok(TinyInstExecutor {
|
||||
tinyinst,
|
||||
coverage,
|
||||
timeout,
|
||||
timeout: self.timeout,
|
||||
observers,
|
||||
phantom: PhantomData,
|
||||
cur_input,
|
||||
use_stdin,
|
||||
}
|
||||
map,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S, OT> HasObservers for TinyInstExecutor<'a, S, OT>
|
||||
impl<'a, S, SP, OT> HasObservers for TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
S: State,
|
||||
SP: ShMemProvider,
|
||||
OT: ObserversTuple<S>,
|
||||
{
|
||||
fn observers(&self) -> &OT {
|
||||
@ -123,16 +307,18 @@ where
|
||||
&mut self.observers
|
||||
}
|
||||
}
|
||||
impl<'a, S, OT> UsesState for TinyInstExecutor<'a, S, OT>
|
||||
impl<'a, S, SP, OT> UsesState for TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
S: UsesInput,
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
type State = S;
|
||||
}
|
||||
impl<'a, S, OT> UsesObservers for TinyInstExecutor<'a, S, OT>
|
||||
impl<'a, S, SP, OT> UsesObservers for TinyInstExecutor<'a, S, SP, OT>
|
||||
where
|
||||
OT: ObserversTuple<S>,
|
||||
S: UsesInput,
|
||||
SP: ShMemProvider,
|
||||
{
|
||||
type Observers = OT;
|
||||
}
|
||||
|
@ -1 +1,69 @@
|
||||
/*!
|
||||
The tinyinst module for `LibAFL`.
|
||||
*/
|
||||
|
||||
#![warn(clippy::cargo)]
|
||||
#![deny(clippy::cargo_common_metadata)]
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
#![deny(clippy::all)]
|
||||
#![deny(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::unreadable_literal,
|
||||
clippy::type_repetition_in_bounds,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::used_underscore_binding,
|
||||
clippy::ptr_as_ptr,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::missing_docs_in_private_items,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
#![cfg_attr(not(test), warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
//trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
unused_qualifications,
|
||||
//unused_results
|
||||
))]
|
||||
#![cfg_attr(test, deny(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
//trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
unused_qualifications,
|
||||
unused_must_use,
|
||||
missing_docs,
|
||||
//unused_results
|
||||
))]
|
||||
#![cfg_attr(
|
||||
test,
|
||||
deny(
|
||||
bad_style,
|
||||
dead_code,
|
||||
improper_ctypes,
|
||||
non_shorthand_field_patterns,
|
||||
no_mangle_generic_items,
|
||||
overflowing_literals,
|
||||
path_statements,
|
||||
patterns_in_fns_without_body,
|
||||
private_in_public,
|
||||
unconditional_recursion,
|
||||
unused,
|
||||
unused_allocation,
|
||||
unused_comparisons,
|
||||
unused_parens,
|
||||
while_true
|
||||
)
|
||||
)]
|
||||
// Till they fix this buggy lint in clippy
|
||||
#![allow(clippy::borrow_as_ptr)]
|
||||
#![allow(clippy::borrow_deref_ref)]
|
||||
|
||||
/// Tinyinst executor
|
||||
pub mod executor;
|
||||
|
Loading…
x
Reference in New Issue
Block a user