Support binary serialization of protos.
diff --git a/examples/libfuzzer/CMakeLists.txt b/examples/libfuzzer/CMakeLists.txt
index 173363c..f6f2dbf 100644
--- a/examples/libfuzzer/CMakeLists.txt
+++ b/examples/libfuzzer/CMakeLists.txt
@@ -12,26 +12,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-protobuf_generate_cpp(LIB_FUZZER_EXAMPLE_PROTO_SRCS
-                      LIB_FUZZER_EXAMPLE_PROTO_HDRS
-                      libfuzzer_example.proto)
-add_executable(libfuzzer_example
-               libfuzzer_example.cc
-               ${LIB_FUZZER_EXAMPLE_PROTO_SRCS})
-target_link_libraries(libfuzzer_example
-                      protobuf-mutator
-                      ${LIB_PROTO_MUTATOR_FUZZER_LIBRARIES})
-set_property(TARGET libfuzzer_example
-             PROPERTY COMPILE_FLAGS ${FUZZING_FLAGS})
-set_property(TARGET libfuzzer_example
-             PROPERTY LINK_FLAGS ${FUZZING_FLAGS})
-
 add_executable(libfuzzer_example_test
                libfuzzer_example_test.cc)
-add_dependencies(libfuzzer_example_test libfuzzer_example)
 target_link_libraries(libfuzzer_example_test
                       ${GTEST_BOTH_LIBRARIES}
                       ${CMAKE_THREAD_LIBS_INIT})
 add_test(test.libfuzzer_example_test libfuzzer_example_test --gtest_color=yes AUTO)
-
 add_dependencies(check libfuzzer_example_test)
+
+protobuf_generate_cpp(LIB_FUZZER_EXAMPLE_PROTO_SRCS
+                      LIB_FUZZER_EXAMPLE_PROTO_HDRS
+                      libfuzzer_example.proto)
+
+add_library(fuzzer-example-proto
+            ${LIB_FUZZER_EXAMPLE_PROTO_SRCS})
+set_property(TARGET fuzzer-example-proto
+             PROPERTY COMPILE_FLAGS ${NO_FUZZING_FLAGS})
+
+foreach(fuzzer libfuzzer_example libfuzzer_bin_example)
+  add_executable(${fuzzer} ${fuzzer}.cc)
+  target_link_libraries(${fuzzer}
+                        fuzzer-example-proto
+                        protobuf-mutator
+                        ${LIB_PROTO_MUTATOR_FUZZER_LIBRARIES})
+  set_property(TARGET ${fuzzer}
+               PROPERTY COMPILE_FLAGS ${FUZZING_FLAGS})
+  set_property(TARGET ${fuzzer}
+               PROPERTY LINK_FLAGS ${FUZZING_FLAGS})
+  add_dependencies(libfuzzer_example_test ${fuzzer})
+endforeach(fuzzer)
diff --git a/examples/libfuzzer/libfuzzer_bin_example.cc b/examples/libfuzzer/libfuzzer_bin_example.cc
new file mode 100644
index 0000000..87dd7fd
--- /dev/null
+++ b/examples/libfuzzer/libfuzzer_bin_example.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstdint>
+
+#include "examples/libfuzzer/libfuzzer_example.pb.h"
+#include "src/libfuzzer_protobuf_mutator.h"
+
+using libfuzzer_example::Msg;
+
+extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
+                                          size_t max_size, unsigned int seed) {
+  return protobuf_mutator::MutateBinaryMessage<Msg>(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::CrossOverBinaryMessages<Msg>(
+      data1, size1, data2, size2, out, max_out_size, seed);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  libfuzzer_example::Msg message;
+  protobuf_mutator::ParseBinaryMessage(data, size, &message);
+
+  // Emulate a bug.
+  if (message.optional_bool() &&
+      std::hash<std::string>()(message.optional_string()) % 1000 == 9) {
+    abort();
+  }
+
+  return 0;
+}
diff --git a/examples/libfuzzer/libfuzzer_example_test.cc b/examples/libfuzzer/libfuzzer_example_test.cc
index 8401a9e..a142553 100644
--- a/examples/libfuzzer/libfuzzer_example_test.cc
+++ b/examples/libfuzzer/libfuzzer_example_test.cc
@@ -32,3 +32,17 @@
   // Cleanup.
   EXPECT_EQ(0, std::system((std::string("rm -rf ") + dir).c_str()));
 }
+
+TEST(LibFuzzerExampleTest, CrashBinary) {
+  char dir_template[] = "/tmp/libfuzzer_example_test_XXXXXX";
+  auto dir = mkdtemp(dir_template);
+  ASSERT_TRUE(dir);
+
+  std::string cmd = "./libfuzzer_bin_example -max_len=150 -artifact_prefix=" +
+                    std::string(dir) + "/ " + dir + "/";
+  int retvalue = std::system(cmd.c_str());
+  EXPECT_EQ(kDefaultLibFuzzerError, WSTOPSIG(retvalue));
+
+  // Cleanup.
+  EXPECT_EQ(0, std::system((std::string("rm -rf ") + dir).c_str()));
+}