libinject/cmp.rs
1//! **Instrumentation for collecting fine-grained coverage information:** including both i)
2//! _wrapping_ external symbols in the loaded-module space; and ii) individually instrumenting all
3//! CPU-level `CMP` and `TEST` instructions found in the target module.
4
5use enum_iterator::Sequence;
6pub mod cmp;
7pub mod utils;
8pub mod wrappers;
9
10/// **Max number of bytes that coverage information is collected for.** Instrumentation overhead will
11/// be large for long comparisons, and writes to longer spans in the coverage bitmap will result in
12/// a greater number of index clashes (more noise).
13pub const CMP_MAX_LEN: usize = 64;
14
15unsafe extern "C" {
16 /// Index for the thread local storage slot that stores the AFL coverage bitmap and the hashed
17 /// address of the previous basic block.
18 static mut winafl_tls_field: ::std::os::raw::c_int;
19 /// The size of the bb/edge coverage partition of the AFL bitmap.
20 static WINAFL_COV_MAP_SIZE: u32;
21 /// The size of the cmp-coverage partition of the AFL bitmap.
22 static WINAFL_CMP_MAP_SIZE: u32;
23}
24
25/// External symbols that will be wrapped collect byte-by-byte coverage information on comparisons.
26#[derive(Debug, PartialEq, Sequence)]
27pub enum Symbols {
28 MEMCMP,
29 WMEMCMP,
30 STRCMP,
31}
32
33impl Symbols {
34 pub fn to_str(&self) -> &str {
35 match self {
36 Self::MEMCMP => "memcmp",
37 Self::WMEMCMP => "wmemcmp",
38 Self::STRCMP => "strcmp",
39 }
40 }
41
42 /// For each symbol, get a pointer to pre-hook function (a function that the DynamoRIO
43 /// `drwrap` extension can run just _before_ the wrapped symbol runs.
44 pub fn wrapper_fn(
45 &self,
46 ) -> unsafe extern "C" fn(
47 wrapcxt: *mut ::std::os::raw::c_void,
48 user_data: *mut *mut ::std::os::raw::c_void,
49 ) {
50 match self {
51 Self::MEMCMP => wrappers::pre_memcmp,
52 Self::WMEMCMP => wrappers::pre_wmemcmp,
53 Self::STRCMP => wrappers::pre_strcmp,
54 }
55 }
56}