Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Input Types and Mutators for Numeric Types #2760

Merged
merged 35 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
aefb8e3
fixing empty multipart name
riesentoaster Dec 6, 2024
a98c981
fixing clippy
riesentoaster Dec 6, 2024
7acf5a3
Merge branch 'main' into main
riesentoaster Dec 6, 2024
2da6dc5
New rules for the contributing (#2752)
tokatoka Dec 6, 2024
1e571a0
Improve Flexibility of DumpToDiskStage (#2753)
riesentoaster Dec 8, 2024
b4ff6b6
Introduce WrappingMutator
riesentoaster Dec 11, 2024
8af6280
introducing mutators for int types
riesentoaster Dec 11, 2024
9806f3f
Merge branch 'main' into numeric-mutators
riesentoaster Dec 11, 2024
21f9177
fixing no_std
riesentoaster Dec 11, 2024
93b79a6
random fixes
riesentoaster Dec 11, 2024
ac648c4
Add hash derivation for WrappingInput
riesentoaster Dec 11, 2024
aa207ec
Revert fixes that broke things
riesentoaster Dec 11, 2024
39ae88c
Derive Default on WrappingInput
riesentoaster Dec 11, 2024
d54a7d3
Add unit tests
riesentoaster Dec 11, 2024
2ea8132
Fixes according to code review
riesentoaster Dec 12, 2024
0b093e4
introduce mappable ValueInputs
riesentoaster Dec 12, 2024
11981ea
remove unnecessary comments
riesentoaster Dec 12, 2024
0fa453a
Merge branch 'main' into numeric-mutators
riesentoaster Dec 12, 2024
cd5e834
Elide more lifetimes
riesentoaster Dec 12, 2024
90932d1
remove dead code
riesentoaster Dec 13, 2024
4158166
simplify hashing
riesentoaster Dec 13, 2024
829e365
improve docs
riesentoaster Dec 13, 2024
ab97abd
improve randomization
riesentoaster Dec 13, 2024
22a26e0
rename method to align with standard library
riesentoaster Dec 13, 2024
6ba97db
add typedefs for int types for ValueMutRefInput
riesentoaster Dec 13, 2024
25f034d
rename test
riesentoaster Dec 13, 2024
faf127c
add safety notice to trait function
riesentoaster Dec 13, 2024
58cf5d0
improve randomize performance for i128/u128
riesentoaster Dec 15, 2024
d81ee93
rename macro
riesentoaster Dec 15, 2024
56c947a
improve comment
riesentoaster Dec 15, 2024
ed97a73
Merge branch 'main' into numeric-mutators
riesentoaster Dec 15, 2024
ea9e4a1
actually check return values in test
riesentoaster Dec 15, 2024
8b87945
make 128 bit int randomize even more efficient
riesentoaster Dec 15, 2024
7f513d4
shifting signed values
riesentoaster Dec 15, 2024
e77d7a5
Merge branch 'main' into numeric-mutators
domenukk Dec 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 19 additions & 77 deletions libafl/src/inputs/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,20 @@
//! The `BytesInput` is the "normal" input, a map of bytes, that can be sent directly to the client
//! (As opposed to other, more abstract, inputs, like an Grammar-Based AST Input)

use alloc::{borrow::ToOwned, rc::Rc, string::String, vec::Vec};
use core::{
cell::RefCell,
hash::{BuildHasher, Hasher},
use alloc::{
borrow::ToOwned,
rc::Rc,
vec::{self, Vec},
};
#[cfg(feature = "std")]
use std::{fs::File, io::Read, path::Path};
use core::cell::RefCell;

use ahash::RandomState;
#[cfg(feature = "std")]
use libafl_bolts::{fs::write_file_atomic, Error};
use libafl_bolts::{ownedref::OwnedSlice, HasLen};
use serde::{Deserialize, Serialize};

use crate::{
corpus::CorpusId,
inputs::{HasMutatorBytes, HasTargetBytes, Input},
};
use super::WrappingInput;
use crate::inputs::{HasMutatorBytes, HasTargetBytes};

/// A bytes input is the basic input
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct BytesInput {
/// The raw input bytes
pub(crate) bytes: Vec<u8>,
}

impl Input for BytesInput {
#[cfg(feature = "std")]
/// Write this input to the file
fn to_file<P>(&self, path: P) -> Result<(), Error>
where
P: AsRef<Path>,
{
write_file_atomic(path, &self.bytes)
}

/// Load the content of this input from a file
#[cfg(feature = "std")]
fn from_file<P>(path: P) -> Result<Self, Error>
where
P: AsRef<Path>,
{
let mut file = File::open(path)?;
let mut bytes: Vec<u8> = vec![];
file.read_to_end(&mut bytes)?;
Ok(BytesInput::new(bytes))
}

/// Generate a name for this input
fn generate_name(&self, _id: Option<CorpusId>) -> String {
let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher();
hasher.write(self.bytes());
format!("{:016x}", hasher.finish())
}
}
pub type BytesInput = WrappingInput<Vec<u8>>;

/// Rc Ref-cell from Input
impl From<BytesInput> for Rc<RefCell<BytesInput>> {
Expand All @@ -65,57 +24,48 @@ impl From<BytesInput> for Rc<RefCell<BytesInput>> {
}

impl HasMutatorBytes for BytesInput {
#[inline]
fn bytes(&self) -> &[u8] {
&self.bytes
self.as_ref()
}

#[inline]
fn bytes_mut(&mut self) -> &mut [u8] {
&mut self.bytes
self.as_mut()
}

fn resize(&mut self, new_len: usize, value: u8) {
self.bytes.resize(new_len, value);
self.as_mut().resize(new_len, value);
}

fn extend<'a, I: IntoIterator<Item = &'a u8>>(&mut self, iter: I) {
Extend::extend(&mut self.bytes, iter);
self.as_mut().extend(iter);
}

fn splice<R, I>(&mut self, range: R, replace_with: I) -> alloc::vec::Splice<'_, I::IntoIter>
fn splice<R, I>(&mut self, range: R, replace_with: I) -> vec::Splice<'_, I::IntoIter>
where
R: core::ops::RangeBounds<usize>,
I: IntoIterator<Item = u8>,
{
self.bytes.splice(range, replace_with)
self.as_mut().splice(range, replace_with)
}

fn drain<R>(&mut self, range: R) -> alloc::vec::Drain<'_, u8>
fn drain<R>(&mut self, range: R) -> vec::Drain<'_, u8>
where
R: core::ops::RangeBounds<usize>,
{
self.bytes.drain(range)
self.as_mut().drain(range)
}
}

impl HasTargetBytes for BytesInput {
#[inline]
fn target_bytes(&self) -> OwnedSlice<u8> {
OwnedSlice::from(&self.bytes)
OwnedSlice::from(self.as_ref())
}
}

impl HasLen for BytesInput {
#[inline]
fn len(&self) -> usize {
self.bytes.len()
}
}

impl From<Vec<u8>> for BytesInput {
fn from(bytes: Vec<u8>) -> Self {
Self::new(bytes)
self.as_ref().len()
}
}

Expand All @@ -127,14 +77,6 @@ impl From<&[u8]> for BytesInput {

impl From<BytesInput> for Vec<u8> {
fn from(value: BytesInput) -> Vec<u8> {
value.bytes
}
}

impl BytesInput {
/// Creates a new bytes input using the given bytes
#[must_use]
pub const fn new(bytes: Vec<u8>) -> Self {
Self { bytes }
value.inner()
}
}
33 changes: 11 additions & 22 deletions libafl/src/inputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
pub mod bytes;
pub use bytes::BytesInput;

pub mod wrapping;
pub use wrapping::WrappingInput;

pub mod encoded;
pub use encoded::*;

Expand Down Expand Up @@ -210,61 +213,47 @@ where
}

/// A wrapper type that allows us to use mutators for Mutators for `&mut `[`Vec`].
#[derive(Debug)]
pub struct MutVecInput<'a>(&'a mut Vec<u8>);

impl<'a> From<&'a mut Vec<u8>> for MutVecInput<'a> {
fn from(value: &'a mut Vec<u8>) -> Self {
Self(value)
}
}
pub type MutVecInput<'a> = WrappingInput<&'a mut Vec<u8>>;

impl HasLen for MutVecInput<'_> {
fn len(&self) -> usize {
self.0.len()
self.as_ref().len()
}
}

impl HasMutatorBytes for MutVecInput<'_> {
fn bytes(&self) -> &[u8] {
self.0
self.as_ref()
}

fn bytes_mut(&mut self) -> &mut [u8] {
self.0
self.as_mut()
}

fn resize(&mut self, new_len: usize, value: u8) {
self.0.resize(new_len, value);
self.as_mut().resize(new_len, value);
}

fn extend<'b, I: IntoIterator<Item = &'b u8>>(&mut self, iter: I) {
self.0.extend(iter);
self.as_mut().extend(iter);
}

fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter>
where
R: RangeBounds<usize>,
I: IntoIterator<Item = u8>,
{
self.0.splice::<R, I>(range, replace_with)
self.as_mut().splice::<R, I>(range, replace_with)
}

fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
where
R: RangeBounds<usize>,
{
self.0.drain(range)
self.as_mut().drain(range)
}
}

impl MappedInput for MutVecInput<'_> {
type Type<'b>
= MutVecInput<'b>
where
Self: 'b;
}

/// Defines the input type shared across traits of the type.
/// Needed for consistency across HasCorpus/HasSolutions and friends.
pub trait UsesInput {
Expand Down
Loading
Loading