Disabling qemu dependecies for qemu fullsystem (#737)
* Disabling qemu dependecies by default * Adding full emulation_mode support * Removing usermode from libafl_qemu default features * Fixing refactoring * Fixing typo in systemmode * Fixing clippy:needless-borrow * Mark libafl_load/save_qemu_snapshot as unused + cpu_reset * Fixing clippy::needless-borrow * Fixing needless-borrow yet again * reset_cpu -> cpu_reset * Fixing github workflow yet again * Fixing clippy::uninlined-format-args * Adding current libafl_qemu_bridge Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
parent
5571a03641
commit
cf9c4188c0
2
.github/workflows/build_and_test.yml
vendored
2
.github/workflows/build_and_test.yml
vendored
@ -96,7 +96,7 @@ jobs:
|
|||||||
# Skipping `python` as it has to be built with the `maturin` tool
|
# Skipping `python` as it has to be built with the `maturin` tool
|
||||||
# `agpl`, `nautilus` require nightly
|
# `agpl`, `nautilus` require nightly
|
||||||
# `sancov_pcguard_edges` is tested seperately
|
# `sancov_pcguard_edges` is tested seperately
|
||||||
run: cargo hack check --each-feature --clean-per-run --exclude-features=agpl,nautilus,python,sancov_pcguard_edges,arm,aarch64,i386,be
|
run: cargo hack check --each-feature --clean-per-run --exclude-features=prelude,agpl,nautilus,python,sancov_pcguard_edges,arm,aarch64,i386,be,systemmode --no-dev-deps
|
||||||
- name: Check nightly features
|
- name: Check nightly features
|
||||||
run: cargo +nightly check --features=agpl && cargo +nightly check --features=nautilus
|
run: cargo +nightly check --features=agpl && cargo +nightly check --features=nautilus
|
||||||
- name: Build examples
|
- name: Build examples
|
||||||
|
@ -13,6 +13,6 @@ debug = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../libafl/" }
|
libafl = { path = "../../libafl/" }
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }
|
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] }
|
||||||
clap = { version = "3.2", features = ["default"] }
|
clap = { version = "3.2", features = ["default"] }
|
||||||
nix = "0.25"
|
nix = "0.25"
|
||||||
|
@ -13,6 +13,6 @@ debug = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../libafl/" }
|
libafl = { path = "../../libafl/" }
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }
|
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] }
|
||||||
clap = { version = "3.2", features = ["default"] }
|
clap = { version = "3.2", features = ["default"] }
|
||||||
nix = "0.25"
|
nix = "0.25"
|
||||||
|
@ -16,4 +16,4 @@ debug = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../libafl/" }
|
libafl = { path = "../../libafl/" }
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["usermode", "arm"] }
|
libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "usermode"] }
|
||||||
|
@ -16,4 +16,4 @@ debug = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../libafl/" }
|
libafl = { path = "../../libafl/" }
|
||||||
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }
|
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] }
|
||||||
|
@ -12,7 +12,7 @@ edition = "2021"
|
|||||||
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["usermode", "fork"]
|
default = ["fork"]
|
||||||
python = ["pyo3", "pyo3-build-config"]
|
python = ["pyo3", "pyo3-build-config"]
|
||||||
fork = ["libafl/fork"]
|
fork = ["libafl/fork"]
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ aarch64 = [] # build qemu for aarch64
|
|||||||
be = []
|
be = []
|
||||||
|
|
||||||
usermode = []
|
usermode = []
|
||||||
|
systemmode = []
|
||||||
|
|
||||||
clippy = [] # special feature for clippy, don't use in normal projects§
|
clippy = [] # special feature for clippy, don't use in normal projects§
|
||||||
|
|
||||||
|
@ -3,7 +3,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 = "35d36bf8fa2d483965a57ee0c7d7a997e8798273";
|
const QEMU_REVISION: &str = "ddb71cf43844f8848ae655ca696bdfc3fb7839f1";
|
||||||
|
|
||||||
fn build_dep_check(tools: &[&str]) {
|
fn build_dep_check(tools: &[&str]) {
|
||||||
for tool in tools {
|
for tool in tools {
|
||||||
@ -26,10 +26,25 @@ macro_rules! assert_unique_feature {
|
|||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn build() {
|
pub fn build() {
|
||||||
|
// Make sure that exactly one qemu mode is set
|
||||||
|
assert_unique_feature!("usermode", "systemmode");
|
||||||
|
let emulation_mode = if cfg!(feature = "usermode") {
|
||||||
|
"usermode".to_string()
|
||||||
|
}else if cfg!(feature = "systemmode") {
|
||||||
|
"systemmode".to_string()
|
||||||
|
}else{
|
||||||
|
env::var("EMULATION_MODE").unwrap_or_else(|_| {
|
||||||
|
println!(
|
||||||
|
"cargo:warning=No emulation mode feature enabled or EMULATION_MODE env specified for libafl_qemu, supported: usermode, systemmmode - defaulting to usermode"
|
||||||
|
);
|
||||||
|
"usermode".to_string()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
println!("cargo:rerun-if-changed=src/asan-giovese.c");
|
println!("cargo:rerun-if-changed=src/asan-giovese.c");
|
||||||
println!("cargo:rerun-if-changed=src/asan-giovese.h");
|
println!("cargo:rerun-if-changed=src/asan-giovese.h");
|
||||||
#[cfg(feature = "usermode")]
|
|
||||||
println!("cargo:rerun-if-env-changed=CROSS_CC");
|
println!("cargo:rerun-if-env-changed=CROSS_CC");
|
||||||
|
|
||||||
// Make sure we have at most one architecutre feature set
|
// Make sure we have at most one architecutre feature set
|
||||||
@ -60,7 +75,6 @@ pub fn build() {
|
|||||||
|
|
||||||
let jobs = env::var("NUM_JOBS");
|
let jobs = env::var("NUM_JOBS");
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
|
||||||
let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| {
|
let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| {
|
||||||
println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if the selected cpu target ({cpu_target}) is not the host arch ({}))", env::consts::ARCH);
|
println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if the selected cpu target ({cpu_target}) is not the host arch ({}))", env::consts::ARCH);
|
||||||
"cc".to_owned()
|
"cc".to_owned()
|
||||||
@ -153,20 +167,20 @@ pub fn build() {
|
|||||||
qemu_path
|
qemu_path
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
let build_dir = qemu_path.join("build");
|
||||||
let target_suffix = "linux-user";
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
|
||||||
let target_suffix = "softmmu";
|
|
||||||
|
|
||||||
let build_dir = out_dir_path.join("build");
|
|
||||||
if !build_dir.is_dir() {
|
|
||||||
fs::create_dir_all(&build_dir).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
let target_suffix = if emulation_mode == "usermode" {
|
||||||
let output_lib = build_dir.join(&format!("libqemu-{cpu_target}.so"));
|
"linux-user".to_string()
|
||||||
#[cfg(not(feature = "usermode"))]
|
}else{
|
||||||
let output_lib = build_dir.join(&format!("libqemu-system-{}.so", cpu_target));
|
"softmmu".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
let output_lib = if emulation_mode == "usermode" {
|
||||||
|
build_dir.join(&format!("libqemu-{cpu_target}.so"))
|
||||||
|
}else{
|
||||||
|
build_dir.join(&format!("libqemu-system-{cpu_target}.so"))
|
||||||
|
};
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed={}", output_lib.to_string_lossy());
|
println!("cargo:rerun-if-changed={}", output_lib.to_string_lossy());
|
||||||
|
|
||||||
@ -177,25 +191,134 @@ pub fn build() {
|
|||||||
.arg("distclean")
|
.arg("distclean")
|
||||||
.status(),
|
.status(),
|
||||||
);*/
|
);*/
|
||||||
let configure = qemu_path.join("configure");
|
if emulation_mode == "usermode" {
|
||||||
|
Command::new("./configure")
|
||||||
#[cfg(feature = "usermode")]
|
.current_dir(&qemu_path)
|
||||||
Command::new(configure)
|
|
||||||
.current_dir(&build_dir)
|
|
||||||
//.arg("--as-static-lib")
|
//.arg("--as-static-lib")
|
||||||
.arg("--as-shared-lib")
|
.arg("--as-shared-lib")
|
||||||
.arg(&format!("--target-list={cpu_target}-{target_suffix}"))
|
.arg(&format!("--target-list={cpu_target}-{target_suffix}"))
|
||||||
.args(["--disable-blobs", "--disable-bsd-user", "--disable-fdt"])
|
.args(["--disable-blobs", "--disable-bsd-user", "--disable-fdt", "--disable-system"])
|
||||||
.status()
|
.status()
|
||||||
.expect("Configure failed");
|
.expect("Configure failed");
|
||||||
#[cfg(not(feature = "usermode"))]
|
}else{
|
||||||
Command::new(configure)
|
Command::new("./configure")
|
||||||
.current_dir(&build_dir)
|
.current_dir(&qemu_path)
|
||||||
//.arg("--as-static-lib")
|
//.arg("--as-static-lib")
|
||||||
.arg("--as-shared-lib")
|
.arg("--as-shared-lib")
|
||||||
.arg(&format!("--target-list={}-{}", cpu_target, target_suffix))
|
.arg(&format!("--target-list={cpu_target}-{target_suffix}"))
|
||||||
|
.arg("--enable-slirp=internal")
|
||||||
|
.arg("--enable-fdt=internal")
|
||||||
|
.arg("--audio-drv-list=")
|
||||||
|
.arg("--disable-alsa")
|
||||||
|
.arg("--disable-attr")
|
||||||
|
.arg("--disable-auth-pam")
|
||||||
|
.arg("--disable-dbus-display")
|
||||||
|
.arg("--disable-blobs")
|
||||||
|
.arg("--disable-bochs")
|
||||||
|
.arg("--disable-bpf")
|
||||||
|
.arg("--disable-brlapi")
|
||||||
|
.arg("--disable-bsd-user")
|
||||||
|
.arg("--disable-bzip2")
|
||||||
|
.arg("--disable-cap-ng")
|
||||||
|
.arg("--disable-canokey")
|
||||||
|
.arg("--disable-cloop")
|
||||||
|
.arg("--disable-cocoa")
|
||||||
|
.arg("--disable-coreaudio")
|
||||||
|
.arg("--disable-curl")
|
||||||
|
.arg("--disable-curses")
|
||||||
|
.arg("--disable-dmg")
|
||||||
|
.arg("--disable-docs")
|
||||||
|
.arg("--disable-dsound")
|
||||||
|
.arg("--disable-fuse")
|
||||||
|
.arg("--disable-fuse-lseek")
|
||||||
|
.arg("--disable-gcrypt")
|
||||||
|
.arg("--disable-gettext")
|
||||||
|
.arg("--disable-gio")
|
||||||
|
.arg("--disable-glusterfs")
|
||||||
|
.arg("--disable-gnutls")
|
||||||
|
.arg("--disable-gtk")
|
||||||
|
.arg("--disable-guest-agent")
|
||||||
|
.arg("--disable-guest-agent-msi")
|
||||||
|
.arg("--disable-hax")
|
||||||
|
.arg("--disable-hvf")
|
||||||
|
.arg("--disable-iconv")
|
||||||
|
.arg("--disable-jack")
|
||||||
|
.arg("--disable-keyring")
|
||||||
|
.arg("--disable-kvm")
|
||||||
|
.arg("--disable-libdaxctl")
|
||||||
|
.arg("--disable-libiscsi")
|
||||||
|
.arg("--disable-libnfs")
|
||||||
|
.arg("--disable-libpmem")
|
||||||
|
.arg("--disable-libssh")
|
||||||
|
.arg("--disable-libudev")
|
||||||
|
.arg("--disable-libusb")
|
||||||
|
.arg("--disable-linux-aio")
|
||||||
|
.arg("--disable-linux-io-uring")
|
||||||
|
.arg("--disable-linux-user")
|
||||||
|
.arg("--disable-live-block-migration")
|
||||||
|
.arg("--disable-lzfse")
|
||||||
|
.arg("--disable-lzo")
|
||||||
|
.arg("--disable-l2tpv3")
|
||||||
|
.arg("--disable-malloc-trim")
|
||||||
|
.arg("--disable-mpath")
|
||||||
|
.arg("--disable-multiprocess")
|
||||||
|
.arg("--disable-netmap")
|
||||||
|
.arg("--disable-nettle")
|
||||||
|
.arg("--disable-numa")
|
||||||
|
.arg("--disable-nvmm")
|
||||||
|
.arg("--disable-opengl")
|
||||||
|
.arg("--disable-oss")
|
||||||
|
.arg("--disable-pa")
|
||||||
|
.arg("--disable-parallels")
|
||||||
|
.arg("--disable-plugins")
|
||||||
|
.arg("--disable-png")
|
||||||
|
.arg("--disable-pvrdma")
|
||||||
|
.arg("--disable-qcow1")
|
||||||
|
.arg("--disable-qed")
|
||||||
|
.arg("--disable-qga-vss")
|
||||||
|
.arg("--disable-rbd")
|
||||||
|
.arg("--disable-rdma")
|
||||||
|
.arg("--disable-replication")
|
||||||
|
.arg("--disable-sdl")
|
||||||
|
.arg("--disable-sdl-image")
|
||||||
|
.arg("--disable-seccomp")
|
||||||
|
.arg("--disable-selinux")
|
||||||
|
.arg("--disable-slirp-smbd")
|
||||||
|
.arg("--disable-smartcard")
|
||||||
|
.arg("--disable-snappy")
|
||||||
|
.arg("--disable-sparse")
|
||||||
|
.arg("--disable-spice")
|
||||||
|
.arg("--disable-spice-protocol")
|
||||||
|
.arg("--disable-tools")
|
||||||
|
.arg("--disable-tpm")
|
||||||
|
.arg("--disable-usb-redir")
|
||||||
|
.arg("--disable-user")
|
||||||
|
.arg("--disable-u2f")
|
||||||
|
.arg("--disable-vde")
|
||||||
|
.arg("--disable-vdi")
|
||||||
|
.arg("--disable-vduse-blk-export")
|
||||||
|
.arg("--disable-vhost-crypto")
|
||||||
|
.arg("--disable-vhost-kernel")
|
||||||
|
.arg("--disable-vhost-net")
|
||||||
|
.arg("--disable-vhost-user-blk-server")
|
||||||
|
.arg("--disable-vhost-vdpa")
|
||||||
|
.arg("--disable-virglrenderer")
|
||||||
|
.arg("--disable-virtfs")
|
||||||
|
.arg("--disable-virtiofsd")
|
||||||
|
.arg("--disable-vmnet")
|
||||||
|
.arg("--disable-vnc")
|
||||||
|
.arg("--disable-vnc-jpeg")
|
||||||
|
.arg("--disable-vnc-sasl")
|
||||||
|
.arg("--disable-vte")
|
||||||
|
.arg("--disable-vvfat")
|
||||||
|
.arg("--disable-whpx")
|
||||||
|
.arg("--disable-xen")
|
||||||
|
.arg("--disable-xen-pci-passthrough")
|
||||||
|
.arg("--disable-xkbcommon")
|
||||||
|
.arg("--disable-zstd")
|
||||||
.status()
|
.status()
|
||||||
.expect("Configure failed");
|
.expect("Configure failed");
|
||||||
|
}
|
||||||
if let Ok(j) = jobs {
|
if let Ok(j) = jobs {
|
||||||
Command::new("make")
|
Command::new("make")
|
||||||
.current_dir(&build_dir)
|
.current_dir(&build_dir)
|
||||||
@ -233,7 +356,7 @@ pub fn build() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
if emulation_mode == "usermode" {
|
||||||
Command::new("ld")
|
Command::new("ld")
|
||||||
.current_dir(out_dir_path)
|
.current_dir(out_dir_path)
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
@ -253,12 +376,12 @@ pub fn build() {
|
|||||||
"--dynamic-list={}/plugins/qemu-plugins.symbols",
|
"--dynamic-list={}/plugins/qemu-plugins.symbols",
|
||||||
qemu_path.display()
|
qemu_path.display()
|
||||||
))
|
))
|
||||||
|
.arg("--end-group")
|
||||||
.status()
|
.status()
|
||||||
.expect("Partial linked failure");
|
.expect("Partial linked failure");
|
||||||
|
}else{
|
||||||
#[cfg(not(feature = "usermode"))]
|
|
||||||
Command::new("ld")
|
Command::new("ld")
|
||||||
.current_dir(&out_dir_path)
|
.current_dir(out_dir_path)
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
.arg("libqemu-partially-linked.o")
|
.arg("libqemu-partially-linked.o")
|
||||||
.arg("-r")
|
.arg("-r")
|
||||||
@ -305,12 +428,14 @@ pub fn build() {
|
|||||||
"--dynamic-list={}/plugins/qemu-plugins.symbols",
|
"--dynamic-list={}/plugins/qemu-plugins.symbols",
|
||||||
qemu_path.display()
|
qemu_path.display()
|
||||||
))
|
))
|
||||||
|
.arg("--end-group")
|
||||||
.status()
|
.status()
|
||||||
.expect("Partial linked failure");
|
.expect("Partial linked failure");
|
||||||
|
}
|
||||||
|
|
||||||
Command::new("ar")
|
Command::new("ar")
|
||||||
.current_dir(out_dir_path)
|
.current_dir(out_dir_path)
|
||||||
.arg("crus")
|
.arg("crs")
|
||||||
.arg("libqemu-partially-linked.a")
|
.arg("libqemu-partially-linked.a")
|
||||||
.arg("libqemu-partially-linked.o")
|
.arg("libqemu-partially-linked.o")
|
||||||
.status()
|
.status()
|
||||||
@ -318,26 +443,13 @@ pub fn build() {
|
|||||||
|
|
||||||
println!("cargo:rustc-link-search=native={out_dir}");
|
println!("cargo:rustc-link-search=native={out_dir}");
|
||||||
println!("cargo:rustc-link-lib=static=qemu-partially-linked");
|
println!("cargo:rustc-link-lib=static=qemu-partially-linked");
|
||||||
|
println!("cargo:rustc-link-lib=rt");
|
||||||
#[cfg(not(feature = "usermode"))]
|
println!("cargo:rustc-link-lib=gmodule-2.0");
|
||||||
{
|
println!("cargo:rustc-link-lib=glib-2.0");
|
||||||
println!("cargo:rustc-link-lib=png");
|
println!("cargo:rustc-link-lib=stdc++");
|
||||||
println!("cargo:rustc-link-lib=z");
|
println!("cargo:rustc-link-lib=z");
|
||||||
println!("cargo:rustc-link-lib=gio-2.0");
|
|
||||||
println!("cargo:rustc-link-lib=gobject-2.0");
|
if emulation_mode == "systemmode" {
|
||||||
println!("cargo:rustc-link-lib=ncursesw");
|
|
||||||
println!("cargo:rustc-link-lib=tinfo");
|
|
||||||
println!("cargo:rustc-link-lib=gtk-3");
|
|
||||||
println!("cargo:rustc-link-lib=gdk-3");
|
|
||||||
println!("cargo:rustc-link-lib=pangocairo-1.0");
|
|
||||||
println!("cargo:rustc-link-lib=pango-1.0");
|
|
||||||
println!("cargo:rustc-link-lib=harfbuzz");
|
|
||||||
println!("cargo:rustc-link-lib=atk-1.0");
|
|
||||||
println!("cargo:rustc-link-lib=cairo-gobject");
|
|
||||||
println!("cargo:rustc-link-lib=cairo");
|
|
||||||
println!("cargo:rustc-link-lib=gdk_pixbuf-2.0");
|
|
||||||
println!("cargo:rustc-link-lib=X11");
|
|
||||||
println!("cargo:rustc-link-lib=epoxy");
|
|
||||||
println!("cargo:rustc-link-lib=pixman-1");
|
println!("cargo:rustc-link-lib=pixman-1");
|
||||||
|
|
||||||
fs::create_dir_all(target_dir.join("pc-bios")).unwrap();
|
fs::create_dir_all(target_dir.join("pc-bios")).unwrap();
|
||||||
@ -352,13 +464,6 @@ pub fn build() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("cargo:rustc-link-lib=rt");
|
|
||||||
println!("cargo:rustc-link-lib=gmodule-2.0");
|
|
||||||
println!("cargo:rustc-link-lib=glib-2.0");
|
|
||||||
println!("cargo:rustc-link-lib=stdc++");
|
|
||||||
|
|
||||||
println!("cargo:rustc-link-lib=z");
|
|
||||||
|
|
||||||
/* #[cfg(not(feature = "python"))]
|
/* #[cfg(not(feature = "python"))]
|
||||||
{
|
{
|
||||||
fs::copy(
|
fs::copy(
|
||||||
@ -376,8 +481,7 @@ pub fn build() {
|
|||||||
println!("cargo:rustc-env=LD_LIBRARY_PATH={}", target_dir.display());
|
println!("cargo:rustc-env=LD_LIBRARY_PATH={}", target_dir.display());
|
||||||
} */
|
} */
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
if emulation_mode == "usermode" {
|
||||||
{
|
|
||||||
let qasan_dir = Path::new("libqasan");
|
let qasan_dir = Path::new("libqasan");
|
||||||
let qasan_dir = fs::canonicalize(qasan_dir).unwrap();
|
let qasan_dir = fs::canonicalize(qasan_dir).unwrap();
|
||||||
|
|
||||||
|
@ -130,14 +130,14 @@ where
|
|||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut code = {
|
let mut code = {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts(emu.g2h(pc), 512)
|
std::slice::from_raw_parts(emu.g2h(pc), 512)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
&mut [0; 512]
|
&mut [0; 512]
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
emu.read_mem(pc, code)
|
emu.read_mem(pc, code)
|
||||||
}; // TODO handle faults
|
}; // TODO handle faults
|
||||||
@ -188,11 +188,11 @@ where
|
|||||||
|
|
||||||
iaddr += insn.bytes().len() as GuestAddr;
|
iaddr += insn.bytes().len() as GuestAddr;
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
code = std::slice::from_raw_parts(emu.g2h(iaddr), 512);
|
code = std::slice::from_raw_parts(emu.g2h(iaddr), 512);
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
emu.read_mem(pc, code);
|
emu.read_mem(pc, code);
|
||||||
} // TODO handle faults
|
} // TODO handle faults
|
||||||
|
@ -47,9 +47,19 @@ impl<'a> EasyElf<'a> {
|
|||||||
return if sym.st_value == 0 {
|
return if sym.st_value == 0 {
|
||||||
None
|
None
|
||||||
} else if self.is_pic() {
|
} else if self.is_pic() {
|
||||||
Some(sym.st_value as GuestAddr + load_addr)
|
#[cfg(cpu_target = "arm")]
|
||||||
|
// Required because of arm interworking addresses aka bit(0) for thumb mode
|
||||||
|
let addr = (sym.st_value as GuestAddr + load_addr) & !(0x1 as GuestAddr);
|
||||||
|
#[cfg(not(cpu_target = "arm"))]
|
||||||
|
let addr = sym.st_value as GuestAddr + load_addr;
|
||||||
|
Some(addr)
|
||||||
} else {
|
} else {
|
||||||
Some(sym.st_value as GuestAddr)
|
#[cfg(cpu_target = "arm")]
|
||||||
|
// Required because of arm interworking addresses aka bit(0) for thumb mode
|
||||||
|
let addr = (sym.st_value as GuestAddr) & !(0x1 as GuestAddr);
|
||||||
|
#[cfg(not(cpu_target = "arm"))]
|
||||||
|
let addr = sym.st_value as GuestAddr;
|
||||||
|
Some(addr)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@ use core::{
|
|||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
ptr::{addr_of, addr_of_mut, null},
|
ptr::{addr_of, addr_of_mut, null},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
use core::{mem::MaybeUninit, ptr::copy_nonoverlapping};
|
use core::{mem::MaybeUninit, ptr::copy_nonoverlapping};
|
||||||
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
|
use std::{slice::from_raw_parts, str::from_utf8_unchecked};
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
@ -185,7 +185,7 @@ impl MapInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn qemu_user_init(argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32;
|
fn qemu_user_init(argc: i32, argv: *const *const u8, envp: *const *const u8) -> i32;
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ extern "C" {
|
|||||||
unsafe extern "C" fn(u64, i32, u64, u64, u64, u64, u64, u64, u64, u64) -> u64;
|
unsafe extern "C" fn(u64, i32, u64, u64, u64, u64, u64, u64, u64, u64) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn qemu_init(argc: i32, argv: *const *const u8, envp: *const *const u8);
|
fn qemu_init(argc: i32, argv: *const *const u8, envp: *const *const u8);
|
||||||
|
|
||||||
@ -246,11 +246,12 @@ extern "C" {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
fn libafl_save_qemu_snapshot(name: *const u8);
|
fn libafl_save_qemu_snapshot(name: *const u8);
|
||||||
|
#[allow(unused)]
|
||||||
fn libafl_load_qemu_snapshot(name: *const u8);
|
fn libafl_load_qemu_snapshot(name: *const u8);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
extern "C" fn qemu_cleanup_atexit() {
|
extern "C" fn qemu_cleanup_atexit() {
|
||||||
unsafe {
|
unsafe {
|
||||||
qemu_cleanup();
|
qemu_cleanup();
|
||||||
@ -359,9 +360,11 @@ extern "C" {
|
|||||||
data: *const (),
|
data: *const (),
|
||||||
);
|
);
|
||||||
fn libafl_qemu_gdb_reply(buf: *const u8, len: usize);
|
fn libafl_qemu_gdb_reply(buf: *const u8, len: usize);
|
||||||
|
|
||||||
|
fn cpu_reset(cpu: CPUStatePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[cfg_attr(feature = "python", pyclass(unsendable))]
|
#[cfg_attr(feature = "python", pyclass(unsendable))]
|
||||||
pub struct GuestMaps {
|
pub struct GuestMaps {
|
||||||
orig_c_iter: *const c_void,
|
orig_c_iter: *const c_void,
|
||||||
@ -369,7 +372,7 @@ pub struct GuestMaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Consider a private new only for Emulator
|
// Consider a private new only for Emulator
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
impl GuestMaps {
|
impl GuestMaps {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
@ -383,7 +386,7 @@ impl GuestMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
impl Iterator for GuestMaps {
|
impl Iterator for GuestMaps {
|
||||||
type Item = MapInfo;
|
type Item = MapInfo;
|
||||||
|
|
||||||
@ -404,7 +407,7 @@ impl Iterator for GuestMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "usermode", feature = "python"))]
|
#[cfg(all(emulation_mode = "usermode", feature = "python"))]
|
||||||
#[pyproto]
|
#[pyproto]
|
||||||
impl PyIterProtocol for GuestMaps {
|
impl PyIterProtocol for GuestMaps {
|
||||||
fn __iter__(slf: PyRef<Self>) -> PyRef<Self> {
|
fn __iter__(slf: PyRef<Self>) -> PyRef<Self> {
|
||||||
@ -415,7 +418,7 @@ impl PyIterProtocol for GuestMaps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
impl Drop for GuestMaps {
|
impl Drop for GuestMaps {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -464,13 +467,13 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
||||||
unsafe { (addr as usize + guest_base) as *mut T }
|
unsafe { (addr as usize + guest_base) as *mut T }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
||||||
unsafe { (addr as usize - guest_base) as GuestAddr }
|
unsafe { (addr as usize - guest_base) as GuestAddr }
|
||||||
@ -483,12 +486,12 @@ impl CPU {
|
|||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
||||||
/// This may only be safely used for valid guest addresses!
|
/// This may only be safely used for valid guest addresses!
|
||||||
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
{
|
{
|
||||||
let host_addr = Emulator::new_empty().g2h(addr);
|
let host_addr = Emulator::new_empty().g2h(addr);
|
||||||
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
|
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
cpu_memory_rw_debug(self.ptr, addr, buf.as_ptr() as *mut u8, buf.len() as i32, 1);
|
cpu_memory_rw_debug(self.ptr, addr, buf.as_ptr() as *mut u8, buf.len() as i32, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,12 +502,12 @@ impl CPU {
|
|||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
||||||
/// This may only be safely used for valid guest addresses!
|
/// This may only be safely used for valid guest addresses!
|
||||||
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
|
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
{
|
{
|
||||||
let host_addr = Emulator::new_empty().g2h(addr);
|
let host_addr = Emulator::new_empty().g2h(addr);
|
||||||
copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len());
|
copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len());
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
cpu_memory_rw_debug(self.ptr, addr, buf.as_mut_ptr(), buf.len() as i32, 0);
|
cpu_memory_rw_debug(self.ptr, addr, buf.as_mut_ptr(), buf.len() as i32, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,6 +544,10 @@ impl CPU {
|
|||||||
Ok(val)
|
Ok(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cpu_reset(&self) {
|
||||||
|
unsafe { cpu_reset(self.ptr) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut EMULATOR_IS_INITIALIZED: bool = false;
|
static mut EMULATOR_IS_INITIALIZED: bool = false;
|
||||||
@ -573,13 +580,13 @@ impl Emulator {
|
|||||||
#[allow(clippy::cast_possible_wrap)]
|
#[allow(clippy::cast_possible_wrap)]
|
||||||
let argc = argv.len() as i32;
|
let argc = argv.len() as i32;
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
qemu_user_init(
|
qemu_user_init(
|
||||||
argc,
|
argc,
|
||||||
argv.as_ptr() as *const *const u8,
|
argv.as_ptr() as *const *const u8,
|
||||||
envp.as_ptr() as *const *const u8,
|
envp.as_ptr() as *const *const u8,
|
||||||
);
|
);
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
{
|
{
|
||||||
qemu_init(
|
qemu_init(
|
||||||
argc,
|
argc,
|
||||||
@ -598,7 +605,7 @@ impl Emulator {
|
|||||||
Emulator { _private: () }
|
Emulator { _private: () }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
pub fn start(&self, cpu: &CPU) {
|
pub fn start(&self, cpu: &CPU) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libafl_cpu_thread_fn(cpu.ptr);
|
libafl_cpu_thread_fn(cpu.ptr);
|
||||||
@ -606,7 +613,7 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This function gets the memory mappings from the emulator.
|
/// This function gets the memory mappings from the emulator.
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn mappings(&self) -> GuestMaps {
|
pub fn mappings(&self) -> GuestMaps {
|
||||||
GuestMaps::new()
|
GuestMaps::new()
|
||||||
@ -639,13 +646,13 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
||||||
unsafe { (addr as usize + guest_base) as *mut T }
|
unsafe { (addr as usize + guest_base) as *mut T }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
||||||
unsafe { (addr as usize - guest_base) as GuestAddr }
|
unsafe { (addr as usize - guest_base) as GuestAddr }
|
||||||
@ -713,47 +720,53 @@ impl Emulator {
|
|||||||
/// Should, in general, be safe to call.
|
/// Should, in general, be safe to call.
|
||||||
/// Of course, the emulated target is not contained securely and can corrupt state or interact with the operating system.
|
/// Of course, the emulated target is not contained securely and can corrupt state or interact with the operating system.
|
||||||
pub unsafe fn run(&self) {
|
pub unsafe fn run(&self) {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
libafl_qemu_run();
|
libafl_qemu_run();
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
qemu_main_loop();
|
qemu_main_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn binary_path<'a>(&self) -> &'a str {
|
pub fn binary_path<'a>(&self) -> &'a str {
|
||||||
unsafe { from_utf8_unchecked(from_raw_parts(exec_path, strlen(exec_path))) }
|
unsafe { from_utf8_unchecked(from_raw_parts(exec_path, strlen(exec_path))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn load_addr(&self) -> GuestAddr {
|
pub fn load_addr(&self) -> GuestAddr {
|
||||||
unsafe { libafl_load_addr() as GuestAddr }
|
unsafe { libafl_load_addr() as GuestAddr }
|
||||||
}
|
}
|
||||||
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
|
#[must_use]
|
||||||
|
pub fn load_addr(&self) -> GuestAddr {
|
||||||
|
// Only work if the binary is linked to the correct address and not pie
|
||||||
|
return 0x0 as GuestAddr;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_brk(&self) -> GuestAddr {
|
pub fn get_brk(&self) -> GuestAddr {
|
||||||
unsafe { libafl_get_brk() as GuestAddr }
|
unsafe { libafl_get_brk() as GuestAddr }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_brk(&self, brk: GuestAddr) {
|
pub fn set_brk(&self, brk: GuestAddr) {
|
||||||
unsafe { libafl_set_brk(brk.into()) };
|
unsafe { libafl_set_brk(brk.into()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_mmap_start(&self) -> GuestAddr {
|
pub fn get_mmap_start(&self) -> GuestAddr {
|
||||||
unsafe { mmap_next_start }
|
unsafe { mmap_next_start }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_mmap_start(&self, start: GuestAddr) {
|
pub fn set_mmap_start(&self, start: GuestAddr) {
|
||||||
unsafe { mmap_next_start = start };
|
unsafe { mmap_next_start = start };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
fn mmap(
|
fn mmap(
|
||||||
&self,
|
&self,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
@ -769,7 +782,7 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn map_private(
|
pub fn map_private(
|
||||||
&self,
|
&self,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
@ -781,7 +794,7 @@ impl Emulator {
|
|||||||
.map(|addr| addr as GuestAddr)
|
.map(|addr| addr as GuestAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn map_fixed(
|
pub fn map_fixed(
|
||||||
&self,
|
&self,
|
||||||
addr: GuestAddr,
|
addr: GuestAddr,
|
||||||
@ -798,7 +811,7 @@ impl Emulator {
|
|||||||
.map(|addr| addr as GuestAddr)
|
.map(|addr| addr as GuestAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn mprotect(&self, addr: GuestAddr, size: usize, perms: MmapPerms) -> Result<(), String> {
|
pub fn mprotect(&self, addr: GuestAddr, size: usize, perms: MmapPerms) -> Result<(), String> {
|
||||||
let res = unsafe { target_mprotect(addr.into(), size as u64, perms.into()) };
|
let res = unsafe { target_mprotect(addr.into(), size as u64, perms.into()) };
|
||||||
if res == 0 {
|
if res == 0 {
|
||||||
@ -808,7 +821,7 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn unmap(&self, addr: GuestAddr, size: usize) -> Result<(), String> {
|
pub fn unmap(&self, addr: GuestAddr, size: usize) -> Result<(), String> {
|
||||||
if unsafe { target_munmap(addr.into(), size as u64) } == 0 {
|
if unsafe { target_munmap(addr.into(), size as u64) } == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -883,33 +896,33 @@ impl Emulator {
|
|||||||
unsafe { libafl_add_backdoor_hook(exec, data) };
|
unsafe { libafl_add_backdoor_hook(exec, data) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
pub fn set_vcpu_start(&self, hook: extern "C" fn(cpu: CPU)) {
|
pub fn set_vcpu_start(&self, hook: extern "C" fn(cpu: CPU)) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libafl_start_vcpu = core::mem::transmute(hook);
|
libafl_start_vcpu = core::mem::transmute(hook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_on_thread_hook(&self, hook: extern "C" fn(tid: u32)) {
|
pub fn set_on_thread_hook(&self, hook: extern "C" fn(tid: u32)) {
|
||||||
unsafe {
|
unsafe {
|
||||||
libafl_on_thread_hook = hook;
|
libafl_on_thread_hook = hook;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#[cfg(not(feature = "usermode"))]
|
/*#[cfg(emulation_mode = "systemmode")]
|
||||||
pub fn save_snapshot(&self, name: &str) {
|
pub fn save_snapshot(&self, name: &str) {
|
||||||
let s = CString::new(name).expect("Invalid snapshot name");
|
let s = CString::new(name).expect("Invalid snapshot name");
|
||||||
unsafe { libafl_save_qemu_snapshot(s.as_ptr() as *const _) };
|
unsafe { libafl_save_qemu_snapshot(s.as_ptr() as *const _) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "usermode"))]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
pub fn load_snapshot(&self, name: &str) {
|
pub fn load_snapshot(&self, name: &str) {
|
||||||
let s = CString::new(name).expect("Invalid snapshot name");
|
let s = CString::new(name).expect("Invalid snapshot name");
|
||||||
unsafe { libafl_load_qemu_snapshot(s.as_ptr() as *const _) };
|
unsafe { libafl_load_qemu_snapshot(s.as_ptr() as *const _) };
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_pre_syscall_hook(
|
pub fn set_pre_syscall_hook(
|
||||||
&self,
|
&self,
|
||||||
hook: extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult,
|
hook: extern "C" fn(i32, u64, u64, u64, u64, u64, u64, u64, u64) -> SyscallHookResult,
|
||||||
@ -919,7 +932,7 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn set_post_syscall_hook(
|
pub fn set_post_syscall_hook(
|
||||||
&self,
|
&self,
|
||||||
hook: extern "C" fn(u64, i32, u64, u64, u64, u64, u64, u64, u64, u64) -> u64,
|
hook: extern "C" fn(u64, i32, u64, u64, u64, u64, u64, u64, u64, u64) -> u64,
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
|||||||
enum Hook {
|
enum Hook {
|
||||||
Function(*const c_void),
|
Function(*const c_void),
|
||||||
Closure(FatPtr),
|
Closure(FatPtr),
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
Once(FatPtr),
|
Once(FatPtr),
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
@ -419,9 +419,9 @@ define_cmp_exec_hook!(exec_cmp2_hook_wrapper, 2, u16);
|
|||||||
define_cmp_exec_hook!(exec_cmp4_hook_wrapper, 3, u32);
|
define_cmp_exec_hook!(exec_cmp4_hook_wrapper, 3, u32);
|
||||||
define_cmp_exec_hook!(exec_cmp8_hook_wrapper, 4, u64);
|
define_cmp_exec_hook!(exec_cmp8_hook_wrapper, 4, u64);
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
static mut ON_THREAD_HOOKS: Vec<Hook> = vec![];
|
static mut ON_THREAD_HOOKS: Vec<Hook> = vec![];
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
extern "C" fn on_thread_hooks_wrapper<QT, S>(tid: u32)
|
extern "C" fn on_thread_hooks_wrapper<QT, S>(tid: u32)
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -455,9 +455,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
static mut SYSCALL_HOOKS: Vec<Hook> = vec![];
|
static mut SYSCALL_HOOKS: Vec<Hook> = vec![];
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
extern "C" fn syscall_hooks_wrapper<QT, S>(
|
extern "C" fn syscall_hooks_wrapper<QT, S>(
|
||||||
sys_num: i32,
|
sys_num: i32,
|
||||||
a0: u64,
|
a0: u64,
|
||||||
@ -557,9 +557,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
static mut SYSCALL_POST_HOOKS: Vec<Hook> = vec![];
|
static mut SYSCALL_POST_HOOKS: Vec<Hook> = vec![];
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
extern "C" fn syscall_after_hooks_wrapper<QT, S>(
|
extern "C" fn syscall_after_hooks_wrapper<QT, S>(
|
||||||
result: u64,
|
result: u64,
|
||||||
sys_num: i32,
|
sys_num: i32,
|
||||||
@ -1417,7 +1417,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn thread_creation(&self, hook: fn(&mut Self, Option<&mut S>, tid: u32)) {
|
pub fn thread_creation(&self, hook: fn(&mut Self, Option<&mut S>, tid: u32)) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ON_THREAD_HOOKS.push(Hook::Function(hook as *const libc::c_void));
|
ON_THREAD_HOOKS.push(Hook::Function(hook as *const libc::c_void));
|
||||||
@ -1426,7 +1426,7 @@ where
|
|||||||
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn thread_creation_closure(
|
pub fn thread_creation_closure(
|
||||||
&self,
|
&self,
|
||||||
hook: Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, u32) + 'a>,
|
hook: Box<dyn FnMut(&'a mut Self, Option<&'a mut S>, u32) + 'a>,
|
||||||
@ -1438,7 +1438,7 @@ where
|
|||||||
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub fn thread_creation_once(&self, hook: Box<dyn FnOnce(&mut Self, Option<&mut S>, u32) + 'a>) {
|
pub fn thread_creation_once(&self, hook: Box<dyn FnOnce(&mut Self, Option<&mut S>, u32) + 'a>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
ON_THREAD_HOOKS.push(Hook::Once(transmute(hook)));
|
ON_THREAD_HOOKS.push(Hook::Once(transmute(hook)));
|
||||||
@ -1447,7 +1447,7 @@ where
|
|||||||
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
.set_on_thread_hook(on_thread_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn syscalls(
|
pub fn syscalls(
|
||||||
&self,
|
&self,
|
||||||
@ -1472,7 +1472,7 @@ where
|
|||||||
.set_pre_syscall_hook(syscall_hooks_wrapper::<QT, S>);
|
.set_pre_syscall_hook(syscall_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn syscalls_closure(
|
pub fn syscalls_closure(
|
||||||
&self,
|
&self,
|
||||||
@ -1499,7 +1499,7 @@ where
|
|||||||
.set_pre_syscall_hook(syscall_hooks_wrapper::<QT, S>);
|
.set_pre_syscall_hook(syscall_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn after_syscalls(
|
pub fn after_syscalls(
|
||||||
&self,
|
&self,
|
||||||
@ -1525,7 +1525,7 @@ where
|
|||||||
.set_post_syscall_hook(syscall_after_hooks_wrapper::<QT, S>);
|
.set_post_syscall_hook(syscall_after_hooks_wrapper::<QT, S>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn after_syscalls_closure(
|
pub fn after_syscalls_closure(
|
||||||
&self,
|
&self,
|
||||||
|
@ -50,13 +50,13 @@ pub mod edges;
|
|||||||
pub use edges::QemuEdgeCoverageHelper;
|
pub use edges::QemuEdgeCoverageHelper;
|
||||||
pub mod cmplog;
|
pub mod cmplog;
|
||||||
pub use cmplog::QemuCmpLogHelper;
|
pub use cmplog::QemuCmpLogHelper;
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub mod snapshot;
|
pub mod snapshot;
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub use snapshot::QemuSnapshotHelper;
|
pub use snapshot::QemuSnapshotHelper;
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub mod asan;
|
pub mod asan;
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub use asan::{init_with_asan, QemuAsanHelper};
|
pub use asan::{init_with_asan, QemuAsanHelper};
|
||||||
|
|
||||||
pub mod calls;
|
pub mod calls;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user