|
1 | 1 | use core::fmt::{self, Debug, Formatter}; |
2 | 2 | use std::{ |
| 3 | + any::TypeId, |
3 | 4 | cell::{Ref, RefCell, RefMut}, |
4 | 5 | ffi::CStr, |
5 | 6 | fs::{self, read_to_string}, |
@@ -34,7 +35,7 @@ use crate::cmplog_rt::CmpLogRuntime; |
34 | 35 | use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime}; |
35 | 36 |
|
36 | 37 | /// The Runtime trait |
37 | | -pub trait FridaRuntime: 'static + Debug { |
| 38 | +pub trait FridaRuntime: 'static + Debug + std::any::Any { |
38 | 39 | /// Initialization |
39 | 40 | fn init( |
40 | 41 | &mut self, |
@@ -193,6 +194,67 @@ where |
193 | 194 | } |
194 | 195 | } |
195 | 196 |
|
| 197 | +/// Vector of `FridaRuntime` |
| 198 | +#[derive(Debug)] |
| 199 | +pub struct FridaRuntimeVec(pub Vec<Box<dyn FridaRuntime>>); |
| 200 | + |
| 201 | +impl MatchFirstType for FridaRuntimeVec { |
| 202 | + fn match_first_type<T: 'static>(&self) -> Option<&T> { |
| 203 | + for member in &self.0 { |
| 204 | + if TypeId::of::<T>() == member.type_id() { |
| 205 | + let raw = std::ptr::from_ref::<dyn FridaRuntime>(&**member) as *const T; |
| 206 | + return unsafe { raw.as_ref() }; |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + None |
| 211 | + } |
| 212 | + |
| 213 | + fn match_first_type_mut<T: 'static>(&mut self) -> Option<&mut T> { |
| 214 | + for member in &mut self.0 { |
| 215 | + if TypeId::of::<T>() == member.type_id() { |
| 216 | + let raw = std::ptr::from_mut::<dyn FridaRuntime>(&mut **member) as *mut T; |
| 217 | + return unsafe { raw.as_mut() }; |
| 218 | + } |
| 219 | + } |
| 220 | + |
| 221 | + None |
| 222 | + } |
| 223 | +} |
| 224 | + |
| 225 | +impl FridaRuntimeTuple for FridaRuntimeVec { |
| 226 | + fn init_all( |
| 227 | + &mut self, |
| 228 | + gum: &Gum, |
| 229 | + ranges: &RangeMap<u64, (u16, String)>, |
| 230 | + module_map: &Rc<ModuleMap>, |
| 231 | + ) { |
| 232 | + for runtime in &mut self.0 { |
| 233 | + runtime.init(gum, ranges, module_map); |
| 234 | + } |
| 235 | + } |
| 236 | + |
| 237 | + fn deinit_all(&mut self, gum: &Gum) { |
| 238 | + for runtime in &mut self.0 { |
| 239 | + runtime.deinit(gum); |
| 240 | + } |
| 241 | + } |
| 242 | + |
| 243 | + fn pre_exec_all(&mut self, input_bytes: &[u8]) -> Result<(), Error> { |
| 244 | + for runtime in &mut self.0 { |
| 245 | + runtime.pre_exec(input_bytes)?; |
| 246 | + } |
| 247 | + Ok(()) |
| 248 | + } |
| 249 | + |
| 250 | + fn post_exec_all(&mut self, input_bytes: &[u8]) -> Result<(), Error> { |
| 251 | + for runtime in &mut self.0 { |
| 252 | + runtime.post_exec(input_bytes)?; |
| 253 | + } |
| 254 | + Ok(()) |
| 255 | + } |
| 256 | +} |
| 257 | + |
196 | 258 | /// Represents a range to be skipped for instrumentation |
197 | 259 | #[derive(Debug, Clone, PartialEq, Eq)] |
198 | 260 | pub enum SkipRange { |
|
0 commit comments