From: Kostya Serebryany Date: Sat, 19 Dec 2015 01:09:49 +0000 (+0000) Subject: [libFuzzer] print successfull mutations sequences X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=7ed616c150739cd644dd8ec9de80f7d9f5326aa4 [libFuzzer] print successfull mutations sequences git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256071 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Fuzzer/FuzzerInterface.h b/lib/Fuzzer/FuzzerInterface.h index c409c06eca1..329e3a9b1e6 100644 --- a/lib/Fuzzer/FuzzerInterface.h +++ b/lib/Fuzzer/FuzzerInterface.h @@ -70,6 +70,10 @@ class MutationDispatcher { public: MutationDispatcher(FuzzerRandomBase &Rand); ~MutationDispatcher(); + /// Indicate that we are about to start a new sequence of mutations. + void StartMutationSequence(); + /// Print the current sequence of mutations. + void PrintMutationSequence(); /// Mutates data by shuffling bytes. size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize); /// Mutates data by erasing a byte. @@ -138,6 +142,8 @@ class UserSuppliedFuzzer { UserSuppliedFuzzer(FuzzerRandomBase *Rand); /// Executes the target function on 'Size' bytes of 'Data'. virtual int TargetFunction(const uint8_t *Data, size_t Size) = 0; + virtual void StartMutationSequence() { MD.StartMutationSequence(); } + virtual void PrintMutationSequence() { MD.PrintMutationSequence(); } /// Mutates 'Size' bytes of data in 'Data' inplace into up to 'MaxSize' bytes, /// returns the new size of the data, which should be positive. virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 889c30c8748..b1ce294b972 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -320,12 +320,8 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U) { return; PrintStats("NEW ", ""); if (Options.Verbosity) { - Printf(" L: %zd", U.size()); - if (U.size() < 30) { - Printf(" "); - PrintUnitInASCII(U, "\t"); - Print(U); - } + Printf(" L: %zd ", U.size()); + USF.PrintMutationSequence(); Printf("\n"); } } @@ -483,6 +479,7 @@ void Fuzzer::Loop() { secondsSinceProcessStartUp() > static_cast(Options.MaxTotalTimeSec)) break; + USF.StartMutationSequence(); CurrentUnit = Corpus[J1]; // Optionally, cross with another unit. if (Options.DoCrossOver && USF.GetRand().RandBool()) { diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp index 74ae0cbb75a..471ae6ce197 100644 --- a/lib/Fuzzer/FuzzerMutate.cpp +++ b/lib/Fuzzer/FuzzerMutate.cpp @@ -17,29 +17,33 @@ namespace fuzzer { -typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size, - size_t Max); +struct Mutator { + size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max); + const char *Name; +}; struct MutationDispatcher::Impl { std::vector Dictionary; std::vector Mutators; + std::vector CurrentMutatorSequence; + + void Add(Mutator M) { Mutators.push_back(M); } Impl() { - Mutators.push_back(&MutationDispatcher::Mutate_EraseByte); - Mutators.push_back(&MutationDispatcher::Mutate_InsertByte); - Mutators.push_back(&MutationDispatcher::Mutate_ChangeByte); - Mutators.push_back(&MutationDispatcher::Mutate_ChangeBit); - Mutators.push_back(&MutationDispatcher::Mutate_ShuffleBytes); - Mutators.push_back(&MutationDispatcher::Mutate_ChangeASCIIInteger); + Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"}); + Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"}); + Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"}); + Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"}); + Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"}); + Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"}); } void AddWordToDictionary(const uint8_t *Word, size_t Size) { if (Dictionary.empty()) { - Mutators.push_back(&MutationDispatcher::Mutate_AddWordFromDictionary); + Add({&MutationDispatcher::Mutate_AddWordFromDictionary, "AddFromDict"}); } Dictionary.push_back(Unit(Word, Word + Size)); } }; - static char FlipRandomBit(char X, FuzzerRandomBase &Rand) { int Bit = Rand(8); char Mask = 1 << Bit; @@ -150,6 +154,16 @@ size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, return Size; } +void MutationDispatcher::StartMutationSequence() { + MDImpl->CurrentMutatorSequence.clear(); +} + +void MutationDispatcher::PrintMutationSequence() { + Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size()); + for (auto M : MDImpl->CurrentMutatorSequence) + Printf("%s-", M.Name); +} + // Mutates Data in place, returns new size. size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { assert(MaxSize > 0); @@ -165,9 +179,12 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { // Try several times before returning un-mutated data. for (int Iter = 0; Iter < 10; Iter++) { size_t MutatorIdx = Rand(MDImpl->Mutators.size()); - size_t NewSize = - (this->*(MDImpl->Mutators[MutatorIdx]))(Data, Size, MaxSize); - if (NewSize) return NewSize; + auto M = MDImpl->Mutators[MutatorIdx]; + size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize); + if (NewSize) { + MDImpl->CurrentMutatorSequence.push_back(M); + return NewSize; + } } return Size; }