This commit is contained in:
Andrea Fioraldi 2021-04-02 11:59:38 +02:00
parent 0f17fa3fc9
commit ceea3e0c14
7 changed files with 31 additions and 58 deletions

View File

@ -17,3 +17,8 @@
- [Feedback](./core_concepts/feedback.md) - [Feedback](./core_concepts/feedback.md)
- [Input](./core_concepts/input.md) - [Input](./core_concepts/input.md)
- [Corpus](./core_concepts/corpus.md) - [Corpus](./core_concepts/corpus.md)
- [Generator](./core_concepts/generator.md)
- [Mutator](./core_concepts/mutator.md)
- [Stage](./core_concepts/mutator.md)

View File

@ -1,3 +1,11 @@
# Feedback # Feedback
The Feedback is an entity that classify the outcome of an execution of the program under test as interesting or not.
Tipically, if an exeuction is interesting, the corresponding input used to feed the target program is added to a corpus.
Most of the times, the notion of Feedback is deeply linked to the Observer, but they are different concepts.
The Feedback, in most of the cases, process the information reported by one or more observer to decide if the execution is interesting.
The concept of "interestingness" is abstract, but tipically it is related to a novelty search (i.e. interesting inputs are those that reach a previosly unseen edge in the control flow graph).
As an example, given an Observer that reports all the size of memory allocations, a maximization Feedback can be used to maximize these sizes to sport patological inputs in terms of memory consumption.

View File

@ -0,0 +1 @@
# Generator

View File

@ -1 +1,12 @@
# Input # Input
Formally, the input of a program is the data taken from external sources and that affect the program behaviour.
In our model of an abstarct fuzzer, we define the Input as the internal representation of the program input (or a part of it).
In the straightforward case, the input of the program is a byte array and in fuzzers such as AFL we store an manipulate exaclty these byte arrays.
But it is not always the case. A program can expect inputs that are not byte arrays (e.g. a sequence of syscalls) and the fuzzer does not represent the Input in the same way that the program consume it.
In case of a grammar fuzzer for instance, the Input is generally an Abstract Syntax Tree because it is a data structure that can be easily manipulated while maintaining the validity, but the program expects a byte array as input so, just before the execution, the tree is serialized to a sequence of bytes.

View File

@ -0,0 +1 @@
# Mutator

View File

@ -1,5 +1,9 @@
# Observer # Observer
An Observer, or Observation Channel, is an entity that provide an information related to a single run of the program under test to the fuzzer. An Observer, or Observation Channel, is an entity that provides an information observed during the execution of the program under test to the fuzzer.
The information contained in the Observer is not preserved cross executions.
As an example, the coverage shared map filled during the execution to report the executed edges used by fuzzers such as AFL and HoggFuzz can be considered an Observation Channel.
This information is not preserved accros runs and it is an observation of a dynamic property of the program.

View File

@ -1,57 +0,0 @@
//! A sancov runtime to update a simple u8 map with coverage-information during fuzzing
//#![feature(asm)]
/// The map size used by this instance.
const MAP_SIZE: usize = 65536;
#[no_mangle]
pub static mut __lafl_dummy_map: [u8; MAP_SIZE] = [0; MAP_SIZE];
#[no_mangle]
pub static mut __lafl_edges_map: *mut u8 = unsafe { __lafl_dummy_map.as_ptr() as *mut _ };
#[no_mangle]
pub static mut __lafl_cmp_map: *mut u8 = unsafe { __lafl_dummy_map.as_ptr() as *mut _ };
#[no_mangle]
pub static mut __lafl_max_edges_size: u32 = 0;
/// Called for each branch the target program takes.
#[no_mangle]
#[inline]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard(guard: &u32) {
let ref mut trace_byte = *__lafl_edges_map.offset(*guard as isize);
/* TODO: translate to RUST inline ASM once it's stable (neverzero)
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
asm! volatile( \
"addb $1, (%0, %1, 1)\n" \
"adcb $0, (%0, %1, 1)\n" \
: /* no out */ \
: "r"(afl_area_ptr), "r"(loc) \
: "memory", "eax")
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
*/
// Make sure we wrap to 0, not zero, it's empirically proven to be better for fuzzing.
let added = (*trace_byte as u16) + 1;
*trace_byte = (added as u8) + (added >> 8) as u8;
//*trace_byte = (*trace_byte).wrapping_add(1);
}
/// Called when the target program starts
#[no_mangle]
#[inline]
pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard_init(mut start: *mut u32, stop: *mut u32) {
if start == stop || *start != 0 {
return;
}
__lafl_max_edges_size = __lafl_max_edges_size.wrapping_add(1);
let fresh1 = start;
start = start.offset(1);
*fresh1 = __lafl_max_edges_size & (MAP_SIZE - 1) as u32;
while start < stop {
__lafl_max_edges_size = __lafl_max_edges_size.wrapping_add(1);
*start = __lafl_max_edges_size & (MAP_SIZE - 1) as u32;
start = start.offset(1)
}
}