remove hardcoded addresses

This commit is contained in:
Alwin Berger 2022-01-11 19:32:25 +01:00
parent de4481e70d
commit c1db0752c1
3 changed files with 56 additions and 18 deletions

View File

@ -18,3 +18,4 @@ clap = { version = "3.0.0-beta.2", features = ["default"] }
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"], default-features=false } # A faster hashmap, nostd compatible hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"], default-features=false } # A faster hashmap, nostd compatible
nix = "0.23.0" nix = "0.23.0"
goblin = "0.4.2"

View File

@ -1,5 +1,6 @@
//! A singlethreaded QEMU fuzzer that can auto-restart. //! A singlethreaded QEMU fuzzer that can auto-restart.
use std::path::Path;
use libafl::corpus::Corpus; use libafl::corpus::Corpus;
use libafl::state::HasCorpus; use libafl::state::HasCorpus;
use libafl::Fuzzer; use libafl::Fuzzer;
@ -58,12 +59,18 @@ pub fn main() {
// Needed only on no_std // Needed only on no_std
//RegistryBuilder::register::<Tokens>(); //RegistryBuilder::register::<Tokens>();
let mut args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let res = match App::new("libafl_qemu_fuzzbench") let res = match App::new("wcet_qemu_fuzzer")
.version("0.4.0") .version("0.4.0")
.author("AFLplusplus team") .author("Alwin Berger")
.about("LibAFL-based fuzzer with QEMU for Fuzzbench") .about("LibAFL-based fuzzer for WCET in System Kernels.")
.arg(
Arg::new("k")
.long("libafl-kernel")
.required(true)
.takes_value(true),
)
.arg( .arg(
Arg::new("out") Arg::new("out")
.long("libafl-out") .long("libafl-out")
@ -130,43 +137,72 @@ pub fn main() {
return; return;
} }
fuzz(in_dir) let kernel = PathBuf::from(res.value_of("k").unwrap().to_string());
fuzz(in_dir, kernel)
.expect("An error occurred while fuzzing"); .expect("An error occurred while fuzzing");
} }
fn virt2phys(vaddr : u64, tab : &goblin::elf::Elf) -> u64 {
let ret;
for i in &tab.program_headers {
if i.vm_range().contains(&vaddr.try_into().expect("Can not cast u64 to usize")) {
ret = vaddr-i.p_vaddr+i.p_paddr;
return ret - (ret % 2);
}
}
ret = vaddr;
// unlike the arm-toolcahin goblin produces some off-by one errors when parsing arm
return ret - (ret % 2);
}
/// The actual fuzzer /// The actual fuzzer
fn fuzz( fn fuzz(
seed_dir: PathBuf, seed_dir: PathBuf,
kernel: PathBuf,
) -> Result<(), Error> { ) -> Result<(), Error> {
//=========== Setup emulator //=========== Setup emulator
let mut env: Vec<(String, String)> = env::vars().collect(); let mut env: Vec<(String, String)> = env::vars().collect();
let mut args2: Vec<String> = vec![ let mut args: Vec<String> = vec![
"qemu-system-arm", "qemu-system-arm",
"-machine","mps2-an385", "-machine","mps2-an385",
"-monitor", "null", "-monitor", "null",
"-semihosting", "-semihosting",
"--semihosting-config", "enable=on,target=native", "--semihosting-config", "enable=on,target=native",
"-kernel", "RTOSDemo.axf", "-kernel", kernel.to_str().unwrap(),
"-serial", "stdio", "-nographic", "-serial", "stdio", "-nographic",
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2", "-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
"-S" "-S"
].iter().map(|x| x.to_string()).collect(); ].iter().map(|x| x.to_string()).collect();
let emu = Emulator::new(&mut args2, &mut env); let emu = Emulator::new(&mut args, &mut env);
//=========== Analyze the binary to find the target function address //=========== Analyze the binary to find the target function address
// let mut elf_buffer = Vec::new(); let mut elf_buffer = Vec::new();
// let elf = EasyElf::from_file(emu::binary_path(), &mut elf_buffer)?; let bin_path=Path::new("./RTOSDemo.axf");
let elf = EasyElf::from_file(bin_path, &mut elf_buffer)?;
// let test_one_input_ptr = elf let test_one_input_ptr = elf
// .resolve_symbol("LLVMFuzzerTestOneInput", 0) .resolve_symbol("FUZZ_INPUT", 0)
// .expect("Symbol LLVMFuzzerTestOneInput not found"); .expect("Symbol FUZZ_INPUT not found");
// println!("LLVMFuzzerTestOneInput @ {:#x}", test_one_input_ptr); let test_one_input_ptr = virt2phys(test_one_input_ptr,&elf.goblin());
println!("FUZZ_INPUT @ {:#x}", test_one_input_ptr);
let test_length_ptr = elf
.resolve_symbol("FUZZ_LENGTH", 0)
.expect("Symbol FUZZ_LENGTH not found");
let test_length_ptr = virt2phys(test_length_ptr,&elf.goblin());
println!("FUZZ_LENGTH @ {:#x}", test_length_ptr);
let check_breakpoint = elf
.resolve_symbol("trigger_Qemu_break", 0)
.expect("Symbol trigger_Qemu_break not found");
let check_breakpoint = virt2phys(check_breakpoint,&elf.goblin());
println!("Breakpoint at {:#x}", check_breakpoint);
//====== Create the input field //====== Create the input field
let input_addr = 0x00006de4+0xc; let input_addr = test_one_input_ptr;
println!("Placing input at {:#x}", input_addr); println!("Placing input at {:#x}", input_addr);
emu.set_breakpoint(0x00004f5c); emu.set_breakpoint(check_breakpoint);
//====== Create the most simple status display and managers. //====== Create the most simple status display and managers.
@ -221,7 +257,8 @@ fn fuzz(
} }
unsafe { unsafe {
emu.write_mem(0x00006de4+0xc,buf); emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
emu.write_mem(input_addr,buf);
// println!("{:#?}",edges_copy); // println!("{:#?}",edges_copy);
emu.run(); emu.run();

View File

@ -1,3 +1,3 @@
mkdir -p target/test_in target/test_out mkdir -p target/test_in target/test_out
[ ! -f target/test_in/test ] && echo " !test" > target/test_in/test [ ! -f target/test_in/test ] && echo " !test" > target/test_in/test
LD_LIBRARY_PATH=target/debug target/debug/wcet_qemu_sys $1 --libafl-out target/test_out --libafl-in target/test_in LD_LIBRARY_PATH=target/debug target/debug/wcet_qemu_sys --libafl-kernel $1 --libafl-out target/test_out --libafl-in target/test_in