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:
parent
4af9af784f
commit
badf3f0e6e
@ -153,7 +153,9 @@ fn fuzz(
|
|||||||
let mut elf_buffer = Vec::new();
|
let mut elf_buffer = Vec::new();
|
||||||
let elf = EasyElf::from_file(emu::binary_path(), &mut elf_buffer)?;
|
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);
|
println!("LLVMFuzzerTestOneInput @ {:#x}", test_one_input_ptr);
|
||||||
|
|
||||||
emu::set_breakpoint(test_one_input_ptr); // LLVMFuzzerTestOneInput
|
emu::set_breakpoint(test_one_input_ptr); // LLVMFuzzerTestOneInput
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Utilities to parse and process ELFs
|
//! 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 std::{convert::AsRef, fs::File, io::Read, path::Path, str};
|
||||||
|
|
||||||
use libafl::Error;
|
use libafl::Error;
|
||||||
@ -38,18 +38,26 @@ impl<'a> EasyElf<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[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() {
|
for sym in self.elf.syms.iter() {
|
||||||
if let Some(sym_name) = self.elf.strtab.get_at(sym.st_name) {
|
if let Some(sym_name) = self.elf.strtab.get_at(sym.st_name) {
|
||||||
if sym_name == name {
|
if sym_name == name {
|
||||||
return if sym.st_value == 0 {
|
return if sym.st_value == 0 {
|
||||||
None
|
None
|
||||||
|
} else {
|
||||||
|
if self.is_pic() {
|
||||||
|
Some(sym.st_value + load_addr)
|
||||||
} else {
|
} else {
|
||||||
Some(sym.st_value)
|
Some(sym.st_value)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_pic(&self) -> bool {
|
||||||
|
self.elf.header.e_type == ET_DYN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ extern "C" {
|
|||||||
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
|
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
|
||||||
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
|
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
|
||||||
fn libafl_qemu_run() -> i32;
|
fn libafl_qemu_run() -> i32;
|
||||||
|
fn libafl_load_addr() -> u64;
|
||||||
|
|
||||||
fn strlen(s: *const u8) -> usize;
|
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))) }
|
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> {
|
pub fn map_private(addr: u64, size: usize, perms: MmapPerms) -> Result<u64, String> {
|
||||||
let res = unsafe {
|
let res = unsafe {
|
||||||
target_mmap(
|
target_mmap(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user