Frida various fixes (#436)

* Make drcov post_exec dependent on whether drcov is enabled

* Fix find_smallest_fit algorithm

* Fix missing ?

* fix warnings

* fix

* todo for non-linux/android shadow, clippy

* typo

* removed unsupposted eq

* cleanup, docu

* libafl::Error

* fixed import

Co-authored-by: tokatoka <tokazerkje@outlook.com>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
This commit is contained in:
s1341 2021-12-29 19:47:33 +02:00 committed by GitHub
parent e47c3be3fd
commit b5153cc525
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 48 additions and 32 deletions

View File

@ -110,6 +110,7 @@ struct Opt {
)]
output: PathBuf,
/*
#[structopt(
parse(try_from_str = timeout_from_millis_str),
short,
@ -129,7 +130,7 @@ struct Opt {
multiple = true
)]
tokens: Vec<PathBuf>,
*/
#[structopt(
long,
help = "The configuration this fuzzer runs with, for multiprocessing",

View File

@ -112,11 +112,9 @@ where
println!("spawning on cores: {:?}", self.cores);
#[cfg(feature = "std")]
let stdout_file = if let Some(filename) = self.stdout_file {
Some(File::create(filename).unwrap())
} else {
None
};
let stdout_file = self
.stdout_file
.map(|filename| File::create(filename).unwrap());
// Spawn clients
let mut index = 0_u64;

View File

