mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-21 13:51:18 +00:00
fixed rust example
This commit is contained in:
@ -50,4 +50,5 @@ harness-debug: harness-debug.o
|
|||||||
$(MAKE) -C ..
|
$(MAKE) -C ..
|
||||||
|
|
||||||
fuzz: ../target harness
|
fuzz: ../target harness
|
||||||
SKIP_BINCHECK=1 ../../../../afl-fuzz -i ../sample_inputs -o ./output -- ./harness @@
|
rm -rf ./output
|
||||||
|
SKIP_BINCHECK=1 ../../../../afl-fuzz -s 1 -i ../sample_inputs -o ./output -- ./harness @@
|
||||||
|
@ -4,10 +4,12 @@ version = "0.1.0"
|
|||||||
authors = ["Dominik Maier <domenukk@gmail.com>"]
|
authors = ["Dominik Maier <domenukk@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
opt-level = 3
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
unicornafl = { path = "../../../unicornafl/bindings/rust/", version="1.0.0" }
|
unicornafl = { path = "../../../unicornafl/bindings/rust/", version="1.0.0" }
|
||||||
capstone="0.6.0"
|
capstone="0.6.0"
|
||||||
libc="0.2.66"
|
libc="0.2.66"
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
17
unicorn_mode/samples/speedtest/rust/Makefile
Normal file
17
unicorn_mode/samples/speedtest/rust/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
all: fuzz
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cargo clean
|
||||||
|
|
||||||
|
./target/release/unicornafl_harness: ./src/main.rs
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
./target/debug/unicornafl_harness: ./src/main.rs
|
||||||
|
cargo build
|
||||||
|
|
||||||
|
../target:
|
||||||
|
$(MAKE) -c ..
|
||||||
|
|
||||||
|
fuzz: ../target ./target/release/unicornafl_harness
|
||||||
|
rm -rf ./output
|
||||||
|
SKIP_BINCHECK=1 ../../../../afl-fuzz -s 1 -i ../sample_inputs -o ./output -- ./target/release/unicornafl_harness @@
|
@ -7,6 +7,7 @@ use std::{
|
|||||||
fs::File,
|
fs::File,
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
process::abort,
|
process::abort,
|
||||||
|
str,
|
||||||
};
|
};
|
||||||
|
|
||||||
use unicornafl::{
|
use unicornafl::{
|
||||||
@ -45,19 +46,24 @@ fn read_file(filename: &str) -> Result<Vec<u8>, io::Error> {
|
|||||||
/// Our location parser
|
/// Our location parser
|
||||||
fn parse_locs(loc_name: &str) -> Result<Vec<u64>, io::Error> {
|
fn parse_locs(loc_name: &str) -> Result<Vec<u64>, io::Error> {
|
||||||
let contents = &read_file(&format!("../target.offsets.{}", loc_name))?;
|
let contents = &read_file(&format!("../target.offsets.{}", loc_name))?;
|
||||||
|
//println!("Read: {:?}", contents);
|
||||||
Ok(str_from_u8_unchecked(&contents)
|
Ok(str_from_u8_unchecked(&contents)
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.flat_map(|x| u64::from_str_radix(x, 16))
|
.map(|x| {
|
||||||
|
//println!("Trying to convert {}", &x[2..]);
|
||||||
|
let result = u64::from_str_radix(&x[2..], 16);
|
||||||
|
result.unwrap()
|
||||||
|
})
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
// find null terminated string in vec
|
// find null terminated string in vec
|
||||||
pub unsafe fn str_from_u8_unchecked(utf8_src: &[u8]) -> &str {
|
pub fn str_from_u8_unchecked(utf8_src: &[u8]) -> &str {
|
||||||
let nul_range_end = utf8_src
|
let nul_range_end = utf8_src
|
||||||
.iter()
|
.iter()
|
||||||
.position(|&c| c == b'\0')
|
.position(|&c| c == b'\0')
|
||||||
.unwrap_or(utf8_src.len());
|
.unwrap_or(utf8_src.len());
|
||||||
::std::str::from_utf8_unchecked(&utf8_src[0..nul_range_end])
|
unsafe { str::from_utf8_unchecked(&utf8_src[0..nul_range_end]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align(size: u64) -> u64 {
|
fn align(size: u64) -> u64 {
|
||||||
@ -81,26 +87,23 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fuzz(input_file: &str) -> Result<(), uc_error> {
|
fn fuzz(input_file: &str) -> Result<(), uc_error> {
|
||||||
let unicorn = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
|
let mut unicorn = Unicorn::new(Arch::X86, Mode::MODE_64, 0)?;
|
||||||
let mut uc = unicorn.borrow();
|
let mut uc: UnicornHandle<'_, _> = unicorn.borrow();
|
||||||
|
|
||||||
let binary = read_file(BINARY).expect(&format!("Could not read modem image: {}", BINARY));
|
let binary = read_file(BINARY).expect(&format!("Could not read modem image: {}", BINARY));
|
||||||
let aligned_binary_size = align(binary.len() as u64);
|
let _aligned_binary_size = align(binary.len() as u64);
|
||||||
// Apply constraints to the mutated input
|
// Apply constraints to the mutated input
|
||||||
if binary.len() as u64 > CODE_SIZE_MAX {
|
if binary.len() as u64 > CODE_SIZE_MAX {
|
||||||
println!("Binary code is too large (> {} bytes)", CODE_SIZE_MAX);
|
println!("Binary code is too large (> {} bytes)", CODE_SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the binary to its place in mem
|
// Write the binary to its place in mem
|
||||||
uc.mem_map(
|
uc.mem_map(BASE_ADDRESS, CODE_SIZE_MAX as usize, Permission::ALL)?;
|
||||||
BASE_ADDRESS,
|
uc.mem_write(BASE_ADDRESS, &binary)?;
|
||||||
CODE_SIZE_MAX as usize,
|
|
||||||
Permission::READ | Permission::WRITE,
|
|
||||||
)?;
|
|
||||||
uc.mem_write(BASE_ADDRESS, &binary);
|
|
||||||
|
|
||||||
// Set the program counter to the start of the code
|
// Set the program counter to the start of the code
|
||||||
let main_locs = parse_locs("main").unwrap();
|
let main_locs = parse_locs("main").unwrap();
|
||||||
|
//println!("Entry Point: {:x}", main_locs[0]);
|
||||||
uc.reg_write(RegisterX86::RIP as i32, main_locs[0])?;
|
uc.reg_write(RegisterX86::RIP as i32, main_locs[0])?;
|
||||||
|
|
||||||
// Setup the stack.
|
// Setup the stack.
|
||||||
@ -146,7 +149,6 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
|
|||||||
uc.reg_write(RAX as i32, HEAP_ADDRESS).unwrap();
|
uc.reg_write(RAX as i32, HEAP_ADDRESS).unwrap();
|
||||||
uc.reg_write(RIP as i32, addr + size as u64).unwrap();
|
uc.reg_write(RIP as i32, addr + size as u64).unwrap();
|
||||||
already_allocated_malloc.set(true);
|
already_allocated_malloc.set(true);
|
||||||
Ok(());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let already_allocated_free = already_allocated.clone();
|
let already_allocated_free = already_allocated.clone();
|
||||||
@ -165,9 +167,8 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
|
|||||||
);
|
);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
uc.reg_write(RIP as i32, addr + size as u64);
|
uc.reg_write(RIP as i32, addr + size as u64).unwrap();
|
||||||
already_allocated_free.set(false);
|
already_allocated_free.set(false);
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -176,36 +177,34 @@ fn fuzz(input_file: &str) -> Result<(), uc_error> {
|
|||||||
|
|
||||||
// This is a fancy print function that we're just going to skip for fuzzing.
|
// This is a fancy print function that we're just going to skip for fuzzing.
|
||||||
let hook_magicfn = move |mut uc: UnicornHandle<'_, _>, addr, size| {
|
let hook_magicfn = move |mut uc: UnicornHandle<'_, _>, addr, size| {
|
||||||
uc.reg_write(RIP as i32, addr + size as u64);
|
uc.reg_write(RIP as i32, addr + size as u64).unwrap();
|
||||||
Ok(())
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for addr in parse_locs("malloc").unwrap() {
|
for addr in parse_locs("malloc").unwrap() {
|
||||||
//hook!(addr, hook_malloc, "malloc");
|
//hook!(addr, hook_malloc, "malloc");
|
||||||
uc.add_code_hook(addr, addr, Box::new(hook_malloc))?;
|
uc.add_code_hook(addr, addr, Box::new(hook_malloc.clone()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr in parse_locs("free").unwrap() {
|
for addr in parse_locs("free").unwrap() {
|
||||||
uc.add_code_hook(addr, addr, Box::new(hook_free))?;
|
uc.add_code_hook(addr, addr, Box::new(hook_free.clone()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr in parse_locs("magicfn").unwrap() {
|
for addr in parse_locs("magicfn").unwrap() {
|
||||||
uc.add_code_hook(addr, addr, Box::new(hook_magicfn))?;
|
uc.add_code_hook(addr, addr, Box::new(hook_magicfn.clone()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let place_input_callback = |mut uc, afl_input, _persistent_round| {
|
let place_input_callback =
|
||||||
// apply constraints to the mutated input
|
|mut uc: UnicornHandle<'_, _>, afl_input: &[u8], _persistent_round| {
|
||||||
if afl_input.len() > INPUT_MAX as usize {
|
// apply constraints to the mutated input
|
||||||
//println!("Skipping testcase with leng {}", afl_input.len());
|
if afl_input.len() > INPUT_MAX as usize {
|
||||||
return false;
|
//println!("Skipping testcase with leng {}", afl_input.len());
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: afl_input[-1] = b'\0'
|
// TODO: afl_input[-1] = b'\0'
|
||||||
uc.mem_write(INPUT_ADDRESS, afl_input).unwrap();
|
uc.mem_write(INPUT_ADDRESS, afl_input).unwrap();
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
|
||||||
let crash_validation_callback = |uc, result, _input, _persistent_round| result != uc_error::OK;
|
|
||||||
|
|
||||||
let end_addrs = parse_locs("main_ends").unwrap();
|
let end_addrs = parse_locs("main_ends").unwrap();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user