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
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- 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
|
||||
run: command -v llvm-config && clang -v
|
||||
- name: Install cargo-hack
|
||||
@ -90,7 +90,7 @@ jobs:
|
||||
- name: Add nightly rustfmt and clippy
|
||||
run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade
|
||||
- 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
|
||||
run: ./scripts/test_all_fuzzers.sh
|
||||
nostd-build:
|
||||
|
@ -9,9 +9,6 @@ default = ["std"]
|
||||
std = []
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
opt-level = 3
|
||||
debug = true
|
||||
|
||||
[dependencies]
|
||||
@ -19,7 +16,3 @@ libafl = { path = "../../libafl/" }
|
||||
libafl_qemu = { path = "../../libafl_qemu/" }
|
||||
clap = { version = "3.0.0-beta.2", features = ["default"] }
|
||||
nix = "0.20.0"
|
||||
|
||||
[lib]
|
||||
name = "fuzzbench_qemu"
|
||||
crate-type = ["staticlib"]
|
||||
|
@ -44,13 +44,16 @@ use libafl_qemu::{
|
||||
QemuExecutor,
|
||||
};
|
||||
|
||||
/// The fuzzer main (as `no_mangle` C function)
|
||||
#[no_mangle]
|
||||
pub fn libafl_qemu_main() {
|
||||
/// The fuzzer main
|
||||
pub fn main() {
|
||||
// Registry the metadata types used in this fuzzer
|
||||
// Needed only on no_std
|
||||
//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")
|
||||
.version("0.4.0")
|
||||
.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]
|
||||
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() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let out_dir = out_dir.to_string_lossy().to_string();
|
||||
let src_dir = Path::new("src");
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-env-changed=CPU_TARGET");
|
||||
|
||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
|
||||
if target_os == "linux" {
|
||||
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);
|
||||
if target_os != "linux" {
|
||||
return;
|
||||
}
|
||||
|
||||
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,
|
||||
ffi::c_void,
|
||||
mem::{size_of, transmute, MaybeUninit},
|
||||
ptr::copy_nonoverlapping,
|
||||
ptr::{copy_nonoverlapping, null},
|
||||
};
|
||||
use num::Num;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
@ -83,6 +83,8 @@ impl MapInfo {
|
||||
}
|
||||
|
||||
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_read_reg(reg: i32, val: *mut u8) -> 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;
|
||||
}
|
||||
|
||||
#[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 {
|
||||
orig_c_iter: *const c_void,
|
||||
c_iter: *const c_void,
|
||||
|
Loading…
x
Reference in New Issue
Block a user