Resolve symbols in PIC binaries in libafl_qemu (#216)

* empty libafl_qemu crate

* fuzzbench qemu fuzzer skeleton

* emu.run() works without bp

* working emu loop

* resolve elf symbols

* running Qemu fuzzer without coverage

* qemu fuzzer with edge coverage

* merge into inprocess::GLOBAL_STATE

* create QemuExecutor and remove QemuEmulator

* qemu hooks and persist edges mapping storing them in State

* windows fix

* add libafl_qemu to workspace

* windows fix

* some clippy

* clippy

* fix fuzzbench_qemu

* fix fuzzbench_qemu makefile

* fuck you macos

* resolve PIC symbols
This commit is contained in:
Andrea Fioraldi 2021-07-09 15:17:57 +02:00 committed by GitHub
parent 4af9af784f
commit badf3f0e6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 4 deletions

View File

@ -153,7 +153,9 @@ fn fuzz(
let mut elf_buffer = Vec::new();
let elf = EasyElf::from_file(emu::binary_path(), &mut elf_buffer)?;
let test_one_input_ptr = elf.resolve_symbol("LLVMFuzzerTestOneInput").unwrap();
let test_one_input_ptr = elf
.resolve_symbol("LLVMFuzzerTestOneInput", emu::load_addr())
.expect("Symbol LLVMFuzzerTestOneInput not found".into());
println!("LLVMFuzzerTestOneInput @ {:#x}", test_one_input_ptr);
emu::set_breakpoint(test_one_input_ptr); // LLVMFuzzerTestOneInput

View File

@ -1,6 +1,6 @@
//! Utilities to parse and process ELFs
use goblin::elf::Elf;
use goblin::elf::{header::ET_DYN, Elf};
use std::{convert::AsRef, fs::File, io::Read, path::Path, str};
use libafl::Error;
@ -38,18 +38,26 @@ impl<'a> EasyElf<'a> {
}
#[must_use]
pub fn resolve_symbol(&self, name: &str) -> Option<u64> {
pub fn resolve_symbol(&self, name: &str, load_addr: u64) -> Option<u64> {
for sym in self.elf.syms.iter() {
if let Some(sym_name) = self.elf.strtab.get_at(sym.st_name) {
if sym_name == name {
return if sym.st_value == 0 {
None
} else {
Some(sym.st_value)
if self.is_pic() {
Some(sym.st_value + load_addr)
} else {
Some(sym.st_value)
}
};
}
}
}
None
}
fn is_pic(&self) -> bool {
self.elf.header.e_type == ET_DYN
}
}

View File

@ -14,6 +14,7 @@ extern "C" {
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
fn libafl_qemu_run() -> i32;
fn libafl_load_addr() -> u64;
fn strlen(s: *const u8) -> usize;
@ -129,6 +130,11 @@ pub fn binary_path<'a>() -> &'a str {
unsafe { from_utf8_unchecked(from_raw_parts(exec_path, strlen(exec_path))) }
}
#[must_use]
pub fn load_addr() -> u64 {
unsafe { libafl_load_addr() }
}
pub fn map_private(addr: u64, size: usize, perms: MmapPerms) -> Result<u64, String> {
let res = unsafe {
target_mmap(