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