From 93085782d6db363a8d148c40b82f9574380af53d Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sat, 8 Jun 2024 16:59:49 +0100 Subject: [PATCH] Rename string stages to unicode stages for consistency (#2293) --- fuzzers/baby_fuzzer_unicode/src/main.rs | 16 +++---- libafl/Cargo.toml | 2 +- libafl/src/mutators/mod.rs | 4 +- .../mutators/{string.rs => unicode/mod.rs} | 45 ++++++++++--------- .../{string => unicode}/unicode_categories.rs | 0 libafl/src/stages/mod.rs | 8 ++-- libafl/src/stages/{string.rs => unicode.rs} | 22 ++++----- .../libafl_libfuzzer_runtime/src/lib.rs | 40 ++++++++--------- 8 files changed, 69 insertions(+), 68 deletions(-) rename libafl/src/mutators/{string.rs => unicode/mod.rs} (92%) rename libafl/src/mutators/{string => unicode}/unicode_categories.rs (100%) rename libafl/src/stages/{string.rs => unicode.rs} (86%) diff --git a/fuzzers/baby_fuzzer_unicode/src/main.rs b/fuzzers/baby_fuzzer_unicode/src/main.rs index f9742fea4f..dfc3ac56ab 100644 --- a/fuzzers/baby_fuzzer_unicode/src/main.rs +++ b/fuzzers/baby_fuzzer_unicode/src/main.rs @@ -13,10 +13,10 @@ use libafl::{ feedbacks::{CrashFeedback, MaxMapFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, - mutators::{StdScheduledMutator, StringCategoryRandMutator, StringSubcategoryRandMutator}, + mutators::{StdScheduledMutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator}, observers::StdMapObserver, schedulers::QueueScheduler, - stages::{mutational::StdMutationalStage, StringIdentificationStage}, + stages::{mutational::StdMutationalStage, UnicodeIdentificationStage}, state::StdState, Evaluator, }; @@ -121,14 +121,14 @@ pub fn main() { // Setup a mutational stage with a basic bytes mutator let mutator = StdScheduledMutator::new(tuple_list!( - StringCategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator + UnicodeCategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator )); let mut stages = tuple_list!( - StringIdentificationStage::new(), + UnicodeIdentificationStage::new(), StdMutationalStage::transforming(mutator) ); diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index 10d734a420..5a1b2ceccd 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -85,7 +85,7 @@ concolic_mutation = ["z3"] ## Enable the fancy TuiMonitor for a termanal UI using crossterm tui_monitor = ["ratatui", "crossterm"] -## Enables `StringClassificationStage` and associated mutators, which allow for mutations which preserve the Unicode property data +## Enables `UnicodeClassificationStage` and associated mutators, which allow for mutations which preserve the Unicode property data unicode = ["libafl_bolts/alloc", "ahash/std", "serde/rc", "bitvec"] ## Enable multi-part input formats and mutators diff --git a/libafl/src/mutators/mod.rs b/libafl/src/mutators/mod.rs index d05c40a9f3..7fa46e4b9c 100644 --- a/libafl/src/mutators/mod.rs +++ b/libafl/src/mutators/mod.rs @@ -21,9 +21,9 @@ pub mod tuneable; pub use tuneable::*; #[cfg(feature = "unicode")] -pub mod string; +pub mod unicode; #[cfg(feature = "unicode")] -pub use string::*; +pub use unicode::*; #[cfg(feature = "multipart_inputs")] pub mod multi; diff --git a/libafl/src/mutators/string.rs b/libafl/src/mutators/unicode/mod.rs similarity index 92% rename from libafl/src/mutators/string.rs rename to libafl/src/mutators/unicode/mod.rs index 52745f9eed..137ec86710 100644 --- a/libafl/src/mutators/string.rs +++ b/libafl/src/mutators/unicode/mod.rs @@ -1,4 +1,5 @@ -//! Mutators for preserving string categories, which may be useful for certain targets which are primarily string-oriented. +//! Mutators for preserving unicode string categories, +//! which may be useful for certain targets which are primarily string-oriented. use alloc::{borrow::Cow, vec::Vec}; use core::{ cmp::{Ordering, Reverse}, @@ -14,7 +15,7 @@ use crate::{ stages::{ extract_metadata, mutational::{MutatedTransform, MutatedTransformPost}, - StringIdentificationMetadata, + UnicodeIdentificationMetadata, }, state::{HasCorpus, HasMaxSize, HasRand}, HasMetadata, @@ -27,17 +28,17 @@ use crate::{ pub mod unicode_categories; /// Input which contains the context necessary to perform unicode mutations -pub type UnicodeInput = (BytesInput, StringIdentificationMetadata); +pub type UnicodeInput = (BytesInput, UnicodeIdentificationMetadata); impl MutatedTransform for UnicodeInput where S: HasCorpus + HasTestcase, { - type Post = StringIdentificationMetadata; + type Post = UnicodeIdentificationMetadata; fn try_transform_from(base: &mut Testcase, state: &S) -> Result { let input = base.load_input(state.corpus())?.clone(); - let metadata = base.metadata::().cloned()?; + let metadata = base.metadata::().cloned()?; Ok((input, metadata)) } @@ -46,7 +47,7 @@ where } } -impl MutatedTransformPost for StringIdentificationMetadata +impl MutatedTransformPost for UnicodeIdentificationMetadata where S: HasTestcase, { @@ -64,7 +65,7 @@ const MAX_CHARS: usize = 16; fn choose_start( rand: &mut R, bytes: &[u8], - meta: &StringIdentificationMetadata, + meta: &UnicodeIdentificationMetadata, ) -> Option<(usize, usize)> { let idx = rand.below(bytes.len()); let mut options = Vec::new(); @@ -268,16 +269,16 @@ fn rand_replace_range char>( /// Mutator which randomly replaces a randomly selected range of bytes with bytes that preserve the /// range's category #[derive(Debug, Default)] -pub struct StringCategoryRandMutator; +pub struct UnicodeCategoryRandMutator; -impl Named for StringCategoryRandMutator { +impl Named for UnicodeCategoryRandMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("string-category-rand"); &NAME } } -impl Mutator for StringCategoryRandMutator +impl Mutator for UnicodeCategoryRandMutator where S: HasRand + HasMaxSize, { @@ -327,16 +328,16 @@ where /// Mutator which randomly replaces a randomly selected range of bytes with bytes that preserve the /// range's subcategory #[derive(Debug, Default)] -pub struct StringSubcategoryRandMutator; +pub struct UnicodeSubcategoryRandMutator; -impl Named for StringSubcategoryRandMutator { +impl Named for UnicodeSubcategoryRandMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-rand"); &NAME } } -impl Mutator for StringSubcategoryRandMutator +impl Mutator for UnicodeSubcategoryRandMutator where S: HasRand + HasMaxSize, { @@ -374,16 +375,16 @@ where /// Mutator which randomly replaces a full category-contiguous region of chars with a random token #[derive(Debug, Default)] -pub struct StringCategoryTokenReplaceMutator; +pub struct UnicodeCategoryTokenReplaceMutator; -impl Named for StringCategoryTokenReplaceMutator { +impl Named for UnicodeCategoryTokenReplaceMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("string-category-token-replace"); &NAME } } -impl Mutator for StringCategoryTokenReplaceMutator +impl Mutator for UnicodeCategoryTokenReplaceMutator where S: HasRand + HasMaxSize + HasMetadata, { @@ -434,16 +435,16 @@ where /// Mutator which randomly replaces a full subcategory-contiguous region of chars with a random token #[derive(Debug, Default)] -pub struct StringSubcategoryTokenReplaceMutator; +pub struct UnicodeSubcategoryTokenReplaceMutator; -impl Named for StringSubcategoryTokenReplaceMutator { +impl Named for UnicodeSubcategoryTokenReplaceMutator { fn name(&self) -> &Cow<'static, str> { static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-replace"); &NAME } } -impl Mutator for StringSubcategoryTokenReplaceMutator +impl Mutator for UnicodeSubcategoryTokenReplaceMutator where S: HasRand + HasMaxSize + HasMetadata, { @@ -499,7 +500,7 @@ mod test { use crate::{ corpus::NopCorpus, inputs::{BytesInput, HasMutatorBytes}, - mutators::{Mutator, StringCategoryRandMutator, StringSubcategoryRandMutator}, + mutators::{Mutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator}, stages::extract_metadata, state::StdState, }; @@ -511,7 +512,7 @@ mod test { let hex = "0123456789abcdef0123456789abcdef"; let mut bytes = BytesInput::from(hex.as_bytes()); - let mut mutator = StringCategoryRandMutator; + let mut mutator = UnicodeCategoryRandMutator; let mut state = StdState::new( StdRand::with_seed(0), @@ -543,7 +544,7 @@ mod test { let hex = "0123456789abcdef0123456789abcdef"; let mut bytes = BytesInput::from(hex.as_bytes()); - let mut mutator = StringSubcategoryRandMutator; + let mut mutator = UnicodeSubcategoryRandMutator; let mut state = StdState::new( StdRand::with_seed(0), diff --git a/libafl/src/mutators/string/unicode_categories.rs b/libafl/src/mutators/unicode/unicode_categories.rs similarity index 100% rename from libafl/src/mutators/string/unicode_categories.rs rename to libafl/src/mutators/unicode/unicode_categories.rs diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 674fa7d045..d1d6e2f70e 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -27,8 +27,6 @@ pub use mutational::{MutationalStage, StdMutationalStage}; pub use power::{PowerMutationalStage, StdPowerMutationalStage}; use serde::{Deserialize, Serialize}; pub use stats::AflStatsStage; -#[cfg(feature = "unicode")] -pub use string::*; #[cfg(feature = "std")] pub use sync::*; pub use tmin::{ @@ -37,6 +35,8 @@ pub use tmin::{ pub use tracing::{ShadowTracingStage, TracingStage}; pub use tuneable::*; use tuple_list::NonEmptyTuple; +#[cfg(feature = "unicode")] +pub use unicode::*; use crate::{ corpus::{CorpusId, HasCurrentCorpusId}, @@ -68,12 +68,12 @@ pub mod generation; pub mod logics; pub mod power; pub mod stats; -#[cfg(feature = "unicode")] -pub mod string; #[cfg(feature = "std")] pub mod sync; pub mod tracing; pub mod tuneable; +#[cfg(feature = "unicode")] +pub mod unicode; /// A stage is one step in the fuzzing process. /// Multiple stages will be scheduled one by one for each input. diff --git a/libafl/src/stages/string.rs b/libafl/src/stages/unicode.rs similarity index 86% rename from libafl/src/stages/string.rs rename to libafl/src/stages/unicode.rs index 7b94e6a695..0a661ab306 100644 --- a/libafl/src/stages/string.rs +++ b/libafl/src/stages/unicode.rs @@ -17,13 +17,13 @@ use crate::{ /// Metadata which stores the list of pre-computed string-like ranges in the input #[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct StringIdentificationMetadata { +pub struct UnicodeIdentificationMetadata { ranges: Rc>, } -impl_serdeany!(StringIdentificationMetadata); +impl_serdeany!(UnicodeIdentificationMetadata); -impl StringIdentificationMetadata { +impl UnicodeIdentificationMetadata { /// The list of pre-computed string-like ranges in the input #[must_use] pub fn ranges(&self) -> &Vec<(usize, BitVec)> { @@ -31,7 +31,7 @@ impl StringIdentificationMetadata { } } -pub(crate) fn extract_metadata(bytes: &[u8]) -> StringIdentificationMetadata { +pub(crate) fn extract_metadata(bytes: &[u8]) -> UnicodeIdentificationMetadata { let mut ranges = Vec::new(); if !bytes.is_empty() { @@ -64,24 +64,24 @@ pub(crate) fn extract_metadata(bytes: &[u8]) -> StringIdentificationMetadata { } } - StringIdentificationMetadata { + UnicodeIdentificationMetadata { ranges: Rc::new(ranges), } } /// Stage which identifies potential strings in the provided input #[derive(Debug)] -pub struct StringIdentificationStage { +pub struct UnicodeIdentificationStage { phantom: PhantomData, } -impl Default for StringIdentificationStage { +impl Default for UnicodeIdentificationStage { fn default() -> Self { Self::new() } } -impl StringIdentificationStage { +impl UnicodeIdentificationStage { /// Create a new instance of the string identification stage #[must_use] pub fn new() -> Self { @@ -91,14 +91,14 @@ impl StringIdentificationStage { } } -impl UsesState for StringIdentificationStage +impl UsesState for UnicodeIdentificationStage where S: State, { type State = S; } -impl Stage for StringIdentificationStage +impl Stage for UnicodeIdentificationStage where S: HasTestcase + HasCorpus + State, E: UsesState, @@ -113,7 +113,7 @@ where _manager: &mut EM, ) -> Result<(), Error> { let mut tc = state.current_testcase_mut()?; - if tc.has_metadata::() { + if tc.has_metadata::() { return Ok(()); // skip recompute } diff --git a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs index c86339e576..54aca0134d 100644 --- a/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs +++ b/libafl_libfuzzer/libafl_libfuzzer_runtime/src/lib.rs @@ -155,8 +155,8 @@ macro_rules! fuzz_with { mutators::{ GrimoireExtensionMutator, GrimoireRecursiveReplacementMutator, GrimoireRandomDeleteMutator, GrimoireStringReplacementMutator, havoc_crossover, havoc_mutations, havoc_mutations_no_crossover, - I2SRandReplace, StdScheduledMutator, StringCategoryRandMutator, StringSubcategoryRandMutator, - StringCategoryTokenReplaceMutator, StringSubcategoryTokenReplaceMutator, Tokens, tokens_mutations + I2SRandReplace, StdScheduledMutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator, + UnicodeCategoryTokenReplaceMutator, UnicodeSubcategoryTokenReplaceMutator, Tokens, tokens_mutations }, observers::{stacktrace::BacktraceObserver, TimeObserver, CanTrack}, schedulers::{ @@ -164,7 +164,7 @@ macro_rules! fuzz_with { }, stages::{ CalibrationStage, GeneralizationStage, IfStage, StdMutationalStage, - StdPowerMutationalStage, StringIdentificationStage, TracingStage, + StdPowerMutationalStage, UnicodeIdentificationStage, TracingStage, }, state::{HasCorpus, StdState}, StdFuzzer, @@ -289,29 +289,29 @@ macro_rules! fuzz_with { // Set up a string category analysis stage for unicode mutations let unicode_used = $options.unicode(); - let string_mutator = StdScheduledMutator::new( + let unicode_mutator = StdScheduledMutator::new( tuple_list!( - StringCategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator, - StringSubcategoryRandMutator, + UnicodeCategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator, + UnicodeSubcategoryRandMutator, ) ); - let string_replace_mutator = StdScheduledMutator::new( + let unicode_replace_mutator = StdScheduledMutator::new( tuple_list!( - StringCategoryTokenReplaceMutator, - StringSubcategoryTokenReplaceMutator, - StringSubcategoryTokenReplaceMutator, - StringSubcategoryTokenReplaceMutator, - StringSubcategoryTokenReplaceMutator, + UnicodeCategoryTokenReplaceMutator, + UnicodeSubcategoryTokenReplaceMutator, + UnicodeSubcategoryTokenReplaceMutator, + UnicodeSubcategoryTokenReplaceMutator, + UnicodeSubcategoryTokenReplaceMutator, ) ); - let string_power = StdMutationalStage::transforming(string_mutator); - let string_replace_power = StdMutationalStage::transforming(string_replace_mutator); + let unicode_power = StdMutationalStage::transforming(unicode_mutator); + let unicode_replace_power = StdMutationalStage::transforming(unicode_replace_mutator); - let string_analysis = StringIdentificationStage::new(); - let string_analysis = IfStage::new(|_, _, _, _| Ok((unicode_used && mutator_status.std_mutational).into()), tuple_list!(string_analysis, string_power, string_replace_power)); + let unicode_analysis = UnicodeIdentificationStage::new(); + let unicode_analysis = IfStage::new(|_, _, _, _| Ok((unicode_used && mutator_status.std_mutational).into()), tuple_list!(unicode_analysis, unicode_power, unicode_replace_power)); // Attempt to use tokens from libfuzzer dicts if !state.has_metadata::() { @@ -481,7 +481,7 @@ macro_rules! fuzz_with { calibration, generalization, tracing, - string_analysis, + unicode_analysis, i2s, cm_i2s, std_power,