From 7543a54d0de1e64fbdc05e7e15381e6806546843 Mon Sep 17 00:00:00 2001 From: jejuisland87654 Date: Thu, 2 Jan 2025 16:33:47 +0100 Subject: [PATCH] Add dynamic frida runtime list called `FridaRuntimeVec` (#2799) Co-authored-by: Dominik Maier --- libafl_frida/src/helper.rs | 64 +++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/libafl_frida/src/helper.rs b/libafl_frida/src/helper.rs index 98d1fe3599..d6dca76dc5 100644 --- a/libafl_frida/src/helper.rs +++ b/libafl_frida/src/helper.rs @@ -1,5 +1,6 @@ use core::fmt::{self, Debug, Formatter}; use std::{ + any::TypeId, cell::{Ref, RefCell, RefMut}, ffi::CStr, fs::{self, read_to_string}, @@ -34,7 +35,7 @@ use crate::cmplog_rt::CmpLogRuntime; use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime}; /// The Runtime trait -pub trait FridaRuntime: 'static + Debug { +pub trait FridaRuntime: 'static + Debug + std::any::Any { /// Initialization fn init( &mut self, @@ -193,6 +194,67 @@ where } } +/// Vector of `FridaRuntime` +#[derive(Debug)] +pub struct FridaRuntimeVec(pub Vec>); + +impl MatchFirstType for FridaRuntimeVec { + fn match_first_type(&self) -> Option<&T> { + for member in &self.0 { + if TypeId::of::() == member.type_id() { + let raw = std::ptr::from_ref::(&**member) as *const T; + return unsafe { raw.as_ref() }; + } + } + + None + } + + fn match_first_type_mut(&mut self) -> Option<&mut T> { + for member in &mut self.0 { + if TypeId::of::() == member.type_id() { + let raw = std::ptr::from_mut::(&mut **member) as *mut T; + return unsafe { raw.as_mut() }; + } + } + + None + } +} + +impl FridaRuntimeTuple for FridaRuntimeVec { + fn init_all( + &mut self, + gum: &Gum, + ranges: &RangeMap, + module_map: &Rc, + ) { + for runtime in &mut self.0 { + runtime.init(gum, ranges, module_map); + } + } + + fn deinit_all(&mut self, gum: &Gum) { + for runtime in &mut self.0 { + runtime.deinit(gum); + } + } + + fn pre_exec_all(&mut self, input_bytes: &[u8]) -> Result<(), Error> { + for runtime in &mut self.0 { + runtime.pre_exec(input_bytes)?; + } + Ok(()) + } + + fn post_exec_all(&mut self, input_bytes: &[u8]) -> Result<(), Error> { + for runtime in &mut self.0 { + runtime.post_exec(input_bytes)?; + } + Ok(()) + } +} + /// Represents a range to be skipped for instrumentation #[derive(Debug, Clone, PartialEq, Eq)] pub enum SkipRange {