From 5846aa2292fc6e770da06902d687429246c2884d Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 12 Apr 2021 15:26:32 +0200 Subject: [PATCH] cmplog runtime --- libafl_targets/Cargo.toml | 1 + libafl_targets/build.rs | 9 ++ libafl_targets/src/cmplog.c | 185 +++++++++++++++++++++++++++++++++++ libafl_targets/src/cmplog.rs | 36 +++++++ libafl_targets/src/lib.rs | 6 ++ 5 files changed, 237 insertions(+) create mode 100644 libafl_targets/src/cmplog.c create mode 100644 libafl_targets/src/cmplog.rs diff --git a/libafl_targets/Cargo.toml b/libafl_targets/Cargo.toml index 67d4e88e64..d0863696ba 100644 --- a/libafl_targets/Cargo.toml +++ b/libafl_targets/Cargo.toml @@ -10,6 +10,7 @@ pcguard_edges = [] pcguard_hitcounts = [] libfuzzer = [] value_profile = [] +cmplog = [] pcguard = ["pcguard_hitcounts"] [build-dependencies] diff --git a/libafl_targets/build.rs b/libafl_targets/build.rs index 01caad4adf..c8745ca084 100644 --- a/libafl_targets/build.rs +++ b/libafl_targets/build.rs @@ -29,6 +29,15 @@ fn main() { .file(_src_dir.join("value_profile.c")) .compile("value_profile"); } + + #[cfg(feature = "cmplog")] + { + println!("cargo:rerun-if-changed=src/cmplog.c"); + + cc::Build::new() + .file(_src_dir.join("cmplog.c")) + .compile("cmplog"); + } println!("cargo:rustc-link-search=native={}", &out_dir); diff --git a/libafl_targets/src/cmplog.c b/libafl_targets/src/cmplog.c new file mode 100644 index 0000000000..efa7acbbcb --- /dev/null +++ b/libafl_targets/src/cmplog.c @@ -0,0 +1,185 @@ +#include + +#define CMPLOG_MAP_W 65536 +#define CMPLOG_MAP_H 32 + +#define CMPLOG_KIND_INS 0 +#define CMPLOG_KIND_RTN 1 + +typedef struct CmpLogHeader { + uint16_t hits; + uint8_t shape; + uint8_t kind; +} CmpLogHeader; + +typedef struct CmpLogOperands { + uint64_t v0; + uint64_t v1; +} CmpLogOperands; + +typedef struct CmpLogMap { + CmpLogHeader headers[CMPLOG_MAP_W]; + CmpLogOperands operands[CMPLOG_MAP_W][CMPLOG_MAP_H]; +} CmpLogMap; + +extern CmpLogMap libafl_cmplog_map; + +extern uint8_t libafl_cmplog_enabled; + +#if defined(__APPLE__) + #pragma weak __sanitizer_cov_trace_const_cmp1 = __sanitizer_cov_trace_cmp1 + #pragma weak __sanitizer_cov_trace_const_cmp2 = __sanitizer_cov_trace_cmp2 + #pragma weak __sanitizer_cov_trace_const_cmp4 = __sanitizer_cov_trace_cmp4 + #pragma weak __sanitizer_cov_trace_const_cmp8 = __sanitizer_cov_trace_cmp8 +#else +void __sanitizer_cov_trace_const_cmp1(uint8_t arg1, uint8_t arg2) __attribute__((alias("__sanitizer_cov_trace_cmp1"))); +void __sanitizer_cov_trace_const_cmp2(uint16_t arg1, uint16_t arg2) + __attribute__((alias("__sanitizer_cov_trace_cmp2"))); +void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2) + __attribute__((alias("__sanitizer_cov_trace_cmp4"))); +void __sanitizer_cov_trace_const_cmp8(uint64_t arg1, uint64_t arg2) + __attribute__((alias("__sanitizer_cov_trace_cmp8"))); +#endif + +void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) { + + if (!libafl_cmplog_enabled) return; + + uintptr_t k = (uintptr_t)__builtin_return_address(0); + k = (k >> 4) ^ (k << 8); + k &= CMPLOG_MAP_W - 1; + + uint16_t hits; + if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map.headers[k].hits = 1; + libafl_cmplog_map.headers[k].shape = 1; + hits = 0; + } else { + hits = libafl_cmplog_map.headers[k].hits++; + if (libafl_cmplog_map.headers[k].shape < 1) { + libafl_cmplog_map.headers[k].shape = 1; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1; + libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2; + +} + +void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2) { + + if (!libafl_cmplog_enabled) return; + + uintptr_t k = (uintptr_t)__builtin_return_address(0); + k = (k >> 4) ^ (k << 8); + k &= CMPLOG_MAP_W - 1; + + uint16_t hits; + if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map.headers[k].hits = 1; + libafl_cmplog_map.headers[k].shape = 2; + hits = 0; + } else { + hits = libafl_cmplog_map.headers[k].hits++; + if (libafl_cmplog_map.headers[k].shape < 2) { + libafl_cmplog_map.headers[k].shape = 2; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1; + libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2; + +} + +void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) { + + if (!libafl_cmplog_enabled) return; + + uintptr_t k = (uintptr_t)__builtin_return_address(0); + k = (k >> 4) ^ (k << 8); + k &= CMPLOG_MAP_W - 1; + + uint16_t hits; + if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map.headers[k].hits = 1; + libafl_cmplog_map.headers[k].shape = 4; + hits = 0; + } else { + hits = libafl_cmplog_map.headers[k].hits++; + if (libafl_cmplog_map.headers[k].shape < 4) { + libafl_cmplog_map.headers[k].shape = 4; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1; + libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2; +} + +void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) { + + if (!libafl_cmplog_enabled) return; + + uintptr_t k = (uintptr_t)__builtin_return_address(0); + k = (k >> 4) ^ (k << 8); + k &= CMPLOG_MAP_W - 1; + + uint16_t hits; + if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map.headers[k].hits = 1; + libafl_cmplog_map.headers[k].shape = 8; + hits = 0; + } else { + hits = libafl_cmplog_map.headers[k].hits++; + if (libafl_cmplog_map.headers[k].shape < 8) { + libafl_cmplog_map.headers[k].shape = 8; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map.operands[k][hits].v0 = (uint64_t)arg1; + libafl_cmplog_map.operands[k][hits].v1 = (uint64_t)arg2; + +} + +void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { + + if (!libafl_cmplog_enabled) return; + + uint8_t shape = (uint8_t)cases[1]; + if (shape) { + shape /= 8; + } + + for (uint64_t i = 0; i < cases[0]; i++) { + + uintptr_t k = (uintptr_t)__builtin_return_address(0) + i; + k = (k >> 4) ^ (k << 8); + k &= CMPLOG_MAP_W - 1; + + uint16_t hits; + if (libafl_cmplog_map.headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map.headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map.headers[k].hits = 1; + libafl_cmplog_map.headers[k].shape = shape; + hits = 0; + } else { + hits = libafl_cmplog_map.headers[k].hits++; + if (libafl_cmplog_map.headers[k].shape < shape) { + libafl_cmplog_map.headers[k].shape = shape; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map.operands[k][hits].v0 = val; + libafl_cmplog_map.operands[k][hits].v1 = cases[i + 2]; + + } + +} diff --git a/libafl_targets/src/cmplog.rs b/libafl_targets/src/cmplog.rs new file mode 100644 index 0000000000..6731cad6e1 --- /dev/null +++ b/libafl_targets/src/cmplog.rs @@ -0,0 +1,36 @@ +// TODO compile time flag +pub const CMPLOG_MAP_W: usize = 65536; +pub const CMPLOG_MAP_H: usize = 32; +pub const CMPLOG_MAP_SIZE: usize = CMPLOG_MAP_W * CMPLOG_MAP_H; + +pub const CMPLOG_KIND_INS: u8 = 0; +pub const CMPLOG_KIND_RTN: u8 = 1; + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct CmpLogHeader { + hits: u16, + shape: u8, + kind: u8, +} + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct CmpLogOperands(u64, u64); + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct CmpLogMap { + headers: [CmpLogHeader; CMPLOG_MAP_W], + operands: [[CmpLogOperands; CMPLOG_MAP_H]; CMPLOG_MAP_W], +} + +#[no_mangle] +pub static mut libafl_cmplog_map: CmpLogMap = CmpLogMap { headers: [CmpLogHeader {hits: 0, shape: 0, kind: 0}; CMPLOG_MAP_W], operands: [[CmpLogOperands(0, 0); CMPLOG_MAP_H]; CMPLOG_MAP_W] }; + +pub use libafl_cmplog_map as CMPLOG_MAP; + +#[no_mangle] +pub static mut libafl_cmplog_enabled: u8 = 0; + +pub use libafl_cmplog_enabled as CMPLOG_ENABLED; diff --git a/libafl_targets/src/lib.rs b/libafl_targets/src/lib.rs index e8f1636554..bddfde4743 100644 --- a/libafl_targets/src/lib.rs +++ b/libafl_targets/src/lib.rs @@ -14,3 +14,9 @@ pub use value_profile::*; pub mod libfuzzer; #[cfg(feature = "libfuzzer")] pub use libfuzzer::*; + +#[cfg(feature = "cmplog")] +pub mod cmplog; +#[cfg(feature = "cmplog")] +pub use cmplog::*; +