@ -10,7 +10,7 @@ use backtrace::Backtrace;
use libc::{sysconf, _SC_PAGESIZE};
use rangemap::RangeSet;
use serde::{Deserialize, Serialize};
use std::{ffi::c_void, io};
use std::{collections::BTreeMap, ffi::c_void, io};
use crate::{
asan::errors::{AsanError, AsanErrors},
@ -26,7 +26,7 @@ pub struct Allocator {
pre_allocated_shadow: bool,
allocations: HashMap<usize, AllocationMetadata>,
shadow_pages: RangeSet<usize>,
allocation_queue: HashMap<usize, Vec<AllocationMetadata>>,
allocation_queue: BTreeMap<usize, Vec<AllocationMetadata>>,
largest_allocation: usize,
total_allocation_size: usize,
base_mapping_addr: usize,
@ -118,8 +118,13 @@ impl Allocator {
shadow_bit = try_shadow_bit;
}
}
assert!(shadow_bit != 0);
#[cfg(not(any(
target_os = "linux",
all(target_arch = "aarch64", target_os = "android")
)))]
todo!("Shadow region not yet supported for this platform!");
assert!(shadow_bit != 0);
// attempt to pre-map the entire shadow-memory space
let addr: usize = 1 << shadow_bit;
@ -146,7 +151,7 @@ impl Allocator {
shadow_bit,
allocations: HashMap::new(),
shadow_pages: RangeSet::new(),
allocation_queue: HashMap::new(),
allocation_queue: BTreeMap::new(),
largest_allocation: 0,
total_allocation_size: 0,
base_mapping_addr: addr + addr + addr,
@ -173,15 +178,12 @@ impl Allocator {
}
fn find_smallest_fit(&mut self, size: usize) -> Option<AllocationMetadata> {
let mut current_size = size;
while current_size <= self.largest_allocation {
if self.allocation_queue.contains_key(&current_size) {
if let Some(metadata) = self.allocation_queue.entry(current_size).or_default().pop()
{
for (current_size, list) in &mut self.allocation_queue {
if *current_size >= size {
if let Some(metadata) = list.pop() {
return Some(metadata);
}
}
current_size *= 2;
}
None
}

View File

@ -6,13 +6,10 @@ even if the target would not have crashed under normal conditions.
this helps finding mem errors early.
*/
use frida_gum::NativePointer;
use frida_gum::{ModuleDetails, RangeDetails};
use hashbrown::HashMap;
use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
use backtrace::Backtrace;
use frida_gum::{ModuleDetails, NativePointer, RangeDetails};
use hashbrown::HashMap;
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
use crate::helper::FridaInstrumentationHelper;
@ -182,10 +179,9 @@ impl AsanRuntime {
}
self.hook_functions(_gum);
/*
unsafe {
let mem = self.allocator.alloc(0xac + 2, 8);
unsafe {
mprotect(
(self.shadow_check_func.unwrap() as usize & 0xffffffffffff000) as *mut c_void,
0x1000,
@ -256,6 +252,7 @@ impl AsanRuntime {
}
// assert!((self.shadow_check_func.unwrap())(((mem2 as usize) + 8875) as *const c_void, 4));
}
*/
}
/// Reset all allocations so that they can be reused for new allocation requests.

View File

@ -1,10 +1,11 @@
#[cfg(target_arch = "x86_64")]
use crate::asan::asan_rt::ASAN_SAVE_REGISTER_NAMES;
use backtrace::Backtrace;
use capstone::{arch::BuildsCapstone, Capstone};
use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity};
#[cfg(target_arch = "aarch64")]
use frida_gum::interceptor::Interceptor;
use frida_gum::ModuleDetails;
use libafl::{
bolts::{ownedref::OwnedPtr, tuples::Named},
corpus::Testcase,
@ -20,9 +21,6 @@ use serde::{Deserialize, Serialize};
use std::io::Write;
use termcolor::{Color, ColorSpec, WriteColor};
#[cfg(target_arch = "x86_64")]
use crate::asan::asan_rt::ASAN_SAVE_REGISTER_NAMES;
use crate::{alloc::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, FridaOptions};
#[derive(Debug, Clone, Serialize, Deserialize)]

View File

@ -1,16 +1,24 @@
//! Generates `DrCov` traces
use ahash::AHasher;
use libafl::inputs::{HasTargetBytes, Input};
use libafl::Error;
use libafl::{
inputs::{HasTargetBytes, Input},
Error,
};
use libafl_targets::drcov::{DrCovBasicBlock, DrCovWriter};
use rangemap::RangeMap;
use std::hash::Hasher;
/// Generates `DrCov` traces
#[derive(Clone, Debug)]
pub struct DrCovRuntime {
/// The basic blocks of this execution
pub drcov_basic_blocks: Vec<DrCovBasicBlock>,
/// The memory ragnes of this target
ranges: RangeMap<usize, (u16, String)>,
}
impl DrCovRuntime {
/// Creates a new [`DrCovRuntime`]
#[must_use]
pub fn new() -> Self {
Self {
@ -19,15 +27,19 @@ impl DrCovRuntime {
}
}
/// initializes this runtime wiith the given `ranges`
pub fn init(&mut self, ranges: &RangeMap<usize, (u16, String)>) {
self.ranges = ranges.clone();
}
/// Called before execution, does nothing
#[allow(clippy::unused_self)]
pub fn pre_exec<I: Input + HasTargetBytes>(&mut self, _input: &I) -> Result<(), Error> {
Ok(())
}
/// Called after execution, writes the trace to a unique `DrCov` file for this trace
/// into `./coverage/<trace_hash>.drcov`
pub fn post_exec<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<(), Error> {
let mut hasher = AHasher::new_with_keys(0, 0);
hasher.write(input.target_bytes().as_slice());
@ -39,3 +51,9 @@ impl DrCovRuntime {
Ok(())
}
}
impl Default for DrCovRuntime {
fn default() -> Self {
Self::new()
}
}

View File

@ -55,7 +55,7 @@ where
mgr: &mut EM,
input: &I,
) -> Result<ExitKind, Error> {
self.helper.pre_exec(input);
self.helper.pre_exec(input)?;
if self.helper.stalker_enabled() {
if self.followed {
self.stalker.activate(NativePointer(core::ptr::null_mut()));

View File

@ -125,7 +125,9 @@ impl<'a> FridaHelper<'a> for FridaInstrumentationHelper<'a> {
}
fn post_exec<I: Input + HasTargetBytes>(&mut self, input: &I) -> Result<(), Error> {
self.drcov_runtime.post_exec(input)?;
if self.options().enable_drcov {
self.drcov_runtime.post_exec(input)?;
}
#[cfg(unix)]
if self.options.asan_enabled() {
if self.options.asan_detect_leaks() {