lain/
lib.rs

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