Skip to content

Commit

Permalink
QEMU Synchronous Exit + Syx Snapshot update (AFLplusplus#1681)
Browse files Browse the repository at this point in the history
* Fix: typo in variable name.

* Fix: thread-safe static for emulator initialization.

* Initial support for synchronous exit from QEMU.

* New commands for the sync exit feature.
Supports physical and virtual address requests.
Updated for new SyxSnapshot naming.

* update qemu commit and fix some things

* - Removed lazy_static dependency
- Compiles for usermode
- Format

* Fix warnings

* Fixed sync_exit for missing architectures

---------

Co-authored-by: Andrea Fioraldi <[email protected]>
  • Loading branch information
rmalmain and andreafioraldi authored Nov 23, 2023
1 parent 28f34e0 commit 43c9100
Show file tree
Hide file tree
Showing 13 changed files with 521 additions and 41 deletions.
2 changes: 2 additions & 0 deletions libafl_qemu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ libafl_qemu_sys = { path = "./libafl_qemu_sys", version = "0.11.1" }
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
hashbrown = { version = "0.14", features = ["serde"] } # A faster hashmap, nostd compatible
num-traits = "0.2"
num-derive = "0.4"
num_enum = "0.7"
goblin = "0.7"
libc = "0.2"
Expand All @@ -64,6 +65,7 @@ rangemap = "1.3"
log = "0.4.20"
addr2line = "0.21"
typed-arena = "2.0"
enum-map = "2.7"

pyo3 = { version = "0.18", optional = true }

Expand Down
11 changes: 9 additions & 2 deletions libafl_qemu/libafl_qemu_build/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ const WRAPPER_HEADER: &str = r#"
#include "qemu/plugin-memory.h"
#include "libafl_extras/exit.h"
"#;

pub fn generate(
Expand Down Expand Up @@ -107,7 +109,11 @@ pub fn generate(
.allowlist_type("qemu_plugin_mem_rw")
.allowlist_type("MemOpIdx")
.allowlist_type("MemOp")
.allowlist_type("device_snapshot_kind_t")
.allowlist_type("DeviceSnapshotKind")
.allowlist_type("libafl_exit_reason")
.allowlist_type("libafl_exit_reason_kind")
.allowlist_type("libafl_exit_reason_sync_backdoor")
.allowlist_type("libafl_exit_reason_breakpoint")
.allowlist_function("qemu_user_init")
.allowlist_function("target_mmap")
.allowlist_function("target_mprotect")
Expand All @@ -123,10 +129,11 @@ pub fn generate(
.allowlist_function("qemu_plugin_get_hwaddr")
.allowlist_function("qemu_target_page_size")
.allowlist_function("syx_snapshot_init")
.allowlist_function("syx_snapshot_create")
.allowlist_function("syx_snapshot_new")
.allowlist_function("syx_snapshot_root_restore")
.allowlist_function("syx_snapshot_dirty_list_add")
.allowlist_function("device_list_all")
.allowlist_function("libafl_get_exit_reason")
.blocklist_function("main_loop_wait") // bindgen issue #1313
.parse_callbacks(Box::new(bindgen::CargoCallbacks));

Expand Down
19 changes: 10 additions & 9 deletions libafl_qemu/libafl_qemu_build/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use which::which;

const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
const QEMU_REVISION: &str = "b0c827246517e36b480ad501cba5ac6e2c3f26f5";
const QEMU_REVISION: &str = "8db5524416b52c999459f1fe3373846bdcb23ac1";

fn build_dep_check(tools: &[&str]) {
for tool in tools {
Expand Down Expand Up @@ -43,9 +43,9 @@ pub fn build(
cpu_target += "el";
}

let custum_qemu_dir = env::var_os("CUSTOM_QEMU_DIR").map(|x| x.to_string_lossy().to_string());
let custum_qemu_no_build = env::var("CUSTOM_QEMU_NO_BUILD").is_ok();
let custum_qemu_no_configure = env::var("CUSTOM_QEMU_NO_CONFIGURE").is_ok();
let custom_qemu_dir = env::var_os("CUSTOM_QEMU_DIR").map(|x| x.to_string_lossy().to_string());
let custom_qemu_no_build = env::var("CUSTOM_QEMU_NO_BUILD").is_ok();
let custom_qemu_no_configure = env::var("CUSTOM_QEMU_NO_CONFIGURE").is_ok();
println!("cargo:rerun-if-env-changed=CUSTOM_QEMU_DIR");
println!("cargo:rerun-if-env-changed=CUSTOM_QEMU_NO_BUILD");
println!("cargo:rerun-if-env-changed=CUSTOM_QEMU_NO_CONFIGURE");
Expand All @@ -63,7 +63,7 @@ pub fn build(
let cc_compiler = cc::Build::new().cpp(false).get_compiler();
let cpp_compiler = cc::Build::new().cpp(true).get_compiler();

let qemu_path = if let Some(qemu_dir) = custum_qemu_dir.as_ref() {
let qemu_path = if let Some(qemu_dir) = custom_qemu_dir.as_ref() {
Path::new(&qemu_dir).to_path_buf()
} else {
let qemu_path = target_dir.join(QEMU_DIRNAME);
Expand Down Expand Up @@ -128,14 +128,14 @@ pub fn build(

println!("cargo:rerun-if-changed={}", output_lib.to_string_lossy());

if !output_lib.is_file() || (custum_qemu_dir.is_some() && !custum_qemu_no_build) {
if !output_lib.is_file() || (custom_qemu_dir.is_some() && !custom_qemu_no_build) {
/*drop(
Command::new("make")
.current_dir(&qemu_path)
.arg("distclean")
.status(),
);*/
if is_usermode && !custum_qemu_no_configure {
if is_usermode && !custom_qemu_no_configure {
let mut cmd = Command::new("./configure");
cmd.current_dir(&qemu_path)
//.arg("--as-static-lib")
Expand All @@ -162,7 +162,7 @@ pub fn build(
cmd.arg("--enable-debug");
}
cmd.status().expect("Configure failed");
} else if !custum_qemu_no_configure {
} else if !custom_qemu_no_configure {
let mut cmd = Command::new("./configure");
cmd.current_dir(&qemu_path)
//.arg("--as-static-lib")
Expand Down Expand Up @@ -290,7 +290,8 @@ pub fn build(
.arg("--disable-xen")
.arg("--disable-xen-pci-passthrough")
.arg("--disable-xkbcommon")
.arg("--disable-zstd");
.arg("--disable-zstd")
.arg("--disable-tests");
if cfg!(feature = "debug_assertions") {
cmd.arg("--enable-debug");
}
Expand Down
22 changes: 21 additions & 1 deletion libafl_qemu/src/aarch64.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::sync::OnceLock;

use capstone::arch::BuildsCapstone;
use enum_map::{enum_map, EnumMap};
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[cfg(feature = "python")]
use pyo3::prelude::*;
pub use strum_macros::EnumIter;
pub use syscall_numbers::aarch64::*;

use crate::CallingConvention;
use crate::{sync_backdoor::SyncBackdoorArgs, CallingConvention};

#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)]
Expand Down Expand Up @@ -46,6 +49,23 @@ pub enum Regs {
Pstate = 33,
}

static SYNC_BACKDOOR_ARCH_REGS: OnceLock<EnumMap<SyncBackdoorArgs, Regs>> = OnceLock::new();

pub fn get_sync_backdoor_arch_regs() -> &'static EnumMap<SyncBackdoorArgs, Regs> {
SYNC_BACKDOOR_ARCH_REGS.get_or_init(|| {
enum_map! {
SyncBackdoorArgs::Ret => Regs::X0,
SyncBackdoorArgs::Cmd => Regs::X0,
SyncBackdoorArgs::Arg1 => Regs::X1,
SyncBackdoorArgs::Arg2 => Regs::X2,
SyncBackdoorArgs::Arg3 => Regs::X3,
SyncBackdoorArgs::Arg4 => Regs::X4,
SyncBackdoorArgs::Arg5 => Regs::X5,
SyncBackdoorArgs::Arg6 => Regs::X6,
}
})
}

/// alias registers
#[allow(non_upper_case_globals)]
impl Regs {
Expand Down
22 changes: 21 additions & 1 deletion libafl_qemu/src/arm.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::sync::OnceLock;

use capstone::arch::BuildsCapstone;
use enum_map::{enum_map, EnumMap};
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[cfg(feature = "python")]
use pyo3::prelude::*;
pub use strum_macros::EnumIter;
pub use syscall_numbers::arm::*;

use crate::CallingConvention;
use crate::{sync_backdoor::SyncBackdoorArgs, CallingConvention};

/// Registers for the ARM instruction set.
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
Expand All @@ -30,6 +33,23 @@ pub enum Regs {
R25 = 25,
}

static SYNC_BACKDOOR_ARCH_REGS: OnceLock<EnumMap<SyncBackdoorArgs, Regs>> = OnceLock::new();

pub fn get_sync_backdoor_arch_regs() -> &'static EnumMap<SyncBackdoorArgs, Regs> {
SYNC_BACKDOOR_ARCH_REGS.get_or_init(|| {
enum_map! {
SyncBackdoorArgs::Ret => Regs::R0,
SyncBackdoorArgs::Cmd => Regs::R0,
SyncBackdoorArgs::Arg1 => Regs::R1,
SyncBackdoorArgs::Arg2 => Regs::R2,
SyncBackdoorArgs::Arg3 => Regs::R3,
SyncBackdoorArgs::Arg4 => Regs::R4,
SyncBackdoorArgs::Arg5 => Regs::R5,
SyncBackdoorArgs::Arg6 => Regs::R6,
}
})
}

/// alias registers
#[allow(non_upper_case_globals)]
impl Regs {
Expand Down
Loading

0 comments on commit 43c9100

Please sign in to comment.