1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//! This crate provides functionality one may find useful while developing a fuzzer. A recent //! nightly Rust build is required for the specialization feature. //! //! Please consider this crate in "beta" and subject to breaking changes for minor version releases for pre-1.0. //! //! [![crates.io](https://img.shields.io/crates/v/lain.svg)](https://crates.io/crates/lain) //! [![docs.rs](https://docs.rs/lain/badge.svg)](https://docs.rs/lain) //! //! ## Documentation //! //! Please refer to [the wiki](https://github.com/microsoft/lain/wiki) for a high-level overview. //! //! For API documentation: https://docs.rs/lain //! //! ## Installation //! //! Lain requires rust nightly builds for specialization support. //! //! Add the following to your Cargo.toml: //! //! ```toml //! [dependencies] //! lain = "0.2" //! ``` //! //! ## Example Usage //! //! ```rust //! extern crate lain; //! //! use lain::prelude::*; //! use lain::rand; //! use lain::hexdump; //! //! #[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, //! } //! //! fn main() { //! let mut mutator = Mutator::new(rand::thread_rng()); //! //! let mut instance = MyStruct::new_fuzzed(&mut mutator, None); //! //! let mut serialized_data = Vec::with_capacity(instance.serialized_size()); //! instance.binary_serialize::<_, BigEndian>(&mut serialized_data); //! //! println!("{:?}", instance); //! println!("hex representation:\n{}", hexdump(&serialized_data)); //! //! // perform small mutations on the instance //! instance.mutate(&mut mutator, None); //! //! println!("{:?}", instance); //! } //! //! // Output: //! // //! // MyStruct { field_1: 95, field_2: 5, field_3: 14, field_4: 8383, ignored_field: 0 } //! // hex representation: //! // ------00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F //! // 0000: 5F 75 00 00 20 BF 00 00 00 00 00 00 00 00 _u...¿........ //! // MyStruct { field_1: 160, field_2: 5, field_3: 14, field_4: 8383, ignored_field: 0 } //! ``` //! //! A complete example of a fuzzer and its target can be found in the [examples](examples/) //! directory. The server is written in C and takes data over a TCP socket, parses a message, and //! mutates some state. The fuzzer has Rust definitions of the C data structure and will send fully //! mutated messages to the server and utilizes the `Driver` object to manage fuzzer threads and //! state. //! //! # Contributing //! //! This project welcomes contributions and suggestions. Most contributions require you to agree to //! a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, //! grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. //! //! When you submit a pull request, a CLA-bot will automatically determine whether you need to //! provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the //! instructions provided by the bot. You will only need to do this once across all repos using our //! CLA. //! //! This project has adopted the [Microsoft Open Source Code of //! Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of //! Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact //! [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or //! comments. #![feature(specialization)] // TODO: Uncomment once const generics are more stable // #![feature(const_generics)] // #![feature(maybe_uninit)] extern crate num; extern crate num_derive; extern crate num_traits; extern crate self as lain; pub extern crate byteorder; pub extern crate field_offset; pub extern crate lain_derive; pub extern crate lazy_static; pub extern crate rand; pub use lain_derive::*; #[macro_use] pub extern crate log; #[macro_use] extern crate mashup; #[doc(hidden)] pub mod buffer; #[doc(hidden)] pub mod dangerous_numbers; pub mod driver; #[doc(hidden)] pub mod mutatable; pub mod mutator; #[doc(hidden)] pub mod new_fuzzed; pub mod prelude; pub mod traits; pub mod types; pub fn hexdump(data: &[u8]) -> String { let mut ret = "------".to_string(); for i in 0..16 { ret += &format!("{:02X} ", i); } let mut ascii = String::new(); for (i, b) in data.iter().enumerate() { if i % 16 == 0 { ret += &format!("\t{}", ascii); ascii.clear(); ret += &format!("\n{:04X}:", i); } ret += &format!(" {:02X}", b); // this is the printable ASCII range if *b > 0x21 && *b != 0x7f { ascii.push(*b as char); } else { ascii.push('.'); } } if data.len() % 16 != 0 { for _i in 0..16 - (data.len() % 16) { ret += &format!(" "); } } ret += &format!("\t{}", ascii); ascii.clear(); ret }