Inline cmplog internal functions code (#1972)

* fmt

* aa

* sattic

* win

* frida

* expose API

* fmt

* frida
This commit is contained in:
Dongjia "toka" Zhang 2024-03-26 17:42:03 +01:00 committed by GitHub
parent 53bfae0a08
commit 91778961da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 184 additions and 180 deletions

View File

@ -4,29 +4,15 @@
//! related to the input. //! 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. //! 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"))] #[cfg(all(feature = "cmplog", target_arch = "x86_64"))]
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
use dynasmrt::dynasm; use dynasmrt::dynasm;
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
use dynasmrt::{DynasmApi, DynasmLabelApi}; 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; use frida_gum::ModuleMap;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use frida_gum::{instruction_writer::InstructionWriter, stalker::StalkerOutput}; use frida_gum::{instruction_writer::InstructionWriter, stalker::StalkerOutput};
@ -41,7 +27,14 @@ use iced_x86::{
BlockEncoder, Code, DecoderOptions, Instruction, InstructionBlock, MemoryOperand, MemorySize, BlockEncoder, Code, DecoderOptions, Instruction, InstructionBlock, MemoryOperand, MemorySize,
OpKind, Register, 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"))] #[cfg(all(feature = "cmplog", target_arch = "aarch64"))]
use crate::utils::{disas_count, writer_register}; use crate::utils::{disas_count, writer_register};
@ -179,7 +172,7 @@ impl CmpLogRuntime {
k &= (CMPLOG_MAP_W as u64) - 1; k &= (CMPLOG_MAP_W as u64) - 1;
unsafe { 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; k &= (CMPLOG_MAP_W as u64) - 1;
unsafe { unsafe {
__libafl_targets_cmplog_instructions(k, size, op1, op2); __libafl_targets_cmplog_instructions(k as usize, size, op1, op2);
} }
} }

View File

@ -42,70 +42,10 @@ CmpLogMap *libafl_cmplog_map_ptr = &libafl_cmplog_map;
CmpLogMapExtended *libafl_cmplog_map_extended_ptr = &libafl_cmplog_map_extended; CmpLogMapExtended *libafl_cmplog_map_extended_ptr = &libafl_cmplog_map_extended;
#endif #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. // 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 // 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 // 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; } if (!ptr || __asan_region_is_poisoned(ptr, len)) { return 0; }
long valid_len; long valid_len;
@ -148,66 +88,10 @@ static long area_is_valid(const void *ptr, size_t len) {
} }
} }
// cmplog routines after area check // Very generic cmplog instructions callback
void __libafl_targets_cmplog_routines_checked(uintptr_t k, const uint8_t *ptr1, void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape,
const uint8_t *ptr2, size_t len) { uint64_t arg1, uint64_t arg2) {
libafl_cmplog_enabled = false; cmplog_instructions_checked(k, shape, arg1, arg2);
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 routines callback // 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); 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 // cmplog routines but with len specified
@ -235,7 +119,7 @@ void __libafl_targets_cmplog_routines_len(uintptr_t k, const uint8_t *ptr1,
return; return;
} }
__libafl_targets_cmplog_routines_checked(k, ptr1, ptr2, len); cmplog_routines_checked(k, ptr1, ptr2, len);
} }
/* /*
CMPLOG Callback for instructions 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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__) #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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t size) {
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; k &= CMPLOG_MAP_W - 1;
__libafl_targets_cmplog_instructions(k, size, arg1, arg2); cmplog_instructions_checked(k, size, arg1, arg2);
} }
#endif #endif
/* /*
@ -352,7 +236,7 @@ void __cmplog_rtn_hook(const uint8_t *ptr1, const uint8_t *ptr2) {
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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) { 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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. */ /* hook for string functions, eg. strcmp, strcasecmp etc. */
void __cmplog_rtn_hook_str_extended(const uint8_t *ptr1, uint8_t *ptr2) { 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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. /* 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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. /* hook for string with length functions, eg. strncmp, strncasecmp etc.
Note that we ignore the len parameter and take longer strings if present. */ 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 = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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++ // gcc libstdc++
@ -525,7 +409,7 @@ void __cmplog_rtn_gcc_stdstring_cstring(const uint8_t *stdstring,
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, void __cmplog_rtn_gcc_stdstring_cstring_extended(const uint8_t *stdstring,
const uint8_t *cstring) { const uint8_t *cstring) {
@ -546,8 +430,7 @@ void __cmplog_rtn_gcc_stdstring_cstring_extended(const uint8_t *stdstring,
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; k &= CMPLOG_MAP_W - 1;
__libafl_targets_cmplog_routines_checked_extended(k, string_ptr, cstring, cmplog_routines_checked_extended(k, string_ptr, cstring, len);
len);
} }
void __cmplog_rtn_gcc_stdstring_stdstring(const uint8_t *stdstring1, 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; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, void __cmplog_rtn_gcc_stdstring_stdstring_extended(const uint8_t *stdstring1,
const uint8_t *stdstring2) { const uint8_t *stdstring2) {
@ -592,8 +475,7 @@ void __cmplog_rtn_gcc_stdstring_stdstring_extended(const uint8_t *stdstring1,
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; k &= CMPLOG_MAP_W - 1;
__libafl_targets_cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, len);
len);
} }
void __cmplog_rtn_llvm_stdstring_cstring(const uint8_t *stdstring, 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; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, void __cmplog_rtn_llvm_stdstring_cstring_extended(const uint8_t *stdstring,
const uint8_t *cstring) { const uint8_t *cstring) {
@ -634,8 +516,7 @@ void __cmplog_rtn_llvm_stdstring_cstring_extended(const uint8_t *stdstring,
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; k &= CMPLOG_MAP_W - 1;
__libafl_targets_cmplog_routines_checked_extended(k, string_ptr, cstring, cmplog_routines_checked_extended(k, string_ptr, cstring, len);
len);
} }
void __cmplog_rtn_llvm_stdstring_stdstring(const uint8_t *stdstring1, 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; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; 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, void __cmplog_rtn_llvm_stdstring_stdstring_extended(const uint8_t *stdstring1,
const uint8_t *stdstring2) { const uint8_t *stdstring2) {
@ -680,6 +561,5 @@ void __cmplog_rtn_llvm_stdstring_stdstring_extended(const uint8_t *stdstring1,
uintptr_t k = RETADDR; uintptr_t k = RETADDR;
k = (k >> 4) ^ (k << 8); k = (k >> 4) ^ (k << 8);
k &= CMPLOG_MAP_W - 1; k &= CMPLOG_MAP_W - 1;
__libafl_targets_cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, cmplog_routines_checked_extended(k, string_ptr1, string_ptr2, len);
len);
} }

View File

@ -108,6 +108,136 @@ extern CmpLogMapExtended *libafl_cmplog_map_extended_ptr;
extern uint8_t libafl_cmplog_enabled; 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, void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape,
uint64_t arg1, uint64_t arg2); uint64_t arg1, uint64_t arg2);

