qemufuzzer skeleton
This commit is contained in:
parent
4cccdf1378
commit
8272e640be
23
fuzzers/qemufuzzer/Cargo.toml
Normal file
23
fuzzers/qemufuzzer/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[package]
|
||||||
|
name = "qemufuzzer"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = []
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
opt-level = 3
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
afl = { path = "../../afl/" }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["staticlib", "cdylib"]
|
99
fuzzers/qemufuzzer/src/lib.rs
Normal file
99
fuzzers/qemufuzzer/src/lib.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use afl::corpus::InMemoryCorpus;
|
||||||
|
use afl::engines::Engine;
|
||||||
|
use afl::engines::Fuzzer;
|
||||||
|
use afl::engines::State;
|
||||||
|
use afl::engines::StdFuzzer;
|
||||||
|
use afl::events::{SimpleStats, LlmpEventManager};
|
||||||
|
use afl::executors::inmemory::InMemoryExecutor;
|
||||||
|
use afl::executors::{Executor, ExitKind};
|
||||||
|
use afl::feedbacks::MaxMapFeedback;
|
||||||
|
use afl::generators::RandPrintablesGenerator;
|
||||||
|
use afl::mutators::scheduled::HavocBytesMutator;
|
||||||
|
use afl::mutators::HasMaxSize;
|
||||||
|
use afl::observers::StdMapObserver;
|
||||||
|
use afl::stages::mutational::StdMutationalStage;
|
||||||
|
use afl::tuples::tuple_list;
|
||||||
|
use afl::utils::StdRand;
|
||||||
|
|
||||||
|
use core::cmp::min;
|
||||||
|
|
||||||
|
mod regs;
|
||||||
|
use regs::*;
|
||||||
|
|
||||||
|
const FUZZ_MAP_SIZE: usize = 1048576;
|
||||||
|
|
||||||
|
type TargetULong = u64;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn fuzz_run_target(regs: *const x86_64_regs);
|
||||||
|
fn fuzz_write_mem(addr: TargetULong, buf: *const u8, size: usize);
|
||||||
|
// fn fuzz_read_mem(addr: TargetULong, buf: *const u8, size: usize);
|
||||||
|
|
||||||
|
static fuzz_start_regs: x86_64_regs;
|
||||||
|
static mut fuzz_hitcounts_map: [u8; FUZZ_MAP_SIZE];
|
||||||
|
static mut fuzz_edges_id: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
|
||||||
|
unsafe {
|
||||||
|
let mut regs = fuzz_start_regs.clone();
|
||||||
|
let len = min(buf.len(), 4096);
|
||||||
|
regs.rsi = len as u64;
|
||||||
|
fuzz_write_mem(regs.rdi, buf.as_ptr(), len);
|
||||||
|
fuzz_run_target(®s);
|
||||||
|
}
|
||||||
|
ExitKind::Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAME_COV_MAP: &str = "cov_map";
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn fuzz_main_loop() {
|
||||||
|
let mut rand = StdRand::new(0);
|
||||||
|
|
||||||
|
let mut corpus = InMemoryCorpus::new();
|
||||||
|
let mut generator = RandPrintablesGenerator::new(32);
|
||||||
|
|
||||||
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
let mut mgr = LlmpEventManager::new_on_port(1337, stats).unwrap();
|
||||||
|
if mgr.is_broker() {
|
||||||
|
println!("Doing broker things.");
|
||||||
|
mgr.broker_loop().unwrap();
|
||||||
|
}
|
||||||
|
println!("We're a client, let's fuzz :)");
|
||||||
|
|
||||||
|
let edges_observer = StdMapObserver::new_from_ptr(&NAME_COV_MAP, unsafe { fuzz_hitcounts_map.as_mut_ptr() }, unsafe { fuzz_edges_id });
|
||||||
|
let edges_feedback = MaxMapFeedback::new_with_observer(&NAME_COV_MAP, &edges_observer);
|
||||||
|
|
||||||
|
let executor = InMemoryExecutor::new("QEMUFuzzer", harness, tuple_list!(edges_observer));
|
||||||
|
let mut state = State::new(tuple_list!(edges_feedback));
|
||||||
|
|
||||||
|
let mut engine = Engine::new(executor);
|
||||||
|
|
||||||
|
state
|
||||||
|
.generate_initial_inputs(
|
||||||
|
&mut rand,
|
||||||
|
&mut corpus,
|
||||||
|
&mut generator,
|
||||||
|
&mut engine,
|
||||||
|
&mut mgr,
|
||||||
|
4,
|
||||||
|
)
|
||||||
|
.expect("Failed to load initial inputs");
|
||||||
|
|
||||||
|
let mut mutator = HavocBytesMutator::new_default();
|
||||||
|
mutator.set_max_size(4096);
|
||||||
|
|
||||||
|
let stage = StdMutationalStage::new(mutator);
|
||||||
|
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
|
||||||
|
|
||||||
|
fuzzer
|
||||||
|
.fuzz_loop(&mut rand, &mut state, &mut corpus, &mut engine, &mut mgr)
|
||||||
|
.expect("Fuzzer fatal error");
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
println!("OK");
|
||||||
|
}
|
107
fuzzers/qemufuzzer/src/regs.rs
Normal file
107
fuzzers/qemufuzzer/src/regs.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* Generated by hand by Fioraldi bindgen */
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct x86_regs {
|
||||||
|
pub eax: u32,
|
||||||
|
pub ebx: u32,
|
||||||
|
pub ecx: u32,
|
||||||
|
pub edx: u32,
|
||||||
|
pub edi: u32,
|
||||||
|
pub esi: u32,
|
||||||
|
pub ebp: u32,
|
||||||
|
pub eip: u32,
|
||||||
|
pub esp: u32,
|
||||||
|
pub eflags: u32,
|
||||||
|
pub xmm_regs: [[u8; 8usize]; 16usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct x86_64_regs {
|
||||||
|
pub rax: u64,
|
||||||
|
pub rbx: u64,
|
||||||
|
pub rcx: u64,
|
||||||
|
pub rdx: u64,
|
||||||
|
pub rdi: u64,
|
||||||
|
pub rsi: u64,
|
||||||
|
pub rbp: u64,
|
||||||
|
pub r8: u64,
|
||||||
|
pub r9: u64,
|
||||||
|
pub r10: u64,
|
||||||
|
pub r11: u64,
|
||||||
|
pub r12: u64,
|
||||||
|
pub r13: u64,
|
||||||
|
pub r14: u64,
|
||||||
|
pub r15: u64,
|
||||||
|
pub rip: u64,
|
||||||
|
pub rsp: u64,
|
||||||
|
pub rflags: u64,
|
||||||
|
pub zmm_regs: [[u8; 32usize]; 64usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct arm_regs {
|
||||||
|
pub r0: u32,
|
||||||
|
pub r1: u32,
|
||||||
|
pub r2: u32,
|
||||||
|
pub r3: u32,
|
||||||
|
pub r4: u32,
|
||||||
|
pub r5: u32,
|
||||||
|
pub r6: u32,
|
||||||
|
pub r7: u32,
|
||||||
|
pub r8: u32,
|
||||||
|
pub r9: u32,
|
||||||
|
pub r10: u32,
|
||||||
|
pub r11: u32,
|
||||||
|
pub r12: u32,
|
||||||
|
pub r13: u32,
|
||||||
|
pub r14: u32,
|
||||||
|
pub r15: u32,
|
||||||
|
pub cpsr: u32,
|
||||||
|
pub vfp_zregs: [[u8; 32usize]; 16usize],
|
||||||
|
pub vfp_xregs: [u32; 16usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct arm64_regs {
|
||||||
|
pub x0: u64,
|
||||||
|
pub x1: u64,
|
||||||
|
pub x2: u64,
|
||||||
|
pub x3: u64,
|
||||||
|
pub x4: u64,
|
||||||
|
pub x5: u64,
|
||||||
|
pub x6: u64,
|
||||||
|
pub x7: u64,
|
||||||
|
pub x8: u64,
|
||||||
|
pub x9: u64,
|
||||||
|
pub x10: u64,
|
||||||
|
pub x11: u64,
|
||||||
|
pub x12: u64,
|
||||||
|
pub x13: u64,
|
||||||
|
pub x14: u64,
|
||||||
|
pub x15: u64,
|
||||||
|
pub x16: u64,
|
||||||
|
pub x17: u64,
|
||||||
|
pub x18: u64,
|
||||||
|
pub x19: u64,
|
||||||
|
pub x20: u64,
|
||||||
|
pub x21: u64,
|
||||||
|
pub x22: u64,
|
||||||
|
pub x23: u64,
|
||||||
|
pub x24: u64,
|
||||||
|
pub x25: u64,
|
||||||
|
pub x26: u64,
|
||||||
|
pub x27: u64,
|
||||||
|
pub x28: u64,
|
||||||
|
pub x29: u64,
|
||||||
|
pub x30: u64,
|
||||||
|
pub x31: u64,
|
||||||
|
pub pc: u64,
|
||||||
|
pub cpsr: u32,
|
||||||
|
pub vfp_zregs: [[u8; 32usize]; 256usize],
|
||||||
|
pub vfp_pregs: [[u8; 17usize]; 32usize],
|
||||||
|
pub vfp_xregs: [u32; 16usize],
|
||||||
|
}
|
11
fuzzers/qemufuzzer/test.sh
Executable file
11
fuzzers/qemufuzzer/test.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
cd qemu
|
||||||
|
git pull
|
||||||
|
|
||||||
|
./build_qemu_fuzz.sh ../target/release/libqemufuzzer.a
|
||||||
|
|
||||||
|
cp build/qemu-x86_64 ../qemu_fuzz
|
||||||
|
|
43
fuzzers/qemufuzzer/test/test.c
Executable file
43
fuzzers/qemufuzzer/test/test.c
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int target_func(const uint8_t *buf, size_t size) {
|
||||||
|
|
||||||
|
/*printf("BUF (%ld): ", size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
printf("%02X", buf[i]);
|
||||||
|
}
|
||||||
|
printf("\n");*/
|
||||||
|
|
||||||
|
if (size == 0) return 0;
|
||||||
|
|
||||||
|
switch (buf[0]) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (buf[1] == 0x44) {
|
||||||
|
//__builtin_trap();
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 0xff:
|
||||||
|
if (buf[2] == 0xff) {
|
||||||
|
if (buf[1] == 0x44) {
|
||||||
|
//*(char *)(0xdeadbeef) = 1;
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
|
return target_func(Data, Size);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user