libafl bridge as Rust crate

This commit is contained in:
Andrea Fioraldi 2021-07-05 15:44:07 +02:00
parent 308c6ab905
commit 5e1a634d0c
5 changed files with 134 additions and 0 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
/qemu_libafl_bridge/Cargo.lock
/qemu_libafl_bridge/target/
/GNUmakefile /GNUmakefile
/build/ /build/
*.pyc *.pyc

6
configure vendored
View File

@ -446,6 +446,8 @@ slirp_smbd="$default_feature"
malloc_trim="auto" malloc_trim="auto"
gio="$default_feature" gio="$default_feature"
libafl_bridge=""
# parse CC options second # parse CC options second
for opt do for opt do
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
@ -1558,6 +1560,8 @@ for opt do
;; ;;
--disable-slirp-smbd) slirp_smbd=no --disable-slirp-smbd) slirp_smbd=no
;; ;;
--with-libafl-bridge=*) libafl_bridge="$optarg"
;;
*) *)
echo "ERROR: unknown option $opt" echo "ERROR: unknown option $opt"
echo "Try '$0 --help' for more information" echo "Try '$0 --help' for more information"
@ -1566,6 +1570,8 @@ for opt do
esac esac
done done
QEMU_LDFLAGS="$QEMU_LDFLAGS $libafl_bridge"
case $git_submodules_action in case $git_submodules_action in
update|validate) update|validate)
if test ! -e "$source_path/.git"; then if test ! -e "$source_path/.git"; then

View File

@ -0,0 +1,11 @@
[package]
name = "qemu_libafl_bridge"
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
[dependencies]
num = "0.4"
num_enum = "0.5.1"

View File

@ -0,0 +1,23 @@
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[derive(IntoPrimitive, TryFromPrimitive, Clone, Copy)]
#[repr(i32)]
#[allow(clippy::pub_enum_variant_names)]
pub enum Amd64Regs {
Rax = 0,
Rcx = 1,
Rdx = 2,
Rbx = 3,
Rsp = 4,
Rbp = 5,
Rsi = 6,
Rdi = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
}

View File

@ -0,0 +1,92 @@
use core::{mem::transmute, ptr::copy_nonoverlapping};
use num::Num;
pub mod amd64;
/*
int libafl_qemu_write_reg(int reg, uint8_t* val);
int libafl_qemu_read_reg(int reg, uint8_t* val);
int libafl_qemu_num_regs(void);
int libafl_qemu_set_breakpoint(uint64_t addr);
int libafl_qemu_remove_breakpoint(uint64_t addr);
*/
extern "C" {
fn libafl_qemu_write_reg(reg: i32, val: *const u8) -> i32;
fn libafl_qemu_read_reg(reg: i32, val: *mut u8) -> i32;
fn libafl_qemu_num_regs() -> i32;
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
fn libafl_qemu_run() -> i32;
static guest_base: isize;
}
pub struct QemuEmulator {}
impl QemuEmulator {
pub fn write_mem(&mut self, addr: isize, buf: &[u8]) {
let host_addr = self.g2h(addr);
unsafe { copy_nonoverlapping(buf.as_ptr() as *const u8, host_addr, buf.len()) }
}
pub fn read_mem(&mut self, addr: isize, buf: &mut [u8]) {
let host_addr = self.g2h(addr);
unsafe {
copy_nonoverlapping(
host_addr as *const u8,
buf.as_mut_ptr() as *mut u8,
buf.len(),
)
}
}
pub fn num_regs(&self) -> i32 {
unsafe { libafl_qemu_num_regs() }
}
pub fn write_reg<T>(&mut self, reg: i32, val: T) -> Result<(), String>
where
T: Num + PartialOrd + Copy,
{
let success = unsafe { libafl_qemu_write_reg(reg, &val as *const _ as *const u8) };
if success != 0 {
Ok(())
} else {
Err(format!("Failed to write to register {}", reg))
}
}
pub fn read_reg<T>(&mut self, reg: i32) -> Result<T, String>
where
T: Num + PartialOrd + Copy,
{
let mut val = T::zero();
let success = unsafe { libafl_qemu_read_reg(reg, &mut val as *mut _ as *mut u8) };
if success != 0 {
Ok(val)
} else {
Err(format!("Failed to read register {}", reg))
}
}
pub fn set_breakpoint(&mut self, addr: isize) {
unsafe { libafl_qemu_set_breakpoint(addr as u64) };
}
pub fn remove_breakpoint(&mut self, addr: isize) {
unsafe { libafl_qemu_remove_breakpoint(addr as u64) };
}
pub fn run(&mut self) {
unsafe { libafl_qemu_run() };
}
pub fn g2h(&self, addr: isize) -> *mut u8 {
unsafe { transmute(addr + guest_base) }
}
pub fn h2g(&self, addr: isize) -> *mut u8 {
unsafe { transmute(addr - guest_base) }
}
}