View File

@ -82,6 +82,7 @@ typedef uint128_t u128;
}) })
#define MEMCPY __builtin_memcpy #define MEMCPY __builtin_memcpy
#else #else
#include <string.h> // needed to use memcpy on windows
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MEMCPY memcpy #define MEMCPY memcpy

View File

@ -19,7 +19,7 @@ void __sanitizer_cov_trace_cmp1(uint8_t arg1, uint8_t arg2) {
#endif #endif
#ifdef SANCOV_CMPLOG #ifdef SANCOV_CMPLOG
k &= CMPLOG_MAP_W - 1; 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 #endif
} }
@ -33,7 +33,7 @@ void __sanitizer_cov_trace_cmp2(uint16_t arg1, uint16_t arg2) {
#endif #endif
#ifdef SANCOV_CMPLOG #ifdef SANCOV_CMPLOG
k &= CMPLOG_MAP_W - 1; 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 #endif
} }
@ -47,7 +47,7 @@ void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) {
#endif #endif
#ifdef SANCOV_CMPLOG #ifdef SANCOV_CMPLOG
k &= CMPLOG_MAP_W - 1; 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 #endif
} }
@ -61,7 +61,7 @@ void __sanitizer_cov_trace_cmp8(uint64_t arg1, uint64_t arg2) {
#endif #endif
#ifdef SANCOV_CMPLOG #ifdef SANCOV_CMPLOG
k &= CMPLOG_MAP_W - 1; 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 #endif
} }
@ -95,7 +95,7 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
#endif #endif
#ifdef SANCOV_CMPLOG #ifdef SANCOV_CMPLOG
k &= CMPLOG_MAP_W - 1; 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 #endif
} }
} }