about summary refs log tree commit diff
path: root/custom_mutators/rust/example_lain
diff options
context:
space:
mode:
authorjulihoh <julihoh@users.noreply.github.com>2021-02-27 15:05:13 +0100
committerGitHub <noreply@github.com>2021-02-27 15:05:13 +0100
commita5da9ce42cab1eab93cf80ca744944ae26e6ab58 (patch)
tree1292da64c63078318d789b2248c247d59173abf2 /custom_mutators/rust/example_lain
parent79e02c2a9b2532624d7f187783ccbe9cbb04ce9b (diff)
downloadafl++-a5da9ce42cab1eab93cf80ca744944ae26e6ab58.tar.gz
custom mutator rust support (#752)
* custom mutator rust support

* clarify how to view documentation for rust mutators

* remove `FuzzResult` hack and clarify lifetimes of CustomMutator::fuzz

* rename TErr associated tyep to Error to be more idiomatic

* fix warnings

* add example for fallible custom mutator

* make Fallible Custom Mutator the default and implement it's handle_err method by default

* rename CustomMutator::handle_err to handle_error

* add example mutator using lain
Diffstat (limited to 'custom_mutators/rust/example_lain')
-rw-r--r--custom_mutators/rust/example_lain/Cargo.toml14
-rw-r--r--custom_mutators/rust/example_lain/rust-toolchain1
-rw-r--r--custom_mutators/rust/example_lain/src/lib.rs60
3 files changed, 75 insertions, 0 deletions
diff --git a/custom_mutators/rust/example_lain/Cargo.toml b/custom_mutators/rust/example_lain/Cargo.toml
new file mode 100644
index 00000000..1f68c7e0
--- /dev/null
+++ b/custom_mutators/rust/example_lain/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "example_lain"
+version = "0.1.0"
+authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+custom_mutator = { path = "../custom_mutator" }
+lain="0.5"
+
+[lib]
+crate-type = ["cdylib"]
\ No newline at end of file
diff --git a/custom_mutators/rust/example_lain/rust-toolchain b/custom_mutators/rust/example_lain/rust-toolchain
new file mode 100644
index 00000000..07ade694
--- /dev/null
+++ b/custom_mutators/rust/example_lain/rust-toolchain
@@ -0,0 +1 @@
+nightly
\ No newline at end of file
diff --git a/custom_mutators/rust/example_lain/src/lib.rs b/custom_mutators/rust/example_lain/src/lib.rs
new file mode 100644
index 00000000..3336e861
--- /dev/null
+++ b/custom_mutators/rust/example_lain/src/lib.rs
@@ -0,0 +1,60 @@
+use custom_mutator::{export_mutator, CustomMutator};
+use lain::{
+    mutator::Mutator,
+    prelude::*,
+    rand::{rngs::StdRng, SeedableRng},
+};
+use std::os::raw::c_uint;
+
+#[derive(Debug, Mutatable, NewFuzzed, BinarySerialize)]
+struct MyStruct {
+    field_1: u8,
+
+    #[lain(bits = 3)]
+    field_2: u8,
+
+    #[lain(bits = 5)]
+    field_3: u8,
+
+    #[lain(min = 5, max = 10000)]
+    field_4: u32,
+
+    #[lain(ignore)]
+    ignored_field: u64,
+}
+
+struct LainMutator {
+    mutator: Mutator<StdRng>,
+    buffer: Vec<u8>,
+}
+
+impl CustomMutator for LainMutator {
+    type Error = ();
+
+    fn init(seed: c_uint) -> Result<Self, ()> {
+        Ok(Self {
+            mutator: Mutator::new(StdRng::seed_from_u64(seed as u64)),
+            buffer: Vec::new(),
+        })
+    }
+
+    fn fuzz<'b, 's: 'b>(
+        &'s mut self,
+        _buffer: &'b mut [u8],
+        _add_buff: Option<&[u8]>,
+        max_size: usize,
+    ) -> Result<Option<&'b [u8]>, ()> {
+        // we just sample an instance of MyStruct, ignoring the current input
+        let instance = MyStruct::new_fuzzed(&mut self.mutator, None);
+        let size = instance.serialized_size();
+        if size > max_size {
+            return Err(());
+        }
+        self.buffer.clear();
+        self.buffer.reserve(size);
+        instance.binary_serialize::<_, BigEndian>(&mut self.buffer);
+        Ok(Some(self.buffer.as_slice()))
+    }
+}
+
+export_mutator!(LainMutator);