AFLplusplus / LibAFL

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Other
2.03k stars 319 forks source link

Expect mutable reference `&mut I` but found mutable reference `&mut libafl::inputs::BytesInput` #1213

Closed cokeBeer closed 1 year ago

cokeBeer commented 1 year ago

Hi, I am trying to implement a custom mutator like StdSchedulerMutator, which holds a MutatorsTuple. I need to send a new BytesInput to get_and_mutate to mutate it as it was shown in mutate.

/// A [`Mutator`] for myself.
pub struct MyMutator<I, MT, S>
where
    MT: MutatorsTuple<I, S>,
    S: HasRand,
    I: HasBytesVec,
{
    mutations: MT,
    phantom: PhantomData<(I, S)>,
}

impl<I, MT, S> Mutator<I, S> for MyMutator<I, MT, S>
where
    MT: MutatorsTuple<I, S>,
    S: HasRand,
    I: HasBytesVec,
{
    #[inline]
    fn mutate(
        &mut self,
        state: &mut S,
        input: &mut I,
        stage_idx: i32,
    ) -> Result<MutationResult, Error> {
        let idx = state.rand_mut().below(self.mutations.len() as u64).into();
        let sample = BytesInput::new(b"hello".to_vec());
        // error here on sample: Expect mutable reference `&mut I` but found mutable reference `libafl::inputs::BytesInput`
        self.mutations.get_and_mutate(idx, state,&mut sample, stage_idx);
        Ok(MutationResult::Mutated)
    }
}

impl<I, MT, S> MyMutator<I, MT, S>
where
    MT: MutatorsTuple<I, S>,
    S: HasRand,
    I: HasBytesVec,
{
    /// Create a new [`MyMutator`] instance specifying mutations
    pub fn new(mutations: MT) -> Self {
        MyMutator {
            mutations,
            phantom: PhantomData,
        }
    }
}

However, I encountered an error

Expect mutable reference `&mut I` but found mutable reference `libafl::inputs::BytesInput`

How can I fix this ?

wtdcode commented 1 year ago

&mut I infers it accepts any types, though probably including BytesInput, but could be any other type. i.e. you have to tell it you want a mutations which accepts BytesInput, the concrete type instead of a generics type. Or depending on what you would like to build, try to create and add a trait for your I to construct from a &str (I think there should be some?).

cokeBeer commented 1 year ago

@wtdcode Thanks. Actually I am building a mutator taking input bytes as a structure, parsing it and mutating target parts. After changing MT: MutatorsTuple<I, S> to MT: MutatorsTuple<BytesInput, S>, my code can work well.

impl<I, MT, S> MyMutator<I, MT, S>
where
    MT: MutatorsTuple<BytesInput, S>, // here
    S: HasRand,
    I: HasBytesVec,
{
    /// Create a new [`MyMutator`] instance specifying mutations
    pub fn new(mutations: MT) -> Self {
        MyMutator {
            mutations,
            phantom: PhantomData,
        }
    }
}