Home | History | Annotate | Download | only in Fuzzer
      1 //===- FuzzerMutate.h - Internal header for the Fuzzer ----------*- C++ -* ===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 // fuzzer::MutationDispatcher
     10 //===----------------------------------------------------------------------===//
     11 
     12 #ifndef LLVM_FUZZER_MUTATE_H
     13 #define LLVM_FUZZER_MUTATE_H
     14 
     15 #include "FuzzerDefs.h"
     16 #include "FuzzerDictionary.h"
     17 #include "FuzzerRandom.h"
     18 
     19 namespace fuzzer {
     20 
     21 class MutationDispatcher {
     22 public:
     23   MutationDispatcher(Random &Rand, const FuzzingOptions &Options);
     24   ~MutationDispatcher() {}
     25   /// Indicate that we are about to start a new sequence of mutations.
     26   void StartMutationSequence();
     27   /// Print the current sequence of mutations.
     28   void PrintMutationSequence();
     29   /// Indicate that the current sequence of mutations was successfull.
     30   void RecordSuccessfulMutationSequence();
     31   /// Mutates data by invoking user-provided mutator.
     32   size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
     33   /// Mutates data by invoking user-provided crossover.
     34   size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
     35   /// Mutates data by shuffling bytes.
     36   size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
     37   /// Mutates data by erasing bytes.
     38   size_t Mutate_EraseBytes(uint8_t *Data, size_t Size, size_t MaxSize);
     39   /// Mutates data by inserting a byte.
     40   size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
     41   /// Mutates data by inserting several repeated bytes.
     42   size_t Mutate_InsertRepeatedBytes(uint8_t *Data, size_t Size, size_t MaxSize);
     43   /// Mutates data by chanding one byte.
     44   size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
     45   /// Mutates data by chanding one bit.
     46   size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
     47   /// Mutates data by copying/inserting a part of data into a different place.
     48   size_t Mutate_CopyPart(uint8_t *Data, size_t Size, size_t MaxSize);
     49 
     50   /// Mutates data by adding a word from the manual dictionary.
     51   size_t Mutate_AddWordFromManualDictionary(uint8_t *Data, size_t Size,
     52                                             size_t MaxSize);
     53 
     54   /// Mutates data by adding a word from the temporary automatic dictionary.
     55   size_t Mutate_AddWordFromTemporaryAutoDictionary(uint8_t *Data, size_t Size,
     56                                                    size_t MaxSize);
     57 
     58   /// Mutates data by adding a word from the TORC.
     59   size_t Mutate_AddWordFromTORC(uint8_t *Data, size_t Size, size_t MaxSize);
     60 
     61   /// Mutates data by adding a word from the persistent automatic dictionary.
     62   size_t Mutate_AddWordFromPersistentAutoDictionary(uint8_t *Data, size_t Size,
     63                                                     size_t MaxSize);
     64 
     65   /// Tries to find an ASCII integer in Data, changes it to another ASCII int.
     66   size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
     67   /// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
     68   size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
     69 
     70   /// CrossOver Data with some other element of the corpus.
     71   size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
     72 
     73   /// Applies one of the configured mutations.
     74   /// Returns the new size of data which could be up to MaxSize.
     75   size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
     76   /// Applies one of the default mutations. Provided as a service
     77   /// to mutation authors.
     78   size_t DefaultMutate(uint8_t *Data, size_t Size, size_t MaxSize);
     79 
     80   /// Creates a cross-over of two pieces of Data, returns its size.
     81   size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
     82                    size_t Size2, uint8_t *Out, size_t MaxOutSize);
     83 
     84   void AddWordToManualDictionary(const Word &W);
     85 
     86   void AddWordToAutoDictionary(DictionaryEntry DE);
     87   void ClearAutoDictionary();
     88   void PrintRecommendedDictionary();
     89 
     90   void SetCorpus(const InputCorpus *Corpus) { this->Corpus = Corpus; }
     91 
     92   Random &GetRand() { return Rand; }
     93 
     94 private:
     95 
     96   struct Mutator {
     97     size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
     98     const char *Name;
     99   };
    100 
    101   size_t AddWordFromDictionary(Dictionary &D, uint8_t *Data, size_t Size,
    102                                size_t MaxSize);
    103   size_t MutateImpl(uint8_t *Data, size_t Size, size_t MaxSize,
    104                     const std::vector<Mutator> &Mutators);
    105 
    106   size_t InsertPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
    107                       size_t ToSize, size_t MaxToSize);
    108   size_t CopyPartOf(const uint8_t *From, size_t FromSize, uint8_t *To,
    109                     size_t ToSize);
    110   size_t ApplyDictionaryEntry(uint8_t *Data, size_t Size, size_t MaxSize,
    111                               DictionaryEntry &DE);
    112 
    113   template <class T>
    114   DictionaryEntry MakeDictionaryEntryFromCMP(T Arg1, T Arg2,
    115                                              const uint8_t *Data, size_t Size);
    116 
    117   Random &Rand;
    118   const FuzzingOptions &Options;
    119 
    120   // Dictionary provided by the user via -dict=DICT_FILE.
    121   Dictionary ManualDictionary;
    122   // Temporary dictionary modified by the fuzzer itself,
    123   // recreated periodically.
    124   Dictionary TempAutoDictionary;
    125   // Persistent dictionary modified by the fuzzer, consists of
    126   // entries that led to successfull discoveries in the past mutations.
    127   Dictionary PersistentAutoDictionary;
    128 
    129   std::vector<Mutator> CurrentMutatorSequence;
    130   std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
    131 
    132   static const size_t kCmpDictionaryEntriesDequeSize = 16;
    133   DictionaryEntry CmpDictionaryEntriesDeque[kCmpDictionaryEntriesDequeSize];
    134   size_t CmpDictionaryEntriesDequeIdx = 0;
    135 
    136   const InputCorpus *Corpus = nullptr;
    137   std::vector<uint8_t> MutateInPlaceHere;
    138 
    139   std::vector<Mutator> Mutators;
    140   std::vector<Mutator> DefaultMutators;
    141 };
    142 
    143 }  // namespace fuzzer
    144 
    145 #endif  // LLVM_FUZZER_MUTATE_H
    146