Qemu as lib (#301)
* linking problems * use shared lib * ci * clippy, ci fixegit pushs * ingoring distclean result * clippy * clippy Co-authored-by: Dominik Maier <domenukk@gmail.com>
This commit is contained in:
parent
8f5df699fe
commit
1fde608145
4
.github/workflows/build_and_test.yml
vendored
4
.github/workflows/build_and_test.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
|||||||
toolchain: stable
|
toolchain: stable
|
||||||
- uses: Swatinem/rust-cache@v1
|
- uses: Swatinem/rust-cache@v1
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt-get install -y llvm llvm-dev clang
|
run: sudo apt-get install -y llvm llvm-dev clang ninja-build
|
||||||
- name: get clang version
|
- name: get clang version
|
||||||
run: command -v llvm-config && clang -v
|
run: command -v llvm-config && clang -v
|
||||||
- name: Install cargo-hack
|
- name: Install cargo-hack
|
||||||
@ -90,7 +90,7 @@ jobs:
|
|||||||
- name: Add nightly rustfmt and clippy
|
- name: Add nightly rustfmt and clippy
|
||||||
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt-get install -y llvm llvm-dev clang nasm
|
run: sudo apt-get install -y llvm llvm-dev clang nasm ninja-build
|
||||||
- name: Build and run example fuzzers
|
- name: Build and run example fuzzers
|
||||||
run: ./scripts/test_all_fuzzers.sh
|
run: ./scripts/test_all_fuzzers.sh
|
||||||
nostd-build:
|
nostd-build:
|
||||||
|
@ -9,9 +9,6 @@ default = ["std"]
|
|||||||
std = []
|
std = []
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
|
||||||
codegen-units = 1
|
|
||||||
opt-level = 3
|
|
||||||
debug = true
|
debug = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -19,7 +16,3 @@ libafl = { path = "../../libafl/" }
|
|||||||
libafl_qemu = { path = "../../libafl_qemu/" }
|
libafl_qemu = { path = "../../libafl_qemu/" }
|
||||||
clap = { version = "3.0.0-beta.2", features = ["default"] }
|
clap = { version = "3.0.0-beta.2", features = ["default"] }
|
||||||
nix = "0.20.0"
|
nix = "0.20.0"
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "fuzzbench_qemu"
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
@ -44,13 +44,16 @@ use libafl_qemu::{
|
|||||||
QemuExecutor,
|
QemuExecutor,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The fuzzer main (as `no_mangle` C function)
|
/// The fuzzer main
|
||||||
#[no_mangle]
|
pub fn main() {
|
||||||
pub fn libafl_qemu_main() {
|
|
||||||
// Registry the metadata types used in this fuzzer
|
// Registry the metadata types used in this fuzzer
|
||||||
// Needed only on no_std
|
// Needed only on no_std
|
||||||
//RegistryBuilder::register::<Tokens>();
|
//RegistryBuilder::register::<Tokens>();
|
||||||
|
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let env: Vec<(String, String)> = env::vars().collect();
|
||||||
|
emu::init(&args, &env);
|
||||||
|
|
||||||
let res = match App::new("libafl_qemu_fuzzbench")
|
let res = match App::new("libafl_qemu_fuzzbench")
|
||||||
.version("0.4.0")
|
.version("0.4.0")
|
||||||
.author("AFLplusplus team")
|
.author("AFLplusplus team")
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub mod fuzzer;
|
|
7
fuzzers/fuzzbench_qemu/src/main.rs
Normal file
7
fuzzers/fuzzbench_qemu/src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub mod fuzzer;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fuzzer::main()
|
||||||
|
}
|
@ -25,3 +25,7 @@ libc = "0.2.97"
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = { version = "1.0" }
|
cc = { version = "1.0" }
|
||||||
|
which = "4.1"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["rlib", "cdylib"]
|
||||||
|
@ -1,21 +1,215 @@
|
|||||||
use std::{env, path::Path};
|
use std::{env, fs::copy, path::Path, process::Command};
|
||||||
|
//use std::fs::read_dir;
|
||||||
|
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 = "22daaa7d0c76b32f8391bad40c0b220f3e659f66";
|
||||||
|
|
||||||
|
fn build_dep_check(tools: &[&str]) {
|
||||||
|
for tool in tools {
|
||||||
|
which(tool).unwrap_or_else(|_| panic!("Build tool {} not found", tool));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
let out_dir = out_dir.to_string_lossy().to_string();
|
println!("cargo:rerun-if-env-changed=CPU_TARGET");
|
||||||
let src_dir = Path::new("src");
|
|
||||||
|
|
||||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||||
|
if target_os != "linux" {
|
||||||
if target_os == "linux" {
|
return;
|
||||||
println!("cargo:rerun-if-changed=src/weaks.c");
|
|
||||||
|
|
||||||
cc::Build::new()
|
|
||||||
.file(src_dir.join("weaks.c"))
|
|
||||||
.compile("weaks");
|
|
||||||
|
|
||||||
println!("cargo:rustc-link-search=native={}", &out_dir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
let jobs = env::var("CARGO_BUILD_JOBS").unwrap_or_else(|_| "1".to_owned());
|
||||||
|
let cpu_target = env::var("CPU_TARGET").unwrap_or_else(|_| {
|
||||||
|
println!("cargo:warning=CPU_TARGET is not set, default to x86_64");
|
||||||
|
"x86_64".to_owned()
|
||||||
|
});
|
||||||
|
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
let out_dir = out_dir.to_string_lossy().to_string();
|
||||||
|
let out_dir_path = Path::new(&out_dir);
|
||||||
|
let mut target_dir = out_dir_path.to_path_buf();
|
||||||
|
target_dir.pop();
|
||||||
|
target_dir.pop();
|
||||||
|
target_dir.pop();
|
||||||
|
//let cwd = env::current_dir().unwrap().to_string_lossy().to_string();
|
||||||
|
|
||||||
|
build_dep_check(&["git", "make"]);
|
||||||
|
|
||||||
|
let qemu_path = out_dir_path.join(QEMU_DIRNAME);
|
||||||
|
if !qemu_path.is_dir() {
|
||||||
|
println!(
|
||||||
|
"cargo:warning=Qemu not found, cloning with git ({})...",
|
||||||
|
QEMU_REVISION
|
||||||
|
);
|
||||||
|
Command::new("git")
|
||||||
|
.current_dir(&out_dir_path)
|
||||||
|
.arg("clone")
|
||||||
|
.arg(QEMU_URL)
|
||||||
|
.status()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.current_dir(&qemu_path)
|
||||||
|
.arg("checkout")
|
||||||
|
.arg(QEMU_REVISION)
|
||||||
|
.status()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let build_dir = qemu_path.join("build");
|
||||||
|
let output_lib = build_dir.join(&format!("libqemu-{}.so", cpu_target));
|
||||||
|
if !output_lib.is_file() {
|
||||||
|
drop(
|
||||||
|
Command::new("make")
|
||||||
|
.current_dir(&qemu_path)
|
||||||
|
.arg("distclean")
|
||||||
|
.status(),
|
||||||
|
);
|
||||||
|
Command::new("./configure")
|
||||||
|
.current_dir(&qemu_path)
|
||||||
|
//.arg("--as-static-lib")
|
||||||
|
.arg("--as-shared-lib")
|
||||||
|
.arg(&format!("--target-list={}-linux-user", cpu_target))
|
||||||
|
.args(&[
|
||||||
|
"--audio-drv-list=",
|
||||||
|
"--disable-blobs",
|
||||||
|
"--disable-bochs",
|
||||||
|
"--disable-brlapi",
|
||||||
|
"--disable-bsd-user",
|
||||||
|
"--disable-bzip2",
|
||||||
|
"--disable-cap-ng",
|
||||||
|
"--disable-cloop",
|
||||||
|
"--disable-curl",
|
||||||
|
"--disable-curses",
|
||||||
|
"--disable-dmg",
|
||||||
|
"--disable-fdt",
|
||||||
|
"--disable-gcrypt",
|
||||||
|
"--disable-glusterfs",
|
||||||
|
"--disable-gnutls",
|
||||||
|
"--disable-gtk",
|
||||||
|
"--disable-guest-agent",
|
||||||
|
"--disable-iconv",
|
||||||
|
"--disable-libiscsi",
|
||||||
|
"--disable-libnfs",
|
||||||
|
"--disable-libssh",
|
||||||
|
"--disable-libusb",
|
||||||
|
"--disable-linux-aio",
|
||||||
|
"--disable-live-block-migration",
|
||||||
|
"--disable-lzo",
|
||||||
|
"--disable-nettle",
|
||||||
|
"--disable-numa",
|
||||||
|
"--disable-opengl",
|
||||||
|
"--disable-parallels",
|
||||||
|
"--disable-plugins",
|
||||||
|
"--disable-qcow1",
|
||||||
|
"--disable-qed",
|
||||||
|
"--disable-rbd",
|
||||||
|
"--disable-rdma",
|
||||||
|
"--disable-replication",
|
||||||
|
"--disable-sdl",
|
||||||
|
"--disable-seccomp",
|
||||||
|
"--disable-smartcard",
|
||||||
|
"--disable-snappy",
|
||||||
|
"--disable-spice",
|
||||||
|
"--disable-system",
|
||||||
|
"--disable-tools",
|
||||||
|
"--disable-tpm",
|
||||||
|
"--disable-usb-redir",
|
||||||
|
"--disable-vde",
|
||||||
|
"--disable-vdi",
|
||||||
|
"--disable-vhost-crypto",
|
||||||
|
"--disable-vhost-kernel",
|
||||||
|
"--disable-vhost-net",
|
||||||
|
"--disable-vhost-scsi",
|
||||||
|
"--disable-vhost-user",
|
||||||
|
"--disable-vhost-vdpa",
|
||||||
|
"--disable-vhost-vsock",
|
||||||
|
"--disable-virglrenderer",
|
||||||
|
"--disable-virtfs",
|
||||||
|
"--disable-vnc",
|
||||||
|
"--disable-vnc-jpeg",
|
||||||
|
"--disable-vnc-png",
|
||||||
|
"--disable-vnc-sasl",
|
||||||
|
"--disable-vte",
|
||||||
|
"--disable-vvfat",
|
||||||
|
"--disable-xen",
|
||||||
|
"--disable-xen-pci-passthrough",
|
||||||
|
"--disable-xfsctl",
|
||||||
|
])
|
||||||
|
.status()
|
||||||
|
.expect("Configure failed");
|
||||||
|
Command::new("make")
|
||||||
|
.current_dir(&qemu_path)
|
||||||
|
.arg("-j")
|
||||||
|
.arg(&jobs)
|
||||||
|
.status()
|
||||||
|
.expect("Make failed");
|
||||||
|
//let _ = remove_file(build_dir.join(&format!("libqemu-{}.so", cpu_target)));
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(
|
||||||
|
build_dir.join(&format!("libqemu-{}.so", cpu_target)),
|
||||||
|
target_dir.join(&format!("libqemu-{}.so", cpu_target)),
|
||||||
|
)
|
||||||
|
.expect("Failed to copy the QEMU shared object");
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-link-search=native={}",
|
||||||
|
&target_dir.to_string_lossy().to_string()
|
||||||
|
);
|
||||||
|
println!("cargo:rustc-link-lib=qemu-{}", cpu_target);
|
||||||
|
|
||||||
|
println!("cargo:rustc-env=LD_LIBRARY_PATH={}", target_dir.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Build a static library
|
||||||
|
let mut objects = vec![];
|
||||||
|
for dir in &[
|
||||||
|
build_dir.join("libcommon.fa.p"),
|
||||||
|
build_dir.join(&format!("libqemu-{}-linux-user.fa.p", cpu_target)),
|
||||||
|
build_dir.join("libqemuutil.a.p"),
|
||||||
|
build_dir.join("libqom.fa.p"),
|
||||||
|
build_dir.join("libhwcore.fa.p"),
|
||||||
|
build_dir.join("libcapstone.a.p"),
|
||||||
|
] {
|
||||||
|
for path in read_dir(dir).unwrap() {
|
||||||
|
let path = path.unwrap().path();
|
||||||
|
if path.is_file() {
|
||||||
|
if let Some(name) = path.file_name() {
|
||||||
|
if name.to_string_lossy().starts_with("stubs") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if let Some(ext) = path.extension() {
|
||||||
|
if ext == "o" {
|
||||||
|
objects.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Command::new("ar")
|
||||||
|
.current_dir(&out_dir_path)
|
||||||
|
.arg("crus")
|
||||||
|
.arg("libqemu-bridge.a")
|
||||||
|
.args(&objects)
|
||||||
|
.status()
|
||||||
|
.expect("Ar failed");
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search=native={}", &out_dir);
|
||||||
|
println!("cargo:rustc-link-lib=static=qemu-bridge");
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-lib=rt");
|
||||||
|
println!("cargo:rustc-link-lib=util");
|
||||||
|
println!("cargo:rustc-link-lib=gthread-2.0");
|
||||||
|
println!("cargo:rustc-link-lib=glib-2.0");
|
||||||
|
println!("cargo:rustc-link-lib=stdc++");
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@ -5,7 +5,7 @@ use core::{
|
|||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
mem::{size_of, transmute, MaybeUninit},
|
mem::{size_of, transmute, MaybeUninit},
|
||||||
ptr::copy_nonoverlapping,
|
ptr::{copy_nonoverlapping, null},
|
||||||
};
|
};
|
||||||
use num::Num;
|
use num::Num;
|
||||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
@ -83,6 +83,8 @@ impl MapInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
fn qemu_user_init(argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32;
|
||||||
|
|
||||||
fn libafl_qemu_write_reg(reg: i32, val: *const u8) -> i32;
|
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_read_reg(reg: i32, val: *mut u8) -> i32;
|
||||||
fn libafl_qemu_num_regs() -> i32;
|
fn libafl_qemu_num_regs() -> i32;
|
||||||
@ -137,6 +139,24 @@ extern "C" {
|
|||||||
unsafe extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult;
|
unsafe extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::must_use_candidate, clippy::similar_names)]
|
||||||
|
pub fn init(args: &[String], env: &[(String, String)]) -> i32 {
|
||||||
|
let argv: Vec<*const u8> = args.iter().map(|x| x.as_bytes().as_ptr()).collect();
|
||||||
|
assert!(argv.len() < i32::MAX as usize);
|
||||||
|
let env_strs: Vec<String> = env.iter().map(|(k, v)| format!("{}={}", &k, &v)).collect();
|
||||||
|
let mut envp: Vec<*const u8> = env_strs.iter().map(|x| x.as_bytes().as_ptr()).collect();
|
||||||
|
envp.push(null());
|
||||||
|
#[allow(clippy::cast_possible_wrap)]
|
||||||
|
let argc = argv.len() as i32;
|
||||||
|
unsafe {
|
||||||
|
qemu_user_init(
|
||||||
|
argc,
|
||||||
|
argv.as_ptr() as *const *const u8,
|
||||||
|
envp.as_ptr() as *const *const u8,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GuestMaps {
|
pub struct GuestMaps {
|
||||||
orig_c_iter: *const c_void,
|
orig_c_iter: *const c_void,
|
||||||
c_iter: *const c_void,
|
c_iter: *const c_void,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user