commit | 8a3c159877fb13b4239c22d0ced01f7f459bbebb | [log] [tgz] |
---|---|---|
author | Vitaly Buka <vitalybuka@google.com> | Fri May 12 22:20:40 2017 -0700 |
committer | Vitaly Buka <vitalybuka@gmail.com> | Mon Jun 05 17:00:35 2017 -0700 |
tree | dee2baf1d36a6563365d3177de20137233a2bae8 | |
parent | d09fb10060b98523d45e754ca8a812a401202ed1 [diff] |
Move out xml code from libprotobuf-mutator sources into examples.
libprotobuf-mutator is a library to randomly mutate protobuffers.
It could be used together with guided fuzzing engines, such as libFuzzer.
Install prerequisites:
sudo apt-get update sudo apt-get install binutils cmake ninja-build liblzma-dev libz-dev docbook2x
Compile and test everything:
mkdir build cd build cmake .. -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug ninja check
Clang is only needed for libFuzzer integration.
To use libprotobuf-mutator simply include protobuf_mutator.h and protobuf_mutator.cc into your build files.
The ProtobufMutator
class implements mutations of the protobuf tree structure and mutations of individual fields. The field mutation logic is very basic -- for better results you should override the ProtobufMutator::Mutate*
methods with more sophisticated logic, e.g. using libFuzzer's mutators.
To apply one mutation to a protobuf object do the following:
class MyProtobufMutator : public protobuf_mutator::Mutator { public: MyProtobufMutator(uint32_t seed) : protobuf_mutator::Mutator(seed) {} // Optionally redefine the Mutate* methods to perform more sophisticated mutations. } void Mutate(MyMessage* message) { MyProtobufMutator mutator(my_random_seed); mutator.Mutate(message, 200); }
See also the ProtobufMutatorMessagesTest.UsageExample
test from protobuf_mutator_test.cc.
LibFuzzerProtobufMutator can help to integrate with libFuzzer. For example
#include "libfuzzer_protobuf_mutator.h" extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size, size_t max_size, unsigned int seed) { return protobuf_mutator::MutateTextMessage<MyMessageType>( data, size, max_size, seed); } extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1, const uint8_t* data2, size_t size2, uint8_t* out, size_t max_out_size, unsigned int seed) { return protobuf_mutator::CrossOverTextMessages<MyMessageType>( data1, size1, data2, size2, out, max_out_size, seed); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { MyMessageType message; protobuf_mutator::ParseTextMessage(data, size, &message); // Code which needs to be fuzzed. ConsumeMyMessageType(message); return 0; }
Please see libfuzzer_example.cc as an example.