Skip to content

Commit fd22932

Browse files
authored
Fix frida libafl after #1523 (#1560)
* Fix frida libpng after PR1523 * fmt * Fix * Clippy
1 parent b3483dd commit fd22932

File tree

3 files changed

+74
-50
lines changed

3 files changed

+74
-50
lines changed

libafl_frida/src/alloc.rs

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl Allocator {
225225

226226
self.allocations
227227
.insert(metadata.address + self.page_size, metadata);
228-
//log::trace!("serving address: {:?}, size: {:x}", address, size);
228+
// log::trace!("serving address: {:?}, size: {:x}", address, size);
229229
address
230230
}
231231

@@ -369,7 +369,7 @@ impl Allocator {
369369
end: usize,
370370
unpoison: bool,
371371
) -> (usize, usize) {
372-
//log::trace!("start: {:x}, end {:x}, size {:x}", start, end, end - start);
372+
// log::trace!("start: {:x}, end {:x}, size {:x}", start, end, end - start);
373373

374374
let shadow_mapping_start = map_to_shadow!(self, start);
375375

@@ -400,7 +400,7 @@ impl Allocator {
400400
self.shadow_pages.insert(shadow_start..shadow_end);
401401
}
402402

403-
//log::trace!("shadow_mapping_start: {:x}, shadow_size: {:x}", shadow_mapping_start, (end - start) / 8);
403+
// log::trace!("shadow_mapping_start: {:x}, shadow_size: {:x}", shadow_mapping_start, (end - start) / 8);
404404
if unpoison {
405405
Self::unpoison(shadow_mapping_start, end - start);
406406
}
@@ -446,31 +446,14 @@ impl Allocator {
446446
true
447447
});
448448
}
449-
}
450-
451-
impl Default for Allocator {
452-
/// Creates a new [`Allocator`] (not supported on this platform!)
453-
#[cfg(not(any(
454-
target_os = "linux",
455-
target_vendor = "apple",
456-
all(target_arch = "aarch64", target_os = "android")
457-
)))]
458-
fn default() -> Self {
459-
todo!("Shadow region not yet supported for this platform!");
460-
}
461-
462-
#[allow(clippy::too_many_lines)]
463-
fn default() -> Self {
464-
let ret = unsafe { sysconf(_SC_PAGESIZE) };
465-
assert!(
466-
ret >= 0,
467-
"Failed to read pagesize {:?}",
468-
io::Error::last_os_error()
469-
);
470449

471-
#[allow(clippy::cast_sign_loss)]
472-
let page_size = ret as usize;
450+
/// Initialize the allocator, making sure a valid shadow bit is selected.
451+
pub fn init(&mut self) {
473452
// probe to find a usable shadow bit:
453+
if self.shadow_bit != 0 {
454+
return;
455+
}
456+
474457
let mut shadow_bit = 0;
475458

476459
let mut occupied_ranges: Vec<(usize, usize)> = vec![];
@@ -487,7 +470,7 @@ impl Default for Allocator {
487470
let start = details.memory_range().base_address().0 as usize;
488471
let end = start + details.memory_range().size();
489472
occupied_ranges.push((start, end));
490-
// log::trace!("{:x} {:x}", start, end);
473+
log::trace!("{:x} {:x}", start, end);
491474
let base: usize = 2;
492475
// On x64, if end > 2**48, then that's in vsyscall or something.
493476
#[cfg(target_arch = "x86_64")]
@@ -523,7 +506,7 @@ impl Default for Allocator {
523506
// check if the proposed shadow bit overlaps with occupied ranges.
524507
for (start, end) in &occupied_ranges {
525508
if (shadow_start <= *end) && (*start <= shadow_end) {
526-
// log::trace!("{:x} {:x}, {:x} {:x}",shadow_start,shadow_end,start,end);
509+
log::trace!("{:x} {:x}, {:x} {:x}", shadow_start, shadow_end, start, end);
527510
log::warn!("shadow_bit {try_shadow_bit:x} is not suitable");
528511
break;
529512
}
@@ -532,7 +515,7 @@ impl Default for Allocator {
532515
if unsafe {
533516
mmap(
534517
NonZeroUsize::new(addr),
535-
NonZeroUsize::new_unchecked(page_size),
518+
NonZeroUsize::new_unchecked(self.page_size),
536519
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
537520
MapFlags::MAP_PRIVATE
538521
| ANONYMOUS_FLAG
@@ -551,7 +534,7 @@ impl Default for Allocator {
551534
}
552535

553536
log::warn!("shadow_bit {shadow_bit:x} is suitable");
554-
assert!(shadow_bit != 0);
537+
// assert!(shadow_bit != 0);
555538
// attempt to pre-map the entire shadow-memory space
556539

557540
let addr: usize = 1 << shadow_bit;
@@ -570,22 +553,53 @@ impl Default for Allocator {
570553
}
571554
.is_ok();
572555

556+
self.pre_allocated_shadow = pre_allocated_shadow;
557+
self.shadow_offset = 1 << shadow_bit;
558+
self.shadow_bit = shadow_bit;
559+
self.base_mapping_addr = addr + addr + addr;
560+
self.current_mapping_addr = addr + addr + addr;
561+
}
562+
}
563+
564+
impl Default for Allocator {
565+
/// Creates a new [`Allocator`] (not supported on this platform!)
566+
#[cfg(not(any(
567+
target_os = "linux",
568+
target_vendor = "apple",
569+
all(target_arch = "aarch64", target_os = "android")
570+
)))]
571+
fn default() -> Self {
572+
todo!("Shadow region not yet supported for this platform!");
573+
}
574+
575+
#[allow(clippy::too_many_lines)]
576+
fn default() -> Self {
577+
let ret = unsafe { sysconf(_SC_PAGESIZE) };
578+
assert!(
579+
ret >= 0,
580+
"Failed to read pagesize {:?}",
581+
io::Error::last_os_error()
582+
);
583+
584+
#[allow(clippy::cast_sign_loss)]
585+
let page_size = ret as usize;
586+
573587
Self {
574588
max_allocation: 1 << 30,
575589
max_allocation_panics: false,
576590
max_total_allocation: 1 << 32,
577591
allocation_backtraces: false,
578592
page_size,
579-
pre_allocated_shadow,
580-
shadow_offset: 1 << shadow_bit,
581-
shadow_bit,
593+
pre_allocated_shadow: false,
594+
shadow_offset: 0,
595+
shadow_bit: 0,
582596
allocations: HashMap::new(),
583597
shadow_pages: RangeSet::new(),
584598
allocation_queue: BTreeMap::new(),
585599
largest_allocation: 0,
586600
total_allocation_size: 0,
587-
base_mapping_addr: addr + addr + addr,
588-
current_mapping_addr: addr + addr + addr,
601+
base_mapping_addr: 0,
602+
current_mapping_addr: 0,
589603
}
590604
}
591605
}

libafl_frida/src/asan/asan_rt.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ impl FridaRuntime for AsanRuntime {
171171
_ranges: &RangeMap<usize, (u16, String)>,
172172
module_map: &Rc<ModuleMap>,
173173
) {
174+
self.allocator.init();
175+
174176
unsafe {
175177
ASAN_ERRORS = Some(AsanErrors::new(self.continue_on_error));
176178
}

libafl_frida/src/helper.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ impl FridaInstrumentationHelperBuilder {
245245
pub fn build<RT: FridaRuntimeTuple>(
246246
self,
247247
gum: &Gum,
248-
mut runtimes: RT,
248+
runtimes: RT,
249249
) -> FridaInstrumentationHelper<'_, RT> {
250250
let Self {
251251
stalker_enabled,
@@ -266,32 +266,40 @@ impl FridaInstrumentationHelperBuilder {
266266
});
267267
let module_map = Rc::new(ModuleMap::new_with_filter(gum, &mut module_filter));
268268

269-
let mut ranges = RangeMap::new();
269+
let ranges = RangeMap::new();
270+
// Wrap ranges and runtimes in reference-counted refcells in order to move
271+
// these references both into the struct that we return and the transformer callback
272+
// that we pass to frida-gum.
273+
//
274+
// These moves MUST occur before the runtimes are init-ed
275+
let ranges = Rc::new(RefCell::new(ranges));
276+
let runtimes = Rc::new(RefCell::new(runtimes));
277+
270278
if stalker_enabled {
271279
for (i, module) in module_map.values().iter().enumerate() {
272280
let range = module.range();
273281
let start = range.base_address().0 as usize;
274-
ranges.insert(start..(start + range.size()), (i as u16, module.path()));
282+
ranges
283+
.borrow_mut()
284+
.insert(start..(start + range.size()), (i as u16, module.path()));
275285
}
276286
for skip in skip_ranges {
277287
match skip {
278-
SkipRange::Absolute(range) => ranges.remove(range),
288+
SkipRange::Absolute(range) => ranges.borrow_mut().remove(range),
279289
SkipRange::ModuleRelative { name, range } => {
280290
let module_details = ModuleDetails::with_name(name).unwrap();
281291
let lib_start = module_details.range().base_address().0 as usize;
282-
ranges.remove((lib_start + range.start)..(lib_start + range.end));
292+
ranges
293+
.borrow_mut()
294+
.remove((lib_start + range.start)..(lib_start + range.end));
283295
}
284296
}
285297
}
286-
runtimes.init_all(gum, &ranges, &module_map);
298+
runtimes
299+
.borrow_mut()
300+
.init_all(gum, &ranges.borrow(), &module_map);
287301
}
288302

289-
// Wrap ranges and runtimes in reference-counted refcells in order to move
290-
// these references both into the struct that we return and the transformer callback
291-
// that we pass to frida-gum.
292-
let ranges = Rc::new(RefCell::new(ranges));
293-
let runtimes = Rc::new(RefCell::new(runtimes));
294-
295303
let transformer = FridaInstrumentationHelper::build_transformer(gum, &ranges, &runtimes);
296304

297305
#[cfg(unix)]
@@ -422,7 +430,7 @@ where
422430
.iter()
423431
.map(PathBuf::from)
424432
.collect::<Vec<_>>();
425-
return FridaInstrumentationHelper::builder()
433+
FridaInstrumentationHelper::builder()
426434
.enable_stalker(options.cmplog || options.asan || !options.disable_coverage)
427435
.disable_excludes(options.disable_excludes)
428436
.instrument_module_if(move |module| pathlist_contains_module(&harness, module))
@@ -435,7 +443,7 @@ where
435443
range: *offset..*offset + 4,
436444
}
437445
}))
438-
.build(gum, runtimes);
446+
.build(gum, runtimes)
439447
}
440448

441449
#[allow(clippy::too_many_lines)]
@@ -487,7 +495,7 @@ where
487495
#[cfg(unix)]
488496
let instr_size = instr.bytes().len();
489497
let address = instr.address();
490-
//log::trace!("block @ {:x} transformed to {:x}", address, output.writer().pc());
498+
// log::trace!("block @ {:x} transformed to {:x}", address, output.writer().pc());
491499

492500
if ranges.borrow().contains_key(&(address as usize)) {
493501
let mut runtimes = (*runtimes).borrow_mut();

0 commit comments

Comments
 (0)