fix libfuzzer custom mutator and add introspection function

This commit is contained in:
van Hauser
2020-11-10 13:43:48 +01:00
parent 82d1c3e18d
commit 1661303248
6 changed files with 59 additions and 3 deletions

View File

@ -83,6 +83,8 @@ void WriteToFile(const std::string &Data, const std::string &Path) {
void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) { void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
return;
// Use raw C interface because this function may be called from a sig handler. // Use raw C interface because this function may be called from a sig handler.
FILE *Out = fopen(Path.c_str(), "wb"); FILE *Out = fopen(Path.c_str(), "wb");
if (!Out) return; if (!Out) return;
@ -93,6 +95,8 @@ void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
void AppendToFile(const std::string &Data, const std::string &Path) { void AppendToFile(const std::string &Data, const std::string &Path) {
return;
AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(), AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(),
Path); Path);
@ -100,6 +104,8 @@ void AppendToFile(const std::string &Data, const std::string &Path) {
void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) { void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
return;
FILE *Out = fopen(Path.c_str(), "a"); FILE *Out = fopen(Path.c_str(), "a");
if (!Out) return; if (!Out) return;
fwrite(Data, sizeof(Data[0]), Size, Out); fwrite(Data, sizeof(Data[0]), Size, Out);
@ -182,6 +188,7 @@ void Printf(const char *Fmt, ...) {
void VPrintf(bool Verbose, const char *Fmt, ...) { void VPrintf(bool Verbose, const char *Fmt, ...) {
return;
if (!Verbose) return; if (!Verbose) return;
va_list ap; va_list ap;
va_start(ap, Fmt); va_start(ap, Fmt);

View File

@ -206,6 +206,8 @@ void Fuzzer::StaticDeathCallback() {
void Fuzzer::DumpCurrentUnit(const char *Prefix) { void Fuzzer::DumpCurrentUnit(const char *Prefix) {
return;
if (!CurrentUnitData) return; // Happens when running individual inputs. if (!CurrentUnitData) return; // Happens when running individual inputs.
ScopedDisableMsanInterceptorChecks S; ScopedDisableMsanInterceptorChecks S;
MD.PrintMutationSequence(); MD.PrintMutationSequence();
@ -733,6 +735,7 @@ std::string Fuzzer::WriteToOutputCorpus(const Unit &U) {
void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) { void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
return;
if (!Options.SaveArtifacts) return; if (!Options.SaveArtifacts) return;
std::string Path = Options.ArtifactPrefix + Prefix + Hash(U); std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
if (!Options.ExactArtifactPath.empty()) if (!Options.ExactArtifactPath.empty())
@ -1073,13 +1076,21 @@ void Fuzzer::MinimizeCrashLoop(const Unit &U) {
} // namespace fuzzer } // namespace fuzzer
#ifdef INTROSPECTION
extern const char *introspection_ptr;
#endif
extern "C" { extern "C" {
ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
size_t MaxSize) { size_t MaxSize) {
assert(fuzzer::F); assert(fuzzer::F);
return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize); size_t r = fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
#ifdef INTROSPECTION
introspection_ptr = fuzzer::F->GetMD().WriteMutationSequence();
#endif
return r;
} }

View File

@ -14,6 +14,8 @@
#include "FuzzerMutate.h" #include "FuzzerMutate.h"
#include "FuzzerOptions.h" #include "FuzzerOptions.h"
#include "FuzzerTracePC.h" #include "FuzzerTracePC.h"
#include <random>
#include <chrono>
namespace fuzzer { namespace fuzzer {
@ -100,15 +102,17 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
} }
size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
size_t MaxSize) { size_t MaxSize) {
if (Size > MaxSize || Size == 0) return 0; if (Size > MaxSize || Size == 0) return 0;
size_t ShuffleAmount = size_t ShuffleAmount =
Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size. Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
size_t ShuffleStart = Rand(Size - ShuffleAmount); size_t ShuffleStart = Rand(Size - ShuffleAmount);
assert(ShuffleStart + ShuffleAmount <= Size); assert(ShuffleStart + ShuffleAmount <= Size);
std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand); unsigned num = std::chrono::system_clock::now().time_since_epoch().count();
std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, std::default_random_engine(num));
//std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
return Size; return Size;
} }
@ -609,8 +613,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
} }
const char *MutationDispatcher::WriteMutationSequence() {
static std::string buf;
buf = "";
for (size_t i = 0; i < CurrentMutatorSequence.size(); i++) {
buf = buf + " " + CurrentMutatorSequence[i].Name;
}
return buf.c_str();
}
void MutationDispatcher::PrintMutationSequence(bool Verbose) { void MutationDispatcher::PrintMutationSequence(bool Verbose) {
return;
Printf("MS: %zd ", CurrentMutatorSequence.size()); Printf("MS: %zd ", CurrentMutatorSequence.size());
size_t EntriesToPrint = size_t EntriesToPrint =
Verbose ? CurrentMutatorSequence.size() Verbose ? CurrentMutatorSequence.size()

View File

@ -26,6 +26,7 @@ public:
void StartMutationSequence(); void StartMutationSequence();
/// Print the current sequence of mutations. Only prints the full sequence /// Print the current sequence of mutations. Only prints the full sequence
/// when Verbose is true. /// when Verbose is true.
const char *WriteMutationSequence();
void PrintMutationSequence(bool Verbose = true); void PrintMutationSequence(bool Verbose = true);
/// Return the current sequence of mutations. /// Return the current sequence of mutations.
std::string MutationSequence(); std::string MutationSequence();

View File

@ -3,6 +3,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
CXX ?= clang++ CXX ?= clang++
ifdef INTROSPECTION
$(info Compiling with introspection documentation)
CFLAGS += -DINTROSPECTION=1
endif
all: libfuzzer-mutator.so all: libfuzzer-mutator.so
FuzzerCrossOver.o: FuzzerCrossOver.cpp FuzzerCrossOver.o: FuzzerCrossOver.cpp

View File

@ -6,6 +6,10 @@
//#include "debug.h" //#include "debug.h"
#include "afl-fuzz.h" #include "afl-fuzz.h"
#ifdef INTROSPECTION
const char *introspection_ptr;
#endif
afl_state_t *afl_struct; afl_state_t *afl_struct;
extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
@ -133,6 +137,14 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf,
} }
#ifdef INTROSPECTION
extern "C" const char* afl_custom_introspection(my_mutator_t *data) {
return introspection_ptr;
}
#endif
/** /**
* Deinitialize everything * Deinitialize everything
* *