From 21f88b58b58445e2bf9be2636269eab0735a3ee0 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 27 Sep 2021 14:09:15 +0200 Subject: [PATCH] Pylibafl --- Cargo.toml | 1 + bindings/pylibafl/Cargo.toml | 16 ++++++ bindings/pylibafl/src/lib.rs | 17 ++++++ libafl_qemu/Cargo.toml | 6 ++- libafl_qemu/build.rs | 101 ++++++++++++++++++++++++++++++----- libafl_qemu/src/lib.rs | 6 +-- libafl_sugar/Cargo.toml | 6 +-- libafl_sugar/src/lib.rs | 2 +- 8 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 bindings/pylibafl/Cargo.toml create mode 100644 bindings/pylibafl/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 36a0cae884..d54c8ae3be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,4 +28,5 @@ default-members = [ ] exclude = [ "fuzzers", + "bindings", ] diff --git a/bindings/pylibafl/Cargo.toml b/bindings/pylibafl/Cargo.toml new file mode 100644 index 0000000000..e0ec8c8a0e --- /dev/null +++ b/bindings/pylibafl/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "pylibafl" +version = "0.1.0" +edition = "2018" + +[dependencies] +pyo3 = { version = "0.14.3", features = ["extension-module"] } +libafl_qemu = { path = "../../libafl_qemu", version = "0.6", features = ["python"] } +libafl_sugar = { path = "../../libafl_sugar", version = "0.6", features = ["python"] } + +[build-dependencies] +pyo3-build-config = { version = "0.14.5" } + +[lib] +name = "pylibafl" +crate-type = ["cdylib"] diff --git a/bindings/pylibafl/src/lib.rs b/bindings/pylibafl/src/lib.rs new file mode 100644 index 0000000000..8db4e5cf97 --- /dev/null +++ b/bindings/pylibafl/src/lib.rs @@ -0,0 +1,17 @@ +use libafl_sugar; +use libafl_qemu; +use pyo3::prelude::*; + +#[pymodule] +#[pyo3(name = "pylibafl")] +pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> { + let sugar_module = PyModule::new(py, "sugar")?; + libafl_sugar::python_module(py, sugar_module)?; + m.add_submodule(sugar_module)?; + + let qemu_module = PyModule::new(py, "qemu")?; + libafl_qemu::python_module(py, qemu_module)?; + m.add_submodule(qemu_module)?; + + Ok(()) +} diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index 04d294acee..fd67220e66 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["fuzzing", "qemu", "instrumentation"] edition = "2018" [features] -python = ["pyo3"] +python = ["pyo3", "pyo3-build-config"] default = [] [dependencies] @@ -23,11 +23,13 @@ num = "0.4" num_enum = "0.5.1" goblin = "0.4.2" libc = "0.2.97" -pyo3 = { version = "0.14.3", features = ["extension-module"], optional = true } +#pyo3 = { version = "0.14.3", features = ["extension-module"], optional = true } +pyo3 = { version = "0.14.3", optional = true } [build-dependencies] cc = { version = "1.0" } which = "4.1" +pyo3-build-config = { version = "0.14.5", optional = true } [lib] name = "libafl_qemu" diff --git a/libafl_qemu/build.rs b/libafl_qemu/build.rs index ad9f55a94e..69f502758b 100644 --- a/libafl_qemu/build.rs +++ b/libafl_qemu/build.rs @@ -1,5 +1,8 @@ -use std::{env, fs::copy, path::Path, process::Command}; -//use std::fs::read_dir; +#[cfg(not(feature = "python"))] +use std::fs::copy; +#[cfg(feature = "python")] +use std::fs::read_dir; +use std::{env, path::Path, process::Command}; use which::which; const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; @@ -150,19 +153,91 @@ fn main() { //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"); + #[cfg(feature = "python")] + { + 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); + } + } + } + } + } + } - println!( - "cargo:rustc-link-search=native={}", - &target_dir.to_string_lossy().to_string() - ); - println!("cargo:rustc-link-lib=qemu-{}", cpu_target); + for obj in &objects { + println!("cargo:rustc-cdylib-link-arg={}", obj.display()); + } - println!("cargo:rustc-env=LD_LIBRARY_PATH={}", target_dir.display()); + println!("cargo:rustc-cdylib-link-arg=-Wl,--start-group"); + + println!("cargo:rustc-cdylib-link-arg=-Wl,--whole-archive"); + println!( + "cargo:rustc-cdylib-link-arg={}/libhwcore.fa", + build_dir.display() + ); + println!( + "cargo:rustc-cdylib-link-arg={}/libqom.fa", + build_dir.display() + ); + println!("cargo:rustc-cdylib-link-arg=-Wl,--no-whole-archive"); + println!( + "cargo:rustc-cdylib-link-arg={}/libcapstone.a", + build_dir.display() + ); + println!( + "cargo:rustc-cdylib-link-arg={}/libqemuutil.a", + build_dir.display() + ); + println!( + "cargo:rustc-cdylib-link-arg={}/libhwcore.fa", + build_dir.display() + ); + println!( + "cargo:rustc-cdylib-link-arg={}/libqom.fa", + build_dir.display() + ); + + println!("cargo:rustc-cdylib-link-arg=-lrt"); + println!("cargo:rustc-cdylib-link-arg=-lutil"); + println!("cargo:rustc-cdylib-link-arg=-lgthread-2.0"); + println!("cargo:rustc-cdylib-link-arg=-lglib-2.0"); + println!("cargo:rustc-cdylib-link-arg=-lstdc++"); + + println!("cargo:rustc-cdylib-link-arg=-Wl,--end-group"); + } + + #[cfg(not(feature = "python"))] + { + 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()); + } } /* diff --git a/libafl_qemu/src/lib.rs b/libafl_qemu/src/lib.rs index d0c7acdfa2..29012a83f2 100644 --- a/libafl_qemu/src/lib.rs +++ b/libafl_qemu/src/lib.rs @@ -33,14 +33,14 @@ pub fn filter_qemu_args() -> Vec { args } -#[cfg(all(target_od = "linux", feature = "python"))] +#[cfg(all(target_os = "linux", feature = "python"))] use pyo3::prelude::*; -#[cfg(all(target_od = "linux", feature = "python"))] +#[cfg(all(target_os = "linux", feature = "python"))] #[pymodule] #[pyo3(name = "libafl_qemu")] #[allow(clippy::items_after_statements)] -fn python_module(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn python_module(_py: Python, m: &PyModule) -> PyResult<()> { use core::mem::transmute; use pyo3::exceptions::PyValueError; diff --git a/libafl_sugar/Cargo.toml b/libafl_sugar/Cargo.toml index e93b3ed962..2a20ee201e 100644 --- a/libafl_sugar/Cargo.toml +++ b/libafl_sugar/Cargo.toml @@ -16,15 +16,15 @@ python = ["pyo3", "libafl_qemu/python", "pyo3-build-config"] default = [] [build-dependencies] -pyo3-build-config = { version = "0.14.2", optional = true } +pyo3-build-config = { version = "0.14.5", optional = true } [dependencies] libafl = { path = "../libafl", version = "0.6.1" } libafl_targets = { path = "../libafl_targets", version = "0.6.1" } libafl_qemu = { path = "../libafl_qemu", version = "0.6.1" } typed-builder = "0.9.0" # Implement the builder pattern at compiletime -pyo3 = { version = "0.14.5", features = ["extension-module"], optional = true } - +#pyo3 = { version = "0.14.3", features = ["extension-module"], optional = true } +pyo3 = { version = "0.14.3", optional = true } [lib] name = "libafl_sugar" diff --git a/libafl_sugar/src/lib.rs b/libafl_sugar/src/lib.rs index e71c958dc2..d480b5861f 100644 --- a/libafl_sugar/src/lib.rs +++ b/libafl_sugar/src/lib.rs @@ -17,7 +17,7 @@ use pyo3::prelude::*; #[cfg(feature = "python")] #[pymodule] #[pyo3(name = "libafl_sugar")] -fn python_module(py: Python, m: &PyModule) -> PyResult<()> { +pub fn python_module(py: Python, m: &PyModule) -> PyResult<()> { inmemory::pybind::register(py, m)?; #[cfg(target_os = "linux")] {