From ea6ceb994ab975b81aea0daaf64b92a3066c1e8d Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Sat, 14 Sep 2024 03:42:07 +0200 Subject: [PATCH] add TARGET_HASH support --- acat/src/main.rs | 4 ++-- config/src/config.rs | 28 ++++++++++++++++++++++ fuzz_runner/src/nyx/aux_buffer.rs | 2 +- libnyx/src/ffi.rs | 40 +++++++++++++++++++++++++++++++ libnyx/src/lib.rs | 7 ++++++ libnyx/test.c | 14 ++++++++++- libnyx/test.sh | 2 +- 7 files changed, 92 insertions(+), 5 deletions(-) diff --git a/acat/src/main.rs b/acat/src/main.rs index cf5a30f..2b14fe6 100644 --- a/acat/src/main.rs +++ b/acat/src/main.rs @@ -1,4 +1,4 @@ -use fuzz_runner::nyx::aux_buffer; +use fuzz_runner::nyx::aux_buffer::{self, AUX_BUFFER_SIZE}; use clap::{App, Arg, AppSettings}; @@ -135,7 +135,7 @@ fn main() { .read(true) .open(aux_buffer_file) .expect("couldn't open aux buffer file"); - let aux_buffer = aux_buffer::AuxBuffer::new_readonly(aux_shm_f, true); + let aux_buffer = aux_buffer::AuxBuffer::new_readonly(aux_shm_f, true, AUX_BUFFER_SIZE); aux_buffer.validate_header().unwrap(); diff --git a/config/src/config.rs b/config/src/config.rs index d4dc4df..ac2cef6 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -1,3 +1,4 @@ +use std::io::Read; use std::time::Duration; use serde_derive::Serialize; use serde_derive::Deserialize; @@ -140,8 +141,32 @@ pub struct FuzzerConfig { pub write_protected_input_buffer: bool, pub cow_primary_size: Option, pub ipt_filters: [IptFilter;4], + pub target_hash: Option<[u8; 20]> } impl FuzzerConfig{ + + fn load_target_hash(sharedir: &str) -> Option<[u8; 20]> { + let mut file = File::open(format!("{}/TARGET_HASH", sharedir)).ok()?; + let mut content = String::new(); + file.read_to_string(&mut content).ok()?; + + let content = content.trim(); + + if content.len() < 40 { + return None; + } + + let mut bytes = [0u8; 20]; + for i in 0..20 { + match u8::from_str_radix(&content[2 * i..2 * i + 2], 16) { + Ok(byte) => bytes[i] = byte, + Err(_) => return None, + } + } + + Some(bytes) + } + pub fn new_from_loader(sharedir: &str, default: FuzzerConfigLoader, config: FuzzerConfigLoader) -> Self { let seed_path = config.seed_path.or(default.seed_path).unwrap(); @@ -152,6 +177,8 @@ impl FuzzerConfig{ Some(into_absolute_path(&sharedir, seed_path)) }; + let target_hash = Self::load_target_hash(&sharedir); + Self{ spec_path: format!("{}/spec.msgp",sharedir), workdir_path: config.workdir_path.or(default.workdir_path).expect("no workdir_path specified"), @@ -172,6 +199,7 @@ impl FuzzerConfig{ config.ip2, config.ip3, ], + target_hash: target_hash, } } } diff --git a/fuzz_runner/src/nyx/aux_buffer.rs b/fuzz_runner/src/nyx/aux_buffer.rs index 2fe8444..2b911e9 100644 --- a/fuzz_runner/src/nyx/aux_buffer.rs +++ b/fuzz_runner/src/nyx/aux_buffer.rs @@ -20,7 +20,7 @@ pub const NYX_INPUT_WRITE: u8 = 4; pub const NYX_ABORT: u8 = 5; -const AUX_BUFFER_SIZE: usize = 4096; +pub const AUX_BUFFER_SIZE: usize = 4096; const AUX_MAGIC: u64 = 0x54502d554d4551_u64; const QEMU_PT_VERSION: u16 = 3; /* let's start at 1 for the initial version using the aux buffer */ diff --git a/libnyx/src/ffi.rs b/libnyx/src/ffi.rs index eb2f020..976894f 100644 --- a/libnyx/src/ffi.rs +++ b/libnyx/src/ffi.rs @@ -60,6 +60,16 @@ pub extern "C" fn nyx_config_load(sharedir: *const c_char) -> *mut c_void { Box::into_raw(Box::new(cfg)) as *mut c_void } +#[no_mangle] +pub extern "C" fn nyx_config_free(config: * mut c_void) { + if config.is_null() { return; } + let cfg = __nyx_config_check_ptr(config); + + unsafe { + drop(Box::from_raw(cfg)); + } +} + /* Simple debug function to print the entire config object to stdout. */ #[no_mangle] pub extern "C" fn nyx_config_debug(config: * mut c_void) { @@ -203,6 +213,36 @@ pub extern "C" fn nyx_get_bitmap_buffer_size(nyx_process: * mut NyxProcess) -> u } } +#[no_mangle] +pub extern "C" fn nyx_get_target_hash(config: * mut c_void, buffer: *mut u8) -> bool { + let cfg = __nyx_config_check_ptr(config); + + unsafe{ + match NyxConfig::target_hash(&mut *cfg) { + Some(mut x) => { + let val = x.as_mut_ptr(); + std::ptr::copy(val, buffer, 20); + true + }, + None => false, + } + } +} + +#[no_mangle] +pub extern "C" fn nyx_get_target_hash64(config: * mut c_void) -> u64 { + let cfg = __nyx_config_check_ptr(config); + + unsafe{ + match NyxConfig::target_hash(&mut *cfg) { + Some(x) => { + u64::from_be_bytes(x[0..8].try_into().unwrap()) + }, + None => 0, + } + } +} + #[no_mangle] pub extern "C" fn nyx_shutdown(nyx_process: * mut NyxProcess) { unsafe{ diff --git a/libnyx/src/lib.rs b/libnyx/src/lib.rs index 967433f..d6560b3 100644 --- a/libnyx/src/lib.rs +++ b/libnyx/src/lib.rs @@ -134,6 +134,13 @@ impl NyxConfig { return Some(process_cfg.ramfs); } + /* Returns the SHA1 target hash (basically the content of the TARGET_HASH file). + * If the TARGET_HASH file does not exist, this function returns None. + */ + pub fn target_hash(&self) -> Option<[u8; 20]> { + self.config.fuzz.target_hash + } + /* Returns the configured timeout threshold as a std::time::Duration object. */ pub fn timeout(&self) -> std::time::Duration { self.config.fuzz.time_limit diff --git a/libnyx/test.c b/libnyx/test.c index a222e25..3e86f9b 100644 --- a/libnyx/test.c +++ b/libnyx/test.c @@ -9,7 +9,9 @@ #include #include #include - +#include +#include + #ifndef HEXDUMP_COLS #define HEXDUMP_COLS 16 #endif @@ -68,6 +70,15 @@ int main(int argc, char** argv){ void* nyx_config = nyx_config_load("/tmp/nyx_libxml2/"); + uint8_t* target_hash = malloc(20); + memset(target_hash, 0, 20); + if (nyx_get_target_hash(nyx_config, target_hash) == true) { + hexdump(target_hash, 20); + } + + printf("TARGET-HASH: %lx\n", nyx_get_target_hash64(nyx_config)); + free(target_hash); + //nyx_config_debug(nyx_config); nyx_config_set_workdir_path(nyx_config, WORKDIR_PATH); @@ -118,5 +129,6 @@ int main(int argc, char** argv){ if(!nyx_remove_work_dir(WORKDIR_PATH) ){ printf("Error: Failed to remove work dir\n"); } + nyx_config_free(nyx_config); } diff --git a/libnyx/test.sh b/libnyx/test.sh index dde33d5..b4109c6 100644 --- a/libnyx/test.sh +++ b/libnyx/test.sh @@ -1 +1 @@ -cargo build && gcc test.c target/debug/liblibnyx.a -o app -pthread -ldl -lrt && ./app +cargo build && gcc test.c target/debug/liblibnyx.a -o app -pthread -ldl -lrt -lm && ./app