aboutsummaryrefslogtreecommitdiff
path: root/custom_mutators
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-11-18 21:25:35 +0100
committerGitHub <noreply@github.com>2020-11-18 21:25:35 +0100
commit4d9eb9bda147a26fc8cbe885b6193cf0c94c6314 (patch)
treec7a903633c7d1b0b5e373535188fd3a458a7f329 /custom_mutators
parent4c59c5234aec0469e4dd02561dbd84387bd53155 (diff)
parentcd0a25be5e9b05a2ab6a11592cd95e7f653bf42d (diff)
downloadafl++-4d9eb9bda147a26fc8cbe885b6193cf0c94c6314.tar.gz
Merge pull request #607 from AFLplusplus/dev
push to stable
Diffstat (limited to 'custom_mutators')
-rw-r--r--custom_mutators/honggfuzz/honggfuzz.c1
-rw-r--r--custom_mutators/libfuzzer/FuzzerIO.cpp7
-rw-r--r--custom_mutators/libfuzzer/FuzzerLoop.cpp13
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.cpp24
-rw-r--r--custom_mutators/libfuzzer/FuzzerMutate.h1
-rw-r--r--custom_mutators/libfuzzer/Makefile5
-rw-r--r--custom_mutators/libfuzzer/libfuzzer.cpp13
-rw-r--r--custom_mutators/radamsa/radamsa-mutator.c1
-rw-r--r--custom_mutators/symcc/symcc.c124
-rw-r--r--custom_mutators/symcc/test_examples/file_test.c36
-rw-r--r--custom_mutators/symcc/test_examples/stdin_test.c28
11 files changed, 237 insertions, 16 deletions
diff --git a/custom_mutators/honggfuzz/honggfuzz.c b/custom_mutators/honggfuzz/honggfuzz.c
index bde922c6..b4f07258 100644
--- a/custom_mutators/honggfuzz/honggfuzz.c
+++ b/custom_mutators/honggfuzz/honggfuzz.c
@@ -37,6 +37,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+ free(data);
perror("mutator_buf alloc");
return NULL;
diff --git a/custom_mutators/libfuzzer/FuzzerIO.cpp b/custom_mutators/libfuzzer/FuzzerIO.cpp
index e0c15db4..d8d52b63 100644
--- a/custom_mutators/libfuzzer/FuzzerIO.cpp
+++ b/custom_mutators/libfuzzer/FuzzerIO.cpp
@@ -83,6 +83,8 @@ void WriteToFile(const std::string &Data, const std::string &Path) {
void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
+ return;
+
// Use raw C interface because this function may be called from a sig handler.
FILE *Out = fopen(Path.c_str(), "wb");
if (!Out) return;
@@ -93,6 +95,8 @@ void WriteToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
void AppendToFile(const std::string &Data, const std::string &Path) {
+ return;
+
AppendToFile(reinterpret_cast<const uint8_t *>(Data.data()), Data.size(),
Path);
@@ -100,6 +104,8 @@ void AppendToFile(const std::string &Data, const std::string &Path) {
void AppendToFile(const uint8_t *Data, size_t Size, const std::string &Path) {
+ return;
+
FILE *Out = fopen(Path.c_str(), "a");
if (!Out) return;
fwrite(Data, sizeof(Data[0]), Size, Out);
@@ -182,6 +188,7 @@ void Printf(const char *Fmt, ...) {
void VPrintf(bool Verbose, const char *Fmt, ...) {
+ return;
if (!Verbose) return;
va_list ap;
va_start(ap, Fmt);
diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp
index 201883f0..08fda520 100644
--- a/custom_mutators/libfuzzer/FuzzerLoop.cpp
+++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp
@@ -206,6 +206,8 @@ void Fuzzer::StaticDeathCallback() {
void Fuzzer::DumpCurrentUnit(const char *Prefix) {
+ return;
+
if (!CurrentUnitData) return; // Happens when running individual inputs.
ScopedDisableMsanInterceptorChecks S;
MD.PrintMutationSequence();
@@ -733,6 +735,7 @@ std::string Fuzzer::WriteToOutputCorpus(const Unit &U) {
void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
+ return;
if (!Options.SaveArtifacts) return;
std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
if (!Options.ExactArtifactPath.empty())
@@ -1073,13 +1076,21 @@ void Fuzzer::MinimizeCrashLoop(const Unit &U) {
} // namespace fuzzer
+#ifdef INTROSPECTION
+ extern const char *introspection_ptr;
+#endif
+
extern "C" {
ATTRIBUTE_INTERFACE size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
size_t MaxSize) {
assert(fuzzer::F);
- return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
+ size_t r = fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
+#ifdef INTROSPECTION
+ introspection_ptr = fuzzer::F->GetMD().WriteMutationSequence();
+#endif
+ return r;
}
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.cpp b/custom_mutators/libfuzzer/FuzzerMutate.cpp
index eebae39b..edfe0455 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.cpp
+++ b/custom_mutators/libfuzzer/FuzzerMutate.cpp
@@ -14,6 +14,8 @@
#include "FuzzerMutate.h"
#include "FuzzerOptions.h"
#include "FuzzerTracePC.h"
+#include <random>
+#include <chrono>
namespace fuzzer {
@@ -100,15 +102,17 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
}
+
size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
size_t MaxSize) {
-
if (Size > MaxSize || Size == 0) return 0;
size_t ShuffleAmount =
Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
size_t ShuffleStart = Rand(Size - ShuffleAmount);
assert(ShuffleStart + ShuffleAmount <= Size);
- std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
+ unsigned num = std::chrono::system_clock::now().time_since_epoch().count();
+ std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, std::default_random_engine(num));
+ //std::shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount, Rand);
return Size;
}
@@ -609,8 +613,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
}
+const char *MutationDispatcher::WriteMutationSequence() {
+
+ static std::string buf;
+ buf = "";
+
+ for (size_t i = 0; i < CurrentMutatorSequence.size(); i++) {
+
+ buf = buf + " " + CurrentMutatorSequence[i].Name;
+
+ }
+
+ return buf.c_str();
+
+}
+
void MutationDispatcher::PrintMutationSequence(bool Verbose) {
+ return;
Printf("MS: %zd ", CurrentMutatorSequence.size());
size_t EntriesToPrint =
Verbose ? CurrentMutatorSequence.size()
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.h b/custom_mutators/libfuzzer/FuzzerMutate.h
index 37fd6100..6252f265 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.h
+++ b/custom_mutators/libfuzzer/FuzzerMutate.h
@@ -26,6 +26,7 @@ public:
void StartMutationSequence();
/// Print the current sequence of mutations. Only prints the full sequence
/// when Verbose is true.
+ const char *WriteMutationSequence();
void PrintMutationSequence(bool Verbose = true);
/// Return the current sequence of mutations.
std::string MutationSequence();
diff --git a/custom_mutators/libfuzzer/Makefile b/custom_mutators/libfuzzer/Makefile
index 95402f6c..51263b89 100644
--- a/custom_mutators/libfuzzer/Makefile
+++ b/custom_mutators/libfuzzer/Makefile
@@ -3,6 +3,11 @@ CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11
#CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
CXX ?= clang++
+ifdef INTROSPECTION
+ $(info Compiling with introspection documentation)
+ CFLAGS += -DINTROSPECTION=1
+endif
+
all: libfuzzer-mutator.so
FuzzerCrossOver.o: FuzzerCrossOver.cpp
diff --git a/custom_mutators/libfuzzer/libfuzzer.cpp b/custom_mutators/libfuzzer/libfuzzer.cpp
index 5e37df66..dc1fbeb2 100644
--- a/custom_mutators/libfuzzer/libfuzzer.cpp
+++ b/custom_mutators/libfuzzer/libfuzzer.cpp
@@ -6,6 +6,10 @@
//#include "debug.h"
#include "afl-fuzz.h"
+#ifdef INTROSPECTION
+ const char *introspection_ptr;
+#endif
+
afl_state_t *afl_struct;
extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
@@ -46,6 +50,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if ((data->mutator_buf = (u8 *)malloc(MAX_FILE)) == NULL) {
+ free(data);
perror("mutator_buf alloc");
return NULL;
@@ -133,6 +138,14 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf,
}
+#ifdef INTROSPECTION
+extern "C" const char* afl_custom_introspection(my_mutator_t *data) {
+
+ return introspection_ptr;
+
+}
+#endif
+
/**
* Deinitialize everything
*
diff --git a/custom_mutators/radamsa/radamsa-mutator.c b/custom_mutators/radamsa/radamsa-mutator.c
index 82d28001..624ace3d 100644
--- a/custom_mutators/radamsa/radamsa-mutator.c
+++ b/custom_mutators/radamsa/radamsa-mutator.c
@@ -33,6 +33,7 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+ free(data);
perror("mutator_buf alloc");
return NULL;
diff --git a/custom_mutators/symcc/symcc.c b/custom_mutators/symcc/symcc.c
index 18b475b8..a609dafb 100644
--- a/custom_mutators/symcc/symcc.c
+++ b/custom_mutators/symcc/symcc.c
@@ -1,7 +1,10 @@
+#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
#include "config.h"
#include "debug.h"
#include "afl-fuzz.h"
@@ -21,6 +24,7 @@ typedef struct my_mutator {
afl_state_t *afl;
u8 * mutator_buf;
u8 * out_dir;
+ u8 * tmp_dir;
u8 * target;
uint32_t seed;
@@ -41,6 +45,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+ free(data);
perror("mutator_buf alloc");
return NULL;
@@ -54,10 +59,11 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if (!(data->out_dir = getenv("SYMCC_OUTPUT_DIR"))) {
data->out_dir = alloc_printf("%s/symcc", afl->out_dir);
- setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1);
}
+ data->tmp_dir = alloc_printf("%s/tmp", data->out_dir);
+ setenv("SYMCC_OUTPUT_DIR", data->tmp_dir, 1);
int pid = fork();
if (pid == -1) return NULL;
@@ -83,6 +89,10 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if (mkdir(data->out_dir, 0755))
PFATAL("Could not create directory %s", data->out_dir);
+
+ if (mkdir(data->tmp_dir, 0755))
+ PFATAL("Could not create directory %s", data->tmp_dir);
+
DBG("out_dir=%s, target=%s\n", data->out_dir, data->target);
return data;
@@ -95,33 +105,119 @@ void afl_custom_queue_new_entry(my_mutator_t * data,
const uint8_t *filename_new_queue,
const uint8_t *filename_orig_queue) {
- int pid = fork();
+ int pipefd[2];
+ struct stat st;
+ ACTF("Queueing to symcc: %s", filename_new_queue);
+ u8 *fn = alloc_printf("%s", filename_new_queue);
+ if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) {
- if (pid == -1) return;
+ ck_free(fn);
+ PFATAL("Couldn't find enqueued file: %s", fn);
- if (pid) pid = waitpid(pid, NULL, 0);
+ }
- if (pid == 0) {
+ if (afl_struct->fsrv.use_stdin) {
+
+ if (pipe(pipefd) == -1) {
+
+ ck_free(fn);
+ PFATAL("Couldn't create a pipe for interacting with symcc child process");
+
+ }
+
+ }
+
+ int pid = fork();
- setenv("SYMCC_INPUT_FILE", afl_struct->fsrv.out_file, 1);
+ if (pid == -1) return;
+
+ if (pid) {
if (afl_struct->fsrv.use_stdin) {
- u8 *fn = alloc_printf("%s/%s", afl_struct->out_dir, filename_new_queue);
+ close(pipefd[0]);
int fd = open(fn, O_RDONLY);
if (fd >= 0) {
ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
- close(fd);
DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r);
- if (r <= 0) return;
- close(0);
- ck_write(0, data->mutator_buf, r, fn);
ck_free(fn);
+ close(fd);
+ if (r <= 0) {
+
+ close(pipefd[1]);
+ return;
+
+ }
+
+ if (r > fcntl(pipefd[1], F_GETPIPE_SZ))
+ fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
+ ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue);
+
+ } else {
+
+ ck_free(fn);
+ close(pipefd[1]);
+ PFATAL(
+ "Something happened to the enqueued file before sending its "
+ "contents to symcc binary");
}
+ close(pipefd[1]);
+
+ }
+
+ pid = waitpid(pid, NULL, 0);
+
+ // At this point we need to transfer files to output dir, since their names
+ // collide and symcc will just overwrite them
+
+ struct dirent **nl;
+ int32_t items = scandir(data->tmp_dir, &nl, NULL, NULL);
+ u8 * origin_name = basename(filename_new_queue);
+ int32_t i;
+ if (items > 0) {
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ struct stat st;
+ u8 *source_name = alloc_printf("%s/%s", data->tmp_dir, nl[i]->d_name);
+ DBG("test=%s\n", fn);
+ if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ u8 *destination_name =
+ alloc_printf("%s/%s.%s", data->out_dir, origin_name, nl[i]->d_name);
+ rename(source_name, destination_name);
+ ck_free(destination_name);
+ DBG("found=%s\n", source_name);
+
+ }
+
+ ck_free(source_name);
+ free(nl[i]);
+
+ }
+
+ free(nl);
+
+ }
+
+ }
+
+ if (pid == 0) {
+
+ if (afl_struct->fsrv.use_stdin) {
+
+ unsetenv("SYMCC_INPUT_FILE");
+ close(pipefd[1]);
+ dup2(pipefd[0], 0);
+
+ } else {
+
+ setenv("SYMCC_INPUT_FILE", afl_struct->fsrv.out_file, 1);
+
}
DBG("exec=%s\n", data->target);
@@ -129,6 +225,7 @@ void afl_custom_queue_new_entry(my_mutator_t * data,
close(2);
dup2(afl_struct->fsrv.dev_null_fd, 1);
dup2(afl_struct->fsrv.dev_null_fd, 2);
+
execvp(data->target, afl_struct->argv);
DBG("exec=FAIL\n");
exit(-1);
@@ -179,7 +276,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
struct dirent **nl;
int32_t i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL);
- size_t size = 0;
+ ssize_t size = 0;
if (items <= 0) return 0;
@@ -198,6 +295,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
size = read(fd, data->mutator_buf, max_size);
*out_buf = data->mutator_buf;
+
close(fd);
done = 1;
@@ -216,7 +314,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
free(nl);
DBG("FUZZ size=%lu\n", size);
- return size;
+ return (uint32_t)size;
}
diff --git a/custom_mutators/symcc/test_examples/file_test.c b/custom_mutators/symcc/test_examples/file_test.c
new file mode 100644
index 00000000..f2b92986
--- /dev/null
+++ b/custom_mutators/symcc/test_examples/file_test.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv) {
+
+ if (argc < 2) {
+
+ printf("Need a file argument\n");
+ return 1;
+
+ }
+
+ int fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+
+ printf("Couldn't open file\n");
+ return 1;
+
+ }
+
+ uint32_t value = 0;
+
+ read(fd, &value, sizeof(value));
+ close(fd);
+
+ value = value ^ 0xffffffff;
+ if (value == 0x11223344) printf("Value one\n");
+ if (value == 0x44332211) printf("Value two\n");
+ if (value != 0x0) printf("Not zero\n");
+ return 0;
+
+}
+
diff --git a/custom_mutators/symcc/test_examples/stdin_test.c b/custom_mutators/symcc/test_examples/stdin_test.c
new file mode 100644
index 00000000..3acfc523
--- /dev/null
+++ b/custom_mutators/symcc/test_examples/stdin_test.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+
+ char input_buffer[16];
+ uint32_t comparisonValue;
+ size_t bytesRead;
+ bytesRead = read(STDIN_FILENO, input_buffer, sizeof(input_buffer));
+ if (bytesRead < 0) exit(-1);
+ comparisonValue = *(uint32_t *)input_buffer;
+ comparisonValue = comparisonValue ^ 0xff112233;
+ if (comparisonValue == 0x66554493) {
+
+ printf("First value\n");
+
+ } else {
+
+ if (comparisonValue == 0x84444415) printf("Second value\n");
+
+ }
+
+ return 0;
+
+}
+