libafl_qemu snapshot device filter (#1386)
* libafl_qemu snapshot device filter * Working device list * regenerate bindings stub
This commit is contained in:
parent
fc9caa8314
commit
ac4a0e7330
@ -90,6 +90,9 @@ pub fn fuzz() {
|
|||||||
|
|
||||||
emu.set_breakpoint(breakpoint); // BREAKPOINT
|
emu.set_breakpoint(breakpoint); // BREAKPOINT
|
||||||
|
|
||||||
|
let devices = emu.list_devices();
|
||||||
|
println!("Devices = {:?}", devices);
|
||||||
|
|
||||||
// let saved_cpu_states: Vec<_> = (0..emu.num_cpus())
|
// let saved_cpu_states: Vec<_> = (0..emu.num_cpus())
|
||||||
// .map(|i| emu.cpu_from_index(i).save_state())
|
// .map(|i| emu.cpu_from_index(i).save_state())
|
||||||
// .collect();
|
// .collect();
|
||||||
|
@ -51,6 +51,7 @@ const WRAPPER_HEADER: &str = r#"
|
|||||||
#include "sysemu/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "sysemu/replay.h"
|
#include "sysemu/replay.h"
|
||||||
|
|
||||||
|
#include "libafl_extras/syx-snapshot/device-save.h"
|
||||||
#include "libafl_extras/syx-snapshot/syx-snapshot.h"
|
#include "libafl_extras/syx-snapshot/syx-snapshot.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -101,6 +102,7 @@ pub fn generate(
|
|||||||
.allowlist_type("qemu_plugin_mem_rw")
|
.allowlist_type("qemu_plugin_mem_rw")
|
||||||
.allowlist_type("MemOpIdx")
|
.allowlist_type("MemOpIdx")
|
||||||
.allowlist_type("MemOp")
|
.allowlist_type("MemOp")
|
||||||
|
.allowlist_type("device_snapshot_kind_t")
|
||||||
.allowlist_function("qemu_user_init")
|
.allowlist_function("qemu_user_init")
|
||||||
.allowlist_function("target_mmap")
|
.allowlist_function("target_mmap")
|
||||||
.allowlist_function("target_mprotect")
|
.allowlist_function("target_mprotect")
|
||||||
@ -117,6 +119,7 @@ pub fn generate(
|
|||||||
.allowlist_function("syx_snapshot_create")
|
.allowlist_function("syx_snapshot_create")
|
||||||
.allowlist_function("syx_snapshot_root_restore")
|
.allowlist_function("syx_snapshot_root_restore")
|
||||||
.allowlist_function("syx_snapshot_dirty_list_add")
|
.allowlist_function("syx_snapshot_dirty_list_add")
|
||||||
|
.allowlist_function("device_list_all")
|
||||||
.blocklist_function("main_loop_wait") // bindgen issue #1313
|
.blocklist_function("main_loop_wait") // bindgen issue #1313
|
||||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use which::which;
|
|||||||
|
|
||||||
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
||||||
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
||||||
const QEMU_REVISION: &str = "6df19ab8f161791b7b16a896d1da1d16b8749006";
|
const QEMU_REVISION: &str = "659539eaceb7acf242f2f6a573b705e1be1befb6";
|
||||||
|
|
||||||
fn build_dep_check(tools: &[&str]) {
|
fn build_dep_check(tools: &[&str]) {
|
||||||
for tool in tools {
|
for tool in tools {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,10 @@ use core::{
|
|||||||
ptr::{addr_of, copy_nonoverlapping, null},
|
ptr::{addr_of, copy_nonoverlapping, null},
|
||||||
};
|
};
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
use std::ffi::CString;
|
use std::{
|
||||||
|
ffi::{CStr, CString},
|
||||||
|
ptr::null_mut,
|
||||||
|
};
|
||||||
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
|
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
@ -30,6 +33,43 @@ pub type GuestHwAddrInfo = libafl_qemu_sys::qemu_plugin_hwaddr;
|
|||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
pub type FastSnapshot = *mut libafl_qemu_sys::syx_snapshot_t;
|
pub type FastSnapshot = *mut libafl_qemu_sys::syx_snapshot_t;
|
||||||
|
|
||||||
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
|
pub enum DeviceSnapshotFilter {
|
||||||
|
All,
|
||||||
|
AllowList(Vec<String>),
|
||||||
|
DenyList(Vec<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
|
impl DeviceSnapshotFilter {
|
||||||
|
fn enum_id(&self) -> libafl_qemu_sys::device_snapshot_kind_t {
|
||||||
|
match self {
|
||||||
|
DeviceSnapshotFilter::All => {
|
||||||
|
libafl_qemu_sys::device_snapshot_kind_e_DEVICE_SNAPSHOT_ALL
|
||||||
|
}
|
||||||
|
DeviceSnapshotFilter::AllowList(_) => {
|
||||||
|
libafl_qemu_sys::device_snapshot_kind_e_DEVICE_SNAPSHOT_ALLOWLIST
|
||||||
|
}
|
||||||
|
DeviceSnapshotFilter::DenyList(_) => {
|
||||||
|
libafl_qemu_sys::device_snapshot_kind_e_DEVICE_SNAPSHOT_DENYLIST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn devices(&self, v: &mut Vec<*mut i8>) -> *mut *mut i8 {
|
||||||
|
v.clear();
|
||||||
|
match self {
|
||||||
|
DeviceSnapshotFilter::All => null_mut(),
|
||||||
|
DeviceSnapshotFilter::AllowList(l) | DeviceSnapshotFilter::DenyList(l) => {
|
||||||
|
for name in l {
|
||||||
|
v.push(name.as_bytes().as_ptr() as *mut i8);
|
||||||
|
}
|
||||||
|
v.as_mut_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct MemAccessInfo {
|
pub struct MemAccessInfo {
|
||||||
@ -1142,7 +1182,30 @@ impl Emulator {
|
|||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn create_fast_snapshot(&self, track: bool) -> FastSnapshot {
|
pub fn create_fast_snapshot(&self, track: bool) -> FastSnapshot {
|
||||||
unsafe { libafl_qemu_sys::syx_snapshot_create(track) }
|
unsafe {
|
||||||
|
libafl_qemu_sys::syx_snapshot_create(
|
||||||
|
track,
|
||||||
|
libafl_qemu_sys::device_snapshot_kind_e_DEVICE_SNAPSHOT_ALL,
|
||||||
|
null_mut(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
|
#[must_use]
|
||||||
|
pub fn create_fast_snapshot_filter(
|
||||||
|
&self,
|
||||||
|
track: bool,
|
||||||
|
device_filter: &DeviceSnapshotFilter,
|
||||||
|
) -> FastSnapshot {
|
||||||
|
let mut v = vec![];
|
||||||
|
unsafe {
|
||||||
|
libafl_qemu_sys::syx_snapshot_create(
|
||||||
|
track,
|
||||||
|
device_filter.enum_id(),
|
||||||
|
device_filter.devices(&mut v),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
@ -1150,6 +1213,29 @@ impl Emulator {
|
|||||||
unsafe { libafl_qemu_sys::syx_snapshot_root_restore(snapshot) }
|
unsafe { libafl_qemu_sys::syx_snapshot_root_restore(snapshot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
|
pub fn list_devices(&self) -> Vec<String> {
|
||||||
|
let mut r = vec![];
|
||||||
|
unsafe {
|
||||||
|
let devices = libafl_qemu_sys::device_list_all();
|
||||||
|
if devices.is_null() {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ptr = devices;
|
||||||
|
while !(*ptr).is_null() {
|
||||||
|
let c_str: &CStr = CStr::from_ptr(*ptr);
|
||||||
|
let name = c_str.to_str().unwrap().to_string();
|
||||||
|
r.push(name);
|
||||||
|
|
||||||
|
ptr = ptr.add(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
libc::free(devices as *mut c_void);
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_pre_syscall_hook(
|
pub fn set_pre_syscall_hook(
|
||||||
&self,
|
&self,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user