mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 19:08:08 +00:00
fix and update libfuzzer custom mutator
This commit is contained in:
@ -77,7 +77,7 @@ struct {
|
|||||||
} Flags;
|
} Flags;
|
||||||
|
|
||||||
static const FlagDescription FlagDescriptions[]{
|
static const FlagDescription FlagDescriptions[]{
|
||||||
|
\
|
||||||
#define FUZZER_DEPRECATED_FLAG(Name) \
|
#define FUZZER_DEPRECATED_FLAG(Name) \
|
||||||
{#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
|
{#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
|
||||||
#define FUZZER_FLAG_INT(Name, Default, Description) \
|
#define FUZZER_FLAG_INT(Name, Default, Description) \
|
||||||
@ -941,23 +941,12 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
|
|||||||
Options.EntropicNumberOfRarestFeatures =
|
Options.EntropicNumberOfRarestFeatures =
|
||||||
(size_t)Flags.entropic_number_of_rarest_features;
|
(size_t)Flags.entropic_number_of_rarest_features;
|
||||||
Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time;
|
Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time;
|
||||||
if (Options.Entropic) {
|
if (!Options.FocusFunction.empty())
|
||||||
|
Options.Entropic = false; // FocusFunction overrides entropic scheduling.
|
||||||
if (!Options.FocusFunction.empty()) {
|
if (Options.Entropic)
|
||||||
|
|
||||||
Printf(
|
|
||||||
"ERROR: The parameters `--entropic` and `--focus_function` cannot "
|
|
||||||
"be used together.\n");
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
|
Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
|
||||||
Options.EntropicFeatureFrequencyThreshold,
|
Options.EntropicFeatureFrequencyThreshold,
|
||||||
Options.EntropicNumberOfRarestFeatures);
|
Options.EntropicNumberOfRarestFeatures);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EntropicOptions Entropic;
|
struct EntropicOptions Entropic;
|
||||||
Entropic.Enabled = Options.Entropic;
|
Entropic.Enabled = Options.Entropic;
|
||||||
Entropic.FeatureFrequencyThreshold =
|
Entropic.FeatureFrequencyThreshold =
|
||||||
|
@ -45,8 +45,8 @@ namespace fuzzer {
|
|||||||
|
|
||||||
ExternalFunctions::ExternalFunctions() {
|
ExternalFunctions::ExternalFunctions() {
|
||||||
\
|
\
|
||||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
|
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||||
GetFnPtr < decltype(ExternalFunctions::NAME)>(#NAME, WARN)
|
this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
|
||||||
|
|
||||||
#include "FuzzerExtFunctions.def"
|
#include "FuzzerExtFunctions.def"
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ namespace fuzzer {
|
|||||||
|
|
||||||
ExternalFunctions::ExternalFunctions() {
|
ExternalFunctions::ExternalFunctions() {
|
||||||
\
|
\
|
||||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME = ::NAME;
|
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||||
CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)),
|
this->NAME = ::NAME; \
|
||||||
#NAME, WARN);
|
CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)), \
|
||||||
|
#NAME, WARN);
|
||||||
|
|
||||||
#include "FuzzerExtFunctions.def"
|
#include "FuzzerExtFunctions.def"
|
||||||
|
|
||||||
|
@ -45,16 +45,15 @@ using namespace fuzzer;
|
|||||||
#endif // LIBFUZZER_MSVC
|
#endif // LIBFUZZER_MSVC
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
\
|
||||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)
|
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||||
RETURN_TYPE NAME##Def FUNC_SIG {
|
RETURN_TYPE NAME##Def FUNC_SIG { \
|
||||||
|
\
|
||||||
Printf("ERROR: Function \"%s\" not defined.\n", #NAME);
|
Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
|
||||||
exit(1);
|
exit(1); \
|
||||||
|
\
|
||||||
}
|
} \
|
||||||
|
EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
|
||||||
EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
|
|
||||||
|
|
||||||
#include "FuzzerExtFunctions.def"
|
#include "FuzzerExtFunctions.def"
|
||||||
|
|
||||||
@ -81,8 +80,8 @@ namespace fuzzer {
|
|||||||
|
|
||||||
ExternalFunctions::ExternalFunctions() {
|
ExternalFunctions::ExternalFunctions() {
|
||||||
\
|
\
|
||||||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
|
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
|
||||||
GetFnPtr < decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
|
this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
|
||||||
|
|
||||||
#include "FuzzerExtFunctions.def"
|
#include "FuzzerExtFunctions.def"
|
||||||
|
|
||||||
|
@ -171,8 +171,9 @@ FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
|
|||||||
FUZZER_FLAG_STRING(focus_function, "Experimental. "
|
FUZZER_FLAG_STRING(focus_function, "Experimental. "
|
||||||
"Fuzzing will focus on inputs that trigger calls to this function. "
|
"Fuzzing will focus on inputs that trigger calls to this function. "
|
||||||
"If -focus_function=auto and -data_flow_trace is used, libFuzzer "
|
"If -focus_function=auto and -data_flow_trace is used, libFuzzer "
|
||||||
"will choose the focus functions automatically.")
|
"will choose the focus functions automatically. Disables -entropic when "
|
||||||
FUZZER_FLAG_INT(entropic, 0, "Experimental. Enables entropic power schedule.")
|
"specified.")
|
||||||
|
FUZZER_FLAG_INT(entropic, 1, "Enables entropic power schedule.")
|
||||||
FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
|
FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
|
||||||
"entropic is enabled, all features which are observed less often than "
|
"entropic is enabled, all features which are observed less often than "
|
||||||
"the specified value are considered as rare.")
|
"the specified value are considered as rare.")
|
||||||
|
290
custom_mutators/libfuzzer/FuzzerInterceptors.cpp
Normal file
290
custom_mutators/libfuzzer/FuzzerInterceptors.cpp
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
//===-- FuzzerInterceptors.cpp --------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Intercept certain libc functions to aid fuzzing.
|
||||||
|
// Linked only when other RTs that define their own interceptors are not linked.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "FuzzerPlatform.h"
|
||||||
|
|
||||||
|
#if LIBFUZZER_LINUX
|
||||||
|
|
||||||
|
#define GET_CALLER_PC() __builtin_return_address(0)
|
||||||
|
|
||||||
|
#define PTR_TO_REAL(x) real_##x
|
||||||
|
#define REAL(x) __interception::PTR_TO_REAL(x)
|
||||||
|
#define FUNC_TYPE(x) x##_type
|
||||||
|
#define DEFINE_REAL(ret_type, func, ...) \
|
||||||
|
typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
|
||||||
|
namespace __interception { \
|
||||||
|
\
|
||||||
|
FUNC_TYPE(func) PTR_TO_REAL(func); \
|
||||||
|
\
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <dlfcn.h> // for dlsym()
|
||||||
|
|
||||||
|
static void *getFuncAddr(const char *name, uintptr_t wrapper_addr) {
|
||||||
|
|
||||||
|
void *addr = dlsym(RTLD_NEXT, name);
|
||||||
|
if (!addr) {
|
||||||
|
|
||||||
|
// If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
|
||||||
|
// later in the library search order than the DSO that we are trying to
|
||||||
|
// intercept, which means that we cannot intercept this function. We still
|
||||||
|
// want the address of the real definition, though, so look it up using
|
||||||
|
// RTLD_DEFAULT.
|
||||||
|
addr = dlsym(RTLD_DEFAULT, name);
|
||||||
|
|
||||||
|
// In case `name' is not loaded, dlsym ends up finding the actual wrapper.
|
||||||
|
// We don't want to intercept the wrapper and have it point to itself.
|
||||||
|
if (reinterpret_cast<uintptr_t>(addr) == wrapper_addr) addr = nullptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FuzzerInited = 0;
|
||||||
|
static bool FuzzerInitIsRunning;
|
||||||
|
|
||||||
|
static void fuzzerInit();
|
||||||
|
|
||||||
|
static void ensureFuzzerInited() {
|
||||||
|
|
||||||
|
assert(!FuzzerInitIsRunning);
|
||||||
|
if (!FuzzerInited) { fuzzerInit(); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int internal_strcmp_strncmp(const char *s1, const char *s2, bool strncmp,
|
||||||
|
size_t n) {
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if (strncmp) {
|
||||||
|
|
||||||
|
if (i == n) break;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned c1 = *s1;
|
||||||
|
unsigned c2 = *s2;
|
||||||
|
if (c1 != c2) return (c1 < c2) ? -1 : 1;
|
||||||
|
if (c1 == 0) break;
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int internal_strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
|
||||||
|
return internal_strcmp_strncmp(s1, s2, true, n);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int internal_strcmp(const char *s1, const char *s2) {
|
||||||
|
|
||||||
|
return internal_strcmp_strncmp(s1, s2, false, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int internal_memcmp(const void *s1, const void *s2, size_t n) {
|
||||||
|
|
||||||
|
const uint8_t *t1 = static_cast<const uint8_t *>(s1);
|
||||||
|
const uint8_t *t2 = static_cast<const uint8_t *>(s2);
|
||||||
|
for (size_t i = 0; i < n; ++i, ++t1, ++t2)
|
||||||
|
if (*t1 != *t2) return *t1 < *t2 ? -1 : 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t internal_strlen(const char *s) {
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
while (s[i])
|
||||||
|
i++;
|
||||||
|
return i;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *internal_strstr(const char *haystack, const char *needle) {
|
||||||
|
|
||||||
|
// This is O(N^2), but we are not using it in hot places.
|
||||||
|
size_t len1 = internal_strlen(haystack);
|
||||||
|
size_t len2 = internal_strlen(needle);
|
||||||
|
if (len1 < len2) return nullptr;
|
||||||
|
for (size_t pos = 0; pos <= len1 - len2; pos++) {
|
||||||
|
|
||||||
|
if (internal_memcmp(haystack + pos, needle, len2) == 0)
|
||||||
|
return const_cast<char *>(haystack) + pos;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// Weak hooks forward-declared to avoid dependency on
|
||||||
|
// <sanitizer/common_interface_defs.h>.
|
||||||
|
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
|
||||||
|
const void *s2, size_t n, int result);
|
||||||
|
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
|
||||||
|
const char *s2, size_t n, int result);
|
||||||
|
void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
|
||||||
|
const char *s2, size_t n, int result);
|
||||||
|
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
|
||||||
|
const char *s2, int result);
|
||||||
|
void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
|
||||||
|
const char *s2, int result);
|
||||||
|
void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
|
||||||
|
const char *s2, char *result);
|
||||||
|
void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
|
||||||
|
const char *s2, char *result);
|
||||||
|
void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
|
||||||
|
const void *s2, size_t len2, void *result);
|
||||||
|
|
||||||
|
DEFINE_REAL(int, bcmp, const void *, const void *, size_t)
|
||||||
|
DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
|
||||||
|
DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
|
||||||
|
DEFINE_REAL(int, strcmp, const char *, const char *)
|
||||||
|
DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
|
||||||
|
DEFINE_REAL(int, strcasecmp, const char *, const char *)
|
||||||
|
DEFINE_REAL(char *, strstr, const char *, const char *)
|
||||||
|
DEFINE_REAL(char *, strcasestr, const char *, const char *)
|
||||||
|
DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int bcmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
|
||||||
|
if (!FuzzerInited) return internal_memcmp(s1, s2, n);
|
||||||
|
int result = REAL(bcmp)(s1, s2, n);
|
||||||
|
__sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
|
||||||
|
|
||||||
|
if (!FuzzerInited) return internal_memcmp(s1, s2, n);
|
||||||
|
int result = REAL(memcmp)(s1, s2, n);
|
||||||
|
__sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
|
||||||
|
if (!FuzzerInited) return internal_strncmp(s1, s2, n);
|
||||||
|
int result = REAL(strncmp)(s1, s2, n);
|
||||||
|
__sanitizer_weak_hook_strncmp(GET_CALLER_PC(), s1, s2, n, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int strcmp(const char *s1, const char *s2) {
|
||||||
|
|
||||||
|
if (!FuzzerInited) return internal_strcmp(s1, s2);
|
||||||
|
int result = REAL(strcmp)(s1, s2);
|
||||||
|
__sanitizer_weak_hook_strcmp(GET_CALLER_PC(), s1, s2, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
|
||||||
|
ensureFuzzerInited();
|
||||||
|
int result = REAL(strncasecmp)(s1, s2, n);
|
||||||
|
__sanitizer_weak_hook_strncasecmp(GET_CALLER_PC(), s1, s2, n, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int strcasecmp(const char *s1, const char *s2) {
|
||||||
|
|
||||||
|
ensureFuzzerInited();
|
||||||
|
int result = REAL(strcasecmp)(s1, s2);
|
||||||
|
__sanitizer_weak_hook_strcasecmp(GET_CALLER_PC(), s1, s2, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE char *strstr(const char *s1, const char *s2) {
|
||||||
|
|
||||||
|
if (!FuzzerInited) return internal_strstr(s1, s2);
|
||||||
|
char *result = REAL(strstr)(s1, s2);
|
||||||
|
__sanitizer_weak_hook_strstr(GET_CALLER_PC(), s1, s2, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE char *strcasestr(const char *s1, const char *s2) {
|
||||||
|
|
||||||
|
ensureFuzzerInited();
|
||||||
|
char *result = REAL(strcasestr)(s1, s2);
|
||||||
|
__sanitizer_weak_hook_strcasestr(GET_CALLER_PC(), s1, s2, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE
|
||||||
|
void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
|
||||||
|
|
||||||
|
ensureFuzzerInited();
|
||||||
|
void *result = REAL(memmem)(s1, len1, s2, len2);
|
||||||
|
__sanitizer_weak_hook_memmem(GET_CALLER_PC(), s1, len1, s2, len2, result);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((section(".preinit_array"),
|
||||||
|
used)) static void (*__local_fuzzer_preinit)(void) = fuzzerInit;
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
static void fuzzerInit() {
|
||||||
|
|
||||||
|
assert(!FuzzerInitIsRunning);
|
||||||
|
if (FuzzerInited) return;
|
||||||
|
FuzzerInitIsRunning = true;
|
||||||
|
|
||||||
|
REAL(bcmp) = reinterpret_cast<memcmp_type>(
|
||||||
|
getFuncAddr("bcmp", reinterpret_cast<uintptr_t>(&bcmp)));
|
||||||
|
REAL(memcmp) = reinterpret_cast<memcmp_type>(
|
||||||
|
getFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
|
||||||
|
REAL(strncmp) = reinterpret_cast<strncmp_type>(
|
||||||
|
getFuncAddr("strncmp", reinterpret_cast<uintptr_t>(&strncmp)));
|
||||||
|
REAL(strcmp) = reinterpret_cast<strcmp_type>(
|
||||||
|
getFuncAddr("strcmp", reinterpret_cast<uintptr_t>(&strcmp)));
|
||||||
|
REAL(strncasecmp) = reinterpret_cast<strncasecmp_type>(
|
||||||
|
getFuncAddr("strncasecmp", reinterpret_cast<uintptr_t>(&strncasecmp)));
|
||||||
|
REAL(strcasecmp) = reinterpret_cast<strcasecmp_type>(
|
||||||
|
getFuncAddr("strcasecmp", reinterpret_cast<uintptr_t>(&strcasecmp)));
|
||||||
|
REAL(strstr) = reinterpret_cast<strstr_type>(
|
||||||
|
getFuncAddr("strstr", reinterpret_cast<uintptr_t>(&strstr)));
|
||||||
|
REAL(strcasestr) = reinterpret_cast<strcasestr_type>(
|
||||||
|
getFuncAddr("strcasestr", reinterpret_cast<uintptr_t>(&strcasestr)));
|
||||||
|
REAL(memmem) = reinterpret_cast<memmem_type>(
|
||||||
|
getFuncAddr("memmem", reinterpret_cast<uintptr_t>(&memmem)));
|
||||||
|
|
||||||
|
FuzzerInitIsRunning = false;
|
||||||
|
FuzzerInited = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -752,7 +752,7 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
|
|||||||
if (Options.Verbosity) {
|
if (Options.Verbosity) {
|
||||||
|
|
||||||
Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
|
Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
|
||||||
MD.PrintMutationSequence();
|
MD.PrintMutationSequence(Options.Verbosity >= 2);
|
||||||
Printf("\n");
|
Printf("\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
26
custom_mutators/libfuzzer/FuzzerMain.cpp
Normal file
26
custom_mutators/libfuzzer/FuzzerMain.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//===- FuzzerMain.cpp - main() function and flags -------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// main() and flags.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "FuzzerDefs.h"
|
||||||
|
#include "FuzzerPlatform.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// This function should be defined by the user.
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
namespace fuzzer {
|
namespace fuzzer {
|
||||||
|
|
||||||
const size_t Dictionary::kMaxDictSize;
|
const size_t Dictionary::kMaxDictSize;
|
||||||
|
static const size_t kMaxMutationsToPrint = 10;
|
||||||
|
|
||||||
static void PrintASCII(const Word &W, const char *PrintAfter) {
|
static void PrintASCII(const Word &W, const char *PrintAfter) {
|
||||||
|
|
||||||
@ -608,18 +609,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MutationDispatcher::PrintMutationSequence() {
|
void MutationDispatcher::PrintMutationSequence(bool Verbose) {
|
||||||
|
|
||||||
Printf("MS: %zd ", CurrentMutatorSequence.size());
|
Printf("MS: %zd ", CurrentMutatorSequence.size());
|
||||||
for (auto M : CurrentMutatorSequence)
|
size_t EntriesToPrint =
|
||||||
Printf("%s-", M.Name);
|
Verbose ? CurrentMutatorSequence.size()
|
||||||
|
: std::min(kMaxMutationsToPrint, CurrentMutatorSequence.size());
|
||||||
|
for (size_t i = 0; i < EntriesToPrint; i++)
|
||||||
|
Printf("%s-", CurrentMutatorSequence[i].Name);
|
||||||
if (!CurrentDictionaryEntrySequence.empty()) {
|
if (!CurrentDictionaryEntrySequence.empty()) {
|
||||||
|
|
||||||
Printf(" DE: ");
|
Printf(" DE: ");
|
||||||
for (auto DE : CurrentDictionaryEntrySequence) {
|
EntriesToPrint = Verbose ? CurrentDictionaryEntrySequence.size()
|
||||||
|
: std::min(kMaxMutationsToPrint,
|
||||||
|
CurrentDictionaryEntrySequence.size());
|
||||||
|
for (size_t i = 0; i < EntriesToPrint; i++) {
|
||||||
|
|
||||||
Printf("\"");
|
Printf("\"");
|
||||||
PrintASCII(DE->GetW(), "\"-");
|
PrintASCII(CurrentDictionaryEntrySequence[i]->GetW(), "\"-");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,9 @@ public:
|
|||||||
~MutationDispatcher() {}
|
~MutationDispatcher() {}
|
||||||
/// Indicate that we are about to start a new sequence of mutations.
|
/// Indicate that we are about to start a new sequence of mutations.
|
||||||
void StartMutationSequence();
|
void StartMutationSequence();
|
||||||
/// Print the current sequence of mutations.
|
/// Print the current sequence of mutations. Only prints the full sequence
|
||||||
void PrintMutationSequence();
|
/// when Verbose is true.
|
||||||
|
void PrintMutationSequence(bool Verbose = true);
|
||||||
/// Return the current sequence of mutations.
|
/// Return the current sequence of mutations.
|
||||||
std::string MutationSequence();
|
std::string MutationSequence();
|
||||||
/// Indicate that the current sequence of mutations was successful.
|
/// Indicate that the current sequence of mutations was successful.
|
||||||
|
@ -46,7 +46,7 @@ struct FuzzingOptions {
|
|||||||
size_t MaxNumberOfRuns = -1L;
|
size_t MaxNumberOfRuns = -1L;
|
||||||
int ReportSlowUnits = 10;
|
int ReportSlowUnits = 10;
|
||||||
bool OnlyASCII = false;
|
bool OnlyASCII = false;
|
||||||
bool Entropic = false;
|
bool Entropic = true;
|
||||||
size_t EntropicFeatureFrequencyThreshold = 0xFF;
|
size_t EntropicFeatureFrequencyThreshold = 0xFF;
|
||||||
size_t EntropicNumberOfRarestFeatures = 100;
|
size_t EntropicNumberOfRarestFeatures = 100;
|
||||||
bool EntropicScalePerExecTime = false;
|
bool EntropicScalePerExecTime = false;
|
||||||
|
@ -1,81 +1,81 @@
|
|||||||
|
|
||||||
#CFLAGS = -O3 -funroll-loops -fPIC -fpermissive -std=c++11
|
CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11
|
||||||
CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
|
#CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
|
||||||
CC ?= clang++
|
CXX ?= clang++
|
||||||
|
|
||||||
all: libfuzzer-mutator.so
|
all: libfuzzer-mutator.so
|
||||||
|
|
||||||
FuzzerCrossOver.o: FuzzerCrossOver.cpp
|
FuzzerCrossOver.o: FuzzerCrossOver.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerDataFlowTrace.o: FuzzerDataFlowTrace.cpp
|
FuzzerDataFlowTrace.o: FuzzerDataFlowTrace.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerDriver.o: FuzzerDriver.cpp
|
FuzzerDriver.o: FuzzerDriver.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerExtFunctionsDlsym.o: FuzzerExtFunctionsDlsym.cpp
|
FuzzerExtFunctionsDlsym.o: FuzzerExtFunctionsDlsym.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerExtFunctionsWeak.o: FuzzerExtFunctionsWeak.cpp
|
FuzzerExtFunctionsWeak.o: FuzzerExtFunctionsWeak.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerExtFunctionsWindows.o: FuzzerExtFunctionsWindows.cpp
|
FuzzerExtFunctionsWindows.o: FuzzerExtFunctionsWindows.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerExtraCounters.o: FuzzerExtraCounters.cpp
|
FuzzerExtraCounters.o: FuzzerExtraCounters.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerFork.o: FuzzerFork.cpp
|
FuzzerFork.o: FuzzerFork.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerIO.o: FuzzerIO.cpp
|
FuzzerIO.o: FuzzerIO.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerIOPosix.o: FuzzerIOPosix.cpp
|
FuzzerIOPosix.o: FuzzerIOPosix.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerIOWindows.o: FuzzerIOWindows.cpp
|
FuzzerIOWindows.o: FuzzerIOWindows.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerLoop.o: FuzzerLoop.cpp
|
FuzzerLoop.o: FuzzerLoop.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerMerge.o: FuzzerMerge.cpp
|
FuzzerMerge.o: FuzzerMerge.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerMutate.o: FuzzerMutate.cpp
|
FuzzerMutate.o: FuzzerMutate.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerSHA1.o: FuzzerSHA1.cpp
|
FuzzerSHA1.o: FuzzerSHA1.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerTracePC.o: FuzzerTracePC.cpp
|
FuzzerTracePC.o: FuzzerTracePC.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtil.o: FuzzerUtil.cpp
|
FuzzerUtil.o: FuzzerUtil.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtilDarwin.o: FuzzerUtilDarwin.cpp
|
FuzzerUtilDarwin.o: FuzzerUtilDarwin.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtilFuchsia.o: FuzzerUtilFuchsia.cpp
|
FuzzerUtilFuchsia.o: FuzzerUtilFuchsia.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtilLinux.o: FuzzerUtilLinux.cpp
|
FuzzerUtilLinux.o: FuzzerUtilLinux.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtilPosix.o: FuzzerUtilPosix.cpp
|
FuzzerUtilPosix.o: FuzzerUtilPosix.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
FuzzerUtilWindows.o: FuzzerUtilWindows.cpp
|
FuzzerUtilWindows.o: FuzzerUtilWindows.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
libfuzzer.o: libfuzzer.cpp
|
libfuzzer.o: libfuzzer.cpp
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -c $^
|
$(CXX) $(CFLAGS) -I../../include -I. -c $^
|
||||||
|
|
||||||
libfuzzer-mutator.so: FuzzerCrossOver.o FuzzerDataFlowTrace.o FuzzerDriver.o FuzzerExtFunctionsDlsym.o FuzzerExtFunctionsWeak.o FuzzerExtFunctionsWindows.o FuzzerExtraCounters.o FuzzerFork.o FuzzerIO.o FuzzerIOPosix.o FuzzerIOWindows.o FuzzerLoop.o FuzzerMerge.o FuzzerMutate.o FuzzerSHA1.o FuzzerTracePC.o FuzzerUtil.o FuzzerUtilDarwin.o FuzzerUtilFuchsia.o FuzzerUtilLinux.o FuzzerUtilPosix.o FuzzerUtilWindows.o libfuzzer.o
|
libfuzzer-mutator.so: FuzzerCrossOver.o FuzzerDataFlowTrace.o FuzzerDriver.o FuzzerExtFunctionsDlsym.o FuzzerExtFunctionsWeak.o FuzzerExtFunctionsWindows.o FuzzerExtraCounters.o FuzzerFork.o FuzzerIO.o FuzzerIOPosix.o FuzzerIOWindows.o FuzzerLoop.o FuzzerMerge.o FuzzerMutate.o FuzzerSHA1.o FuzzerTracePC.o FuzzerUtil.o FuzzerUtilDarwin.o FuzzerUtilFuchsia.o FuzzerUtilLinux.o FuzzerUtilPosix.o FuzzerUtilWindows.o libfuzzer.o
|
||||||
$(CC) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
|
$(CXX) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o *~ *.so core
|
rm -f *.o *~ *.so core
|
||||||
|
@ -21,4 +21,4 @@ are done.
|
|||||||
|
|
||||||
> Original repository: https://github.com/llvm/llvm-project
|
> Original repository: https://github.com/llvm/llvm-project
|
||||||
> Path: compiler-rt/lib/fuzzer/*.{h|cpp}
|
> Path: compiler-rt/lib/fuzzer/*.{h|cpp}
|
||||||
> Source commit: d4b88ac1658d681e143482336cac27c6a74b8b24
|
> Source commit: df3e903655e2499968fc7af64fb5fa52b2ee79bb
|
||||||
|
@ -72,7 +72,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
|||||||
|
|
||||||
/* When a new queue entry is added we check if there are new dictionary
|
/* When a new queue entry is added we check if there are new dictionary
|
||||||
entries to add to honggfuzz structure */
|
entries to add to honggfuzz structure */
|
||||||
#if ß
|
#if 0
|
||||||
extern "C" void afl_custom_queue_new_entry(my_mutator_t * data,
|
extern "C" void afl_custom_queue_new_entry(my_mutator_t * data,
|
||||||
const uint8_t *filename_new_queue,
|
const uint8_t *filename_new_queue,
|
||||||
const uint8_t *filename_orig_queue) {
|
const uint8_t *filename_orig_queue) {
|
||||||
|
Reference in New Issue
Block a user