diff --git a/libafl_frida/src/cmplog_rt.rs b/libafl_frida/src/cmplog_rt.rs index aa2f7d9cd9..ac47156ae1 100644 --- a/libafl_frida/src/cmplog_rt.rs +++ b/libafl_frida/src/cmplog_rt.rs @@ -4,29 +4,15 @@ //! related to the input. //! Read the [`RedQueen`](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/) paper for the general concepts. +#[cfg(target_arch = "aarch64")] +use core::ffi::c_void; #[cfg(all(feature = "cmplog", target_arch = "x86_64"))] use std::collections::HashMap; +use std::rc::Rc; use dynasmrt::dynasm; #[cfg(target_arch = "aarch64")] use dynasmrt::{DynasmApi, DynasmLabelApi}; -use libafl::{ - inputs::{HasTargetBytes, Input}, - Error, -}; -use libafl_targets::CMPLOG_MAP_W; -use rangemap::RangeMap; - -use crate::helper::FridaRuntime; -extern "C" { - /// Tracks cmplog instructions - pub fn __libafl_targets_cmplog_instructions(k: u64, shape: u8, arg1: u64, arg2: u64); -} - -#[cfg(target_arch = "aarch64")] -use core::ffi::c_void; -use std::rc::Rc; - use frida_gum::ModuleMap; #[cfg(target_arch = "x86_64")] use frida_gum::{instruction_writer::InstructionWriter, stalker::StalkerOutput}; @@ -41,7 +27,14 @@ use iced_x86::{ BlockEncoder, Code, DecoderOptions, Instruction, InstructionBlock, MemoryOperand, MemorySize, OpKind, Register, }; +use libafl::{ + inputs::{HasTargetBytes, Input}, + Error, +}; +use libafl_targets::{cmps::__libafl_targets_cmplog_instructions, CMPLOG_MAP_W}; +use rangemap::RangeMap; +use crate::helper::FridaRuntime; #[cfg(all(feature = "cmplog", target_arch = "aarch64"))] use crate::utils::{disas_count, writer_register}; @@ -179,7 +172,7 @@ impl CmpLogRuntime { k &= (CMPLOG_MAP_W as u64) - 1; unsafe { - __libafl_targets_cmplog_instructions(k, 8, op1, op2); + __libafl_targets_cmplog_instructions(k as usize, 8, op1, op2); } } @@ -195,7 +188,7 @@ impl CmpLogRuntime { k &= (CMPLOG_MAP_W as u64) - 1; unsafe { - __libafl_targets_cmplog_instructions(k, size, op1, op2); + __libafl_targets_cmplog_instructions(k as usize, size, op1, op2); } } diff --git a/libafl_targets/src/cmplog.c b/libafl_targets/src/cmplog.c index 48e2ff1d9d..9a2b175204 100644 --- a/libafl_targets/src/cmplog.c +++ b/libafl_targets/src/cmplog.c @@ -42,70 +42,10 @@ CmpLogMap *libafl_cmplog_map_ptr = &libafl_cmplog_map; CmpLogMapExtended *libafl_cmplog_map_extended_ptr = &libafl_cmplog_map_extended; #endif -void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape, - uint64_t arg1, uint64_t arg2) { - if (!libafl_cmplog_enabled) { return; } - libafl_cmplog_enabled = false; - - uint16_t hits; - if (libafl_cmplog_map_ptr->headers[k].kind != CMPLOG_KIND_INS) { - libafl_cmplog_map_ptr->headers[k].kind = CMPLOG_KIND_INS; - libafl_cmplog_map_ptr->headers[k].hits = 1; - libafl_cmplog_map_ptr->headers[k].shape = shape; - hits = 0; - } else { - hits = libafl_cmplog_map_ptr->headers[k].hits++; - if (libafl_cmplog_map_ptr->headers[k].shape < shape) { - libafl_cmplog_map_ptr->headers[k].shape = shape; - } - } - - hits &= CMPLOG_MAP_H - 1; - libafl_cmplog_map_ptr->vals.operands[k][hits].v0 = arg1; - libafl_cmplog_map_ptr->vals.operands[k][hits].v1 = arg2; - libafl_cmplog_enabled = true; -} - -void __libafl_targets_cmplog_instructions_extended(uintptr_t k, uint8_t shape, - uint64_t arg1, uint64_t arg2, - uint8_t attr) { -#ifdef CMPLOG_EXTENDED - if (!libafl_cmplog_enabled) { return; } - libafl_cmplog_enabled = false; - - // printf("%ld %ld %ld\n", k, arg1, arg2); - uint16_t hits; - if (libafl_cmplog_map_extended_ptr->headers[k].type != AFL_CMP_TYPE_INS) { - libafl_cmplog_map_extended_ptr->headers[k].type = AFL_CMP_TYPE_INS; - libafl_cmplog_map_extended_ptr->headers[k].hits = 1; - libafl_cmplog_map_extended_ptr->headers[k].shape = shape; - hits = 0; - } else { - hits = libafl_cmplog_map_extended_ptr->headers[k].hits++; - if (libafl_cmplog_map_extended_ptr->headers[k].shape < shape) { - libafl_cmplog_map_extended_ptr->headers[k].shape = shape; - } - } - - hits &= CMPLOG_MAP_H - 1; - libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v0 = arg1; - libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v1 = arg2; - libafl_cmplog_map_extended_ptr->headers[k].attribute = attr; - libafl_cmplog_enabled = true; -#else - // just do nothing - (void)k; - (void)shape; - (void)arg1; - (void)arg2; - (void)attr; -#endif -} - // POSIX shenanigan to see if an area is mapped. // If it is mapped as X-only, we have a problem, so maybe we should add a check // to avoid to call it on .text addresses -static long area_is_valid(const void *ptr, size_t len) { +static inline long area_is_valid(const void *ptr, size_t len) { if (!ptr || __asan_region_is_poisoned(ptr, len)) { return 0; } long valid_len; @@ -148,66 +88,10 @@ static long area_is_valid(const void *ptr, size_t len) { } } -// cmplog routines after area check -void __libafl_targets_cmplog_routines_checked(uintptr_t k, const uint8_t *ptr1, - const uint8_t *ptr2, size_t len) { - libafl_cmplog_enabled = false; - uint32_t hits; - - if (libafl_cmplog_map_ptr->headers[k].kind != CMPLOG_KIND_RTN) { - libafl_cmplog_map_ptr->headers[k].kind = CMPLOG_KIND_RTN; - libafl_cmplog_map_ptr->headers[k].hits = 1; - libafl_cmplog_map_ptr->headers[k].shape = len; - hits = 0; - } else { - hits = libafl_cmplog_map_ptr->headers[k].hits++; - if (libafl_cmplog_map_ptr->headers[k].shape < len) { - libafl_cmplog_map_ptr->headers[k].shape = - len; // TODO; adjust len for AFL++'s cmplog protocol - } - } - - hits &= CMPLOG_MAP_RTN_H - 1; - MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v0, ptr1, len); - MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v1, ptr2, len); - libafl_cmplog_enabled = true; -} - -// cmplog routines after area check -void __libafl_targets_cmplog_routines_checked_extended(uintptr_t k, - const uint8_t *ptr1, - const uint8_t *ptr2, - size_t len) { -#ifdef CMPLOG_EXTENDED - libafl_cmplog_enabled = false; - uint32_t hits; - // printf("RTN: %ld %ld %ld %ld\n", k, *ptr1, *ptr2, len); - if (libafl_cmplog_map_extended_ptr->headers[k].type != AFL_CMP_TYPE_RTN) { - libafl_cmplog_map_extended_ptr->headers[k].type = AFL_CMP_TYPE_RTN; - libafl_cmplog_map_extended_ptr->headers[k].hits = 1; - libafl_cmplog_map_extended_ptr->headers[k].shape = len; - hits = 0; - } else { - hits = libafl_cmplog_map_extended_ptr->headers[k].hits++; - if (libafl_cmplog_map_extended_ptr->headers[k].shape < len) { - libafl_cmplog_map_extended_ptr->headers[k].shape = - len; // TODO; adjust len for AFL++'s cmplog protocol - } - } - - hits &= CMPLOG_MAP_RTN_H - 1; - libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v0_len = len; - libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v1_len = len; - MEMCPY(libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v0, ptr1, len); - MEMCPY(libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v1, ptr2, len); - libafl_cmplog_enabled = true; -#else - // just do nothing - (void)k; - (void)ptr1; - (void)ptr2; - (void)len; -#endif +// Very generic cmplog instructions callback +void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape, + uint64_t arg1, uint64_t arg2) { + cmplog_instructions_checked(k, shape, arg1, arg2); } // Very generic cmplog routines callback @@ -222,7 +106,7 @@ void __libafl_targets_cmplog_routines(uintptr_t k, const uint8_t *ptr1, } int len = MIN(l1, l2); - __libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, len); + cmplog_routines_checked(k, ptr1, ptr2, len); } // cmplog routines but with len specified @@ -235,7 +119,7 @@ void __libafl_targets_cmplog_routines_len(uintptr_t k, const uint8_t *ptr1, return; } - __libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, len); + cmplog_routines_checked(k, ptr1, ptr2, len); } /* CMPLOG Callback for instructions @@ -246,14 +130,14 @@ void __cmplog_ins_hook1_extended(uint8_t arg1, uint8_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, 0, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, 0, arg1, arg2, attr); } void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 1, arg1, arg2); + cmplog_instructions_checked(k, 1, arg1, arg2); } void __cmplog_ins_hook2_extended(uint16_t arg1, uint16_t arg2, uint8_t attr) { @@ -261,14 +145,14 @@ void __cmplog_ins_hook2_extended(uint16_t arg1, uint16_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, 1, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, 1, arg1, arg2, attr); } void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 2, arg1, arg2); + cmplog_instructions_checked(k, 2, arg1, arg2); } void __cmplog_ins_hook4_extended(uint32_t arg1, uint32_t arg2, uint8_t attr) { @@ -276,14 +160,14 @@ void __cmplog_ins_hook4_extended(uint32_t arg1, uint32_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, 3, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, 3, arg1, arg2, attr); } void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 4, arg1, arg2); + cmplog_instructions_checked(k, 4, arg1, arg2); } void __cmplog_ins_hook8_extended(uint64_t arg1, uint64_t arg2, uint8_t attr) { @@ -291,14 +175,14 @@ void __cmplog_ins_hook8_extended(uint64_t arg1, uint64_t arg2, uint8_t attr) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, 7, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, 7, arg1, arg2, attr); } void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 8, arg1, arg2); + cmplog_instructions_checked(k, 8, arg1, arg2); } #if !defined(_WIN32) && defined(__SIZEOF_INT128__) @@ -308,14 +192,14 @@ void __cmplog_ins_hook16_extended(uint128_t arg1, uint128_t arg2, k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, 15, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, 15, arg1, arg2, attr); } void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 16, arg1, arg2); + cmplog_instructions_checked(k, 16, arg1, arg2); } void __cmplog_ins_hookN_extended(uint128_t arg1, uint128_t arg2, uint8_t attr, @@ -324,14 +208,14 @@ void __cmplog_ins_hookN_extended(uint128_t arg1, uint128_t arg2, uint8_t attr, k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions_extended(k, size - 1, arg1, arg2, attr); + cmplog_instructions_extended_checked(k, size - 1, arg1, arg2, attr); } void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t size) { uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, size, arg1, arg2); + cmplog_instructions_checked(k, size, arg1, arg2); } #endif /* @@ -352,7 +236,7 @@ void __cmplog_rtn_hook(const uint8_t *ptr1, const uint8_t *ptr2) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, len); + cmplog_routines_checked(k, ptr1, ptr2, len); } void __cmplog_rtn_hook_extended(const uint8_t *ptr1, const uint8_t *ptr2) { @@ -369,7 +253,7 @@ void __cmplog_rtn_hook_extended(const uint8_t *ptr1, const uint8_t *ptr2) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, ptr1, ptr2, len); + cmplog_routines_checked_extended(k, ptr1, ptr2, len); } void __cmplog_rtn_hook_n(const uint8_t *ptr1, const uint8_t *ptr2, @@ -404,7 +288,7 @@ void __cmplog_rtn_hook_str(const uint8_t *ptr1, uint8_t *ptr2) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, l); + cmplog_routines_checked(k, ptr1, ptr2, l); } /* hook for string functions, eg. strcmp, strcasecmp etc. */ void __cmplog_rtn_hook_str_extended(const uint8_t *ptr1, uint8_t *ptr2) { @@ -426,7 +310,7 @@ void __cmplog_rtn_hook_str_extended(const uint8_t *ptr1, uint8_t *ptr2) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, ptr1, ptr2, l); + cmplog_routines_checked_extended(k, ptr1, ptr2, l); } /* hook for string with length functions, eg. strncmp, strncasecmp etc. @@ -451,7 +335,7 @@ void __cmplog_rtn_hook_strn(uint8_t *ptr1, uint8_t *ptr2, uint64_t len) { k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, l); + cmplog_routines_checked(k, ptr1, ptr2, l); } /* hook for string with length functions, eg. strncmp, strncasecmp etc. Note that we ignore the len parameter and take longer strings if present. */ @@ -476,7 +360,7 @@ void __cmplog_rtn_hook_strn_extended(uint8_t *ptr1, uint8_t *ptr2, k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, ptr1, ptr2, l); + cmplog_routines_checked_extended(k, ptr1, ptr2, l); } // gcc libstdc++ @@ -525,7 +409,7 @@ void __cmplog_rtn_gcc_stdstring_cstring(const uint8_t *stdstring, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, string_ptr, cstring, len); + cmplog_routines_checked(k, string_ptr, cstring, len); } void __cmplog_rtn_gcc_stdstring_cstring_extended(const uint8_t *stdstring, const uint8_t *cstring) { @@ -546,8 +430,7 @@ void __cmplog_rtn_gcc_stdstring_cstring_extended(const uint8_t *stdstring, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, string_ptr, cstring, - len); + cmplog_routines_checked_extended(k, string_ptr, cstring, len); } void __cmplog_rtn_gcc_stdstring_stdstring(const uint8_t *stdstring1, @@ -570,7 +453,7 @@ void __cmplog_rtn_gcc_stdstring_stdstring(const uint8_t *stdstring1, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, string_ptr1, string_ptr2, len); + cmplog_routines_checked(k, string_ptr1, string_ptr2, len); } void __cmplog_rtn_gcc_stdstring_stdstring_extended(const uint8_t *stdstring1, const uint8_t *stdstring2) { @@ -592,8 +475,7 @@ void __cmplog_rtn_gcc_stdstring_stdstring_extended(const uint8_t *stdstring1, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, - len); + cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, len); } void __cmplog_rtn_llvm_stdstring_cstring(const uint8_t *stdstring, @@ -614,7 +496,7 @@ void __cmplog_rtn_llvm_stdstring_cstring(const uint8_t *stdstring, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, string_ptr, cstring, len); + cmplog_routines_checked(k, string_ptr, cstring, len); } void __cmplog_rtn_llvm_stdstring_cstring_extended(const uint8_t *stdstring, const uint8_t *cstring) { @@ -634,8 +516,7 @@ void __cmplog_rtn_llvm_stdstring_cstring_extended(const uint8_t *stdstring, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, string_ptr, cstring, - len); + cmplog_routines_checked_extended(k, string_ptr, cstring, len); } void __cmplog_rtn_llvm_stdstring_stdstring(const uint8_t *stdstring1, @@ -658,7 +539,7 @@ void __cmplog_rtn_llvm_stdstring_stdstring(const uint8_t *stdstring1, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked(k, string_ptr1, string_ptr2, len); + cmplog_routines_checked(k, string_ptr1, string_ptr2, len); } void __cmplog_rtn_llvm_stdstring_stdstring_extended(const uint8_t *stdstring1, const uint8_t *stdstring2) { @@ -680,6 +561,5 @@ void __cmplog_rtn_llvm_stdstring_stdstring_extended(const uint8_t *stdstring1, uintptr_t k = RETADDR; k = (k >> 4) ^ (k << 8); k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, - len); + cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, len); } \ No newline at end of file diff --git a/libafl_targets/src/cmplog.h b/libafl_targets/src/cmplog.h index ae37f2559f..292954fa80 100644 --- a/libafl_targets/src/cmplog.h +++ b/libafl_targets/src/cmplog.h @@ -108,6 +108,136 @@ extern CmpLogMapExtended *libafl_cmplog_map_extended_ptr; extern uint8_t libafl_cmplog_enabled; +// 5 of CMPLOG inner APIs, we static inline everything +// area_is_valid, cmplog_instructions_checked, +// cmplog_instructions_extended_checked, +// cmplog_routines_checked, +// cmplog_routines_checked_extended + +static inline void cmplog_instructions_checked(uintptr_t k, uint8_t shape, + uint64_t arg1, uint64_t arg2) { + if (!libafl_cmplog_enabled) { return; } + libafl_cmplog_enabled = false; + + uint16_t hits; + if (libafl_cmplog_map_ptr->headers[k].kind != CMPLOG_KIND_INS) { + libafl_cmplog_map_ptr->headers[k].kind = CMPLOG_KIND_INS; + libafl_cmplog_map_ptr->headers[k].hits = 1; + libafl_cmplog_map_ptr->headers[k].shape = shape; + hits = 0; + } else { + hits = libafl_cmplog_map_ptr->headers[k].hits++; + if (libafl_cmplog_map_ptr->headers[k].shape < shape) { + libafl_cmplog_map_ptr->headers[k].shape = shape; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map_ptr->vals.operands[k][hits].v0 = arg1; + libafl_cmplog_map_ptr->vals.operands[k][hits].v1 = arg2; + libafl_cmplog_enabled = true; +} + +static inline void cmplog_instructions_extended_checked( + uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2, uint8_t attr) { +#ifdef CMPLOG_EXTENDED + if (!libafl_cmplog_enabled) { return; } + libafl_cmplog_enabled = false; + + // printf("%ld %ld %ld\n", k, arg1, arg2); + uint16_t hits; + if (libafl_cmplog_map_extended_ptr->headers[k].type != AFL_CMP_TYPE_INS) { + libafl_cmplog_map_extended_ptr->headers[k].type = AFL_CMP_TYPE_INS; + libafl_cmplog_map_extended_ptr->headers[k].hits = 1; + libafl_cmplog_map_extended_ptr->headers[k].shape = shape; + hits = 0; + } else { + hits = libafl_cmplog_map_extended_ptr->headers[k].hits++; + if (libafl_cmplog_map_extended_ptr->headers[k].shape < shape) { + libafl_cmplog_map_extended_ptr->headers[k].shape = shape; + } + } + + hits &= CMPLOG_MAP_H - 1; + libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v0 = arg1; + libafl_cmplog_map_extended_ptr->vals.operands[k][hits].v1 = arg2; + libafl_cmplog_map_extended_ptr->headers[k].attribute = attr; + libafl_cmplog_enabled = true; +#else + // just do nothing + (void)k; + (void)shape; + (void)arg1; + (void)arg2; + (void)attr; +#endif +} + +// cmplog routines after area check +static inline void cmplog_routines_checked(uintptr_t k, const uint8_t *ptr1, + const uint8_t *ptr2, size_t len) { + libafl_cmplog_enabled = false; + uint32_t hits; + + if (libafl_cmplog_map_ptr->headers[k].kind != CMPLOG_KIND_RTN) { + libafl_cmplog_map_ptr->headers[k].kind = CMPLOG_KIND_RTN; + libafl_cmplog_map_ptr->headers[k].hits = 1; + libafl_cmplog_map_ptr->headers[k].shape = len; + hits = 0; + } else { + hits = libafl_cmplog_map_ptr->headers[k].hits++; + if (libafl_cmplog_map_ptr->headers[k].shape < len) { + libafl_cmplog_map_ptr->headers[k].shape = + len; // TODO; adjust len for AFL++'s cmplog protocol + } + } + + hits &= CMPLOG_MAP_RTN_H - 1; + MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v0, ptr1, len); + MEMCPY(libafl_cmplog_map_ptr->vals.routines[k][hits].v1, ptr2, len); + libafl_cmplog_enabled = true; +} + +// cmplog routines after area check +static inline void cmplog_routines_checked_extended(uintptr_t k, + const uint8_t *ptr1, + const uint8_t *ptr2, + size_t len) { +#ifdef CMPLOG_EXTENDED + libafl_cmplog_enabled = false; + uint32_t hits; + // printf("RTN: %ld %ld %ld %ld\n", k, *ptr1, *ptr2, len); + if (libafl_cmplog_map_extended_ptr->headers[k].type != AFL_CMP_TYPE_RTN) { + libafl_cmplog_map_extended_ptr->headers[k].type = AFL_CMP_TYPE_RTN; + libafl_cmplog_map_extended_ptr->headers[k].hits = 1; + libafl_cmplog_map_extended_ptr->headers[k].shape = len; + hits = 0; + } else { + hits = libafl_cmplog_map_extended_ptr->headers[k].hits++; + if (libafl_cmplog_map_extended_ptr->headers[k].shape < len) { + libafl_cmplog_map_extended_ptr->headers[k].shape = + len; // TODO; adjust len for AFL++'s cmplog protocol + } + } + + hits &= CMPLOG_MAP_RTN_H - 1; + libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v0_len = len; + libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v1_len = len; + MEMCPY(libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v0, ptr1, len); + MEMCPY(libafl_cmplog_map_extended_ptr->vals.routines[k][hits].v1, ptr2, len); + libafl_cmplog_enabled = true; +#else + // just do nothing + (void)k; + (void)ptr1; + (void)ptr2; + (void)len; +#endif +} + +// Expose these three APIs so that you can still call into them from outside +// libafl_targets + void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2); diff --git a/libafl_targets/src/common.h b/libafl_targets/src/common.h index ae4c6ae401..0852f94c20 100644 --- a/libafl_targets/src/common.h +++ b/libafl_targets/src/common.h @@ -82,6 +82,7 @@ typedef uint128_t u128; }) #define MEMCPY __builtin_memcpy #else + #include // needed to use memcpy on windows #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MEMCPY memcpy diff --git a/libafl_targets/src/libfuzzer.c b/libafl_targets/src/libfuzzer.c index 094a028c97..ff6e2968ee 100644 --- a/libafl_targets/src/libfuzzer.c +++ b/libafl_targets/src/libfuzzer.c @@ -48,11 +48,11 @@ int main(int argc, char **argv) { libafl_main(); return 0; } - #ifdef FUZZER_DEFINE_RUN_DRIVER + #ifdef FUZZER_DEFINE_RUN_DRIVER return LLVMFuzzerRunDriver(&argc, &argv, &LLVMFuzzerTestOneInput); - #else + #else return 0; - #endif + #endif } #endif #endif diff --git a/libafl_targets/src/sancov_cmp.c b/libafl_targets/src/sancov_cmp.c index c39553e75e..1786c7abe3 100644 --- a/libafl_targets/src/sancov_cmp.c +++ b/libafl_targets/src/sancov_cmp.c @@ -19,7 +19,7 @@ void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) { #endif #ifdef SANCOV_CMPLOG k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 1, (uint64_t)arg1, (uint64_t)arg2); + cmplog_instructions_checked(k, 1, (uint64_t)arg1, (uint64_t)arg2); #endif } @@ -33,7 +33,7 @@ void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2) { #endif #ifdef SANCOV_CMPLOG k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 2, (uint64_t)arg1, (uint64_t)arg2); + cmplog_instructions_checked(k, 2, (uint64_t)arg1, (uint64_t)arg2); #endif } @@ -47,7 +47,7 @@ void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) { #endif #ifdef SANCOV_CMPLOG k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 4, (uint64_t)arg1, (uint64_t)arg2); + cmplog_instructions_checked(k, 4, (uint64_t)arg1, (uint64_t)arg2); #endif } @@ -61,7 +61,7 @@ void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) { #endif #ifdef SANCOV_CMPLOG k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, 8, (uint64_t)arg1, (uint64_t)arg2); + cmplog_instructions_checked(k, 8, (uint64_t)arg1, (uint64_t)arg2); #endif } @@ -95,7 +95,7 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) { #endif #ifdef SANCOV_CMPLOG k &= CMPLOG_MAP_W - 1; - __libafl_targets_cmplog_instructions(k, cases[1] / 8, val, cases[i + 2]); + cmplog_instructions_checked(k, cases[1] / 8, val, cases[i + 2]); #endif } }