about summary refs log tree commit diff
path: root/examples/afl_proxy
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-04-29 15:21:51 +0200
committervan Hauser <vh@thc.org>2020-04-29 15:21:51 +0200
commitc53663c7ac2c1f96a2dfe3fcbc6fb232bf1d9a74 (patch)
tree9c0d1ccbe859a6cc9a22e5a579ae585f83c0c8aa /examples/afl_proxy
parentbc2e65e4821ef4b8fbc33be6c705adfa1c32e02f (diff)
downloadafl++-c53663c7ac2c1f96a2dfe3fcbc6fb232bf1d9a74.tar.gz
afl-proxy -> afl_proxy
Diffstat (limited to 'examples/afl_proxy')
-rw-r--r--examples/afl_proxy/Makefile7
-rw-r--r--examples/afl_proxy/README.md9
-rw-r--r--examples/afl_proxy/afl-proxy.c235
3 files changed, 251 insertions, 0 deletions
diff --git a/examples/afl_proxy/Makefile b/examples/afl_proxy/Makefile
new file mode 100644
index 00000000..4b368f8d
--- /dev/null
+++ b/examples/afl_proxy/Makefile
@@ -0,0 +1,7 @@
+all:	afl-proxy
+
+afl-proxy:	afl-proxy.c
+	$(CC) -I../../include -o afl-proxy afl-proxy.c
+
+clean:
+	rm -f afl-proxy *~ core
diff --git a/examples/afl_proxy/README.md b/examples/afl_proxy/README.md
new file mode 100644
index 00000000..3c768a19
--- /dev/null
+++ b/examples/afl_proxy/README.md
@@ -0,0 +1,9 @@
+# afl-proxy
+
+afl-proxy is an example skeleton file which can easily be used to fuzz
+and instrument non-standard things.
+
+You only need to change the while() loop of the main() to send the
+data of buf[] with length len to the target and write the coverage
+information to __afl_area_ptr[__afl_map_size]
+
diff --git a/examples/afl_proxy/afl-proxy.c b/examples/afl_proxy/afl-proxy.c
new file mode 100644
index 00000000..eea03549
--- /dev/null
+++ b/examples/afl_proxy/afl-proxy.c
@@ -0,0 +1,235 @@
+/*
+   american fuzzy lop++ - afl-proxy skeleton example
+   ---------------------------------------------------
+
+   Written by Marc Heuse <mh@mh-sec.de>
+
+   Copyright 2019-2020 AFLplusplus Project. 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
+
+
+   HOW-TO
+   ======
+
+   You only need to change the while() loop of the main() to send the
+   data of buf[] with length len to the target and write the coverage
+   information to __afl_area_ptr[__afl_map_size]
+
+
+*/
+
+#ifdef __ANDROID__
+#include "android-ashmem.h"
+#endif
+#include "config.h"
+#include "types.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <sys/mman.h>
+#include <sys/shm.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+u8 *__afl_area_ptr;
+
+#ifdef __ANDROID__
+u32 __afl_map_size = MAP_SIZE;
+#else
+__thread u32 __afl_map_size = MAP_SIZE;
+#endif
+
+/* Error reporting to forkserver controller */
+
+void send_forkserver_error(int error) {
+
+  u32 status;
+  if (!error || error > 0xffff) return;
+  status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error));
+  if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return;
+
+}
+
+/* SHM setup. */
+
+static void __afl_map_shm(void) {
+
+  char *id_str = getenv(SHM_ENV_VAR);
+  char *ptr;
+
+  if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) {
+
+    u32 val = atoi(ptr);
+    if (val > 0) __afl_map_size = val;
+
+  }
+
+  if (__afl_map_size > MAP_SIZE) {
+
+    if (__afl_map_size > FS_OPT_MAX_MAPSIZE) {
+
+      fprintf(stderr,
+              "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to "
+              "be able to run this instrumented program!\n",
+              __afl_map_size);
+      if (id_str) {
+
+        send_forkserver_error(FS_ERROR_MAP_SIZE);
+        exit(-1);
+
+      }
+
+    } else {
+
+      fprintf(stderr,
+              "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to "
+              "be able to run this instrumented program!\n",
+              __afl_map_size);
+
+    }
+
+  }
+
+  if (id_str) {
+
+#ifdef USEMMAP
+    const char *   shm_file_path = id_str;
+    int            shm_fd = -1;
+    unsigned char *shm_base = NULL;
+
+    /* create the shared memory segment as if it was a file */
+    shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
+    if (shm_fd == -1) {
+
+      fprintf(stderr, "shm_open() failed\n");
+      send_forkserver_error(FS_ERROR_SHM_OPEN);
+      exit(1);
+
+    }
+
+    /* map the shared memory segment to the address space of the process */
+    shm_base =
+        mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+
+    if (shm_base == MAP_FAILED) {
+
+      close(shm_fd);
+      shm_fd = -1;
+
+      fprintf(stderr, "mmap() failed\n");
+      send_forkserver_error(FS_ERROR_MMAP);
+      exit(2);
+
+    }
+
+    __afl_area_ptr = shm_base;
+#else
+    u32 shm_id = atoi(id_str);
+
+    __afl_area_ptr = shmat(shm_id, 0, 0);
+
+#endif
+
+    if (__afl_area_ptr == (void *)-1) {
+
+      send_forkserver_error(FS_ERROR_SHMAT);
+      exit(1);
+
+    }
+
+    /* Write something into the bitmap so that the parent doesn't give up */
+
+    __afl_area_ptr[0] = 1;
+
+  }
+
+}
+
+/* Fork server logic. */
+
+static void __afl_start_forkserver(void) {
+
+  u8  tmp[4] = {0, 0, 0, 0};
+  u32 status = 0;
+
+  if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
+    status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
+  if (status) status |= (FS_OPT_ENABLED);
+  memcpy(tmp, &status, 4);
+
+  /* Phone home and tell the parent that we're OK. */
+
+  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
+
+}
+
+static u32 __afl_next_testcase(u8 *buf, u32 max_len) {
+
+  s32 status;
+
+  /* Wait for parent by reading from the pipe. Abort if read fails. */
+  if (read(FORKSRV_FD, &status, 4) != 4) return 0;
+
+  /* we have a testcase - read it */
+  status = read(0, buf, max_len);
+
+  if (status < 1)
+    return 0;
+  else
+    return status;
+
+}
+
+static void __afl_end_testcase(void) {
+
+  int status = 0xffffff;
+
+  if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1);
+
+}
+
+/* you just need to modify the while() loop in this main() */
+
+int main(int argc, char *argv[]) {
+
+  /* This is were the testcase data is written into */
+  u8  buf[1024];
+  u32 len;
+
+  /* here you specify the map size you need that you are reporting to
+     afl-fuzz. */
+  __afl_map_size = MAP_SIZE;
+
+  /* then we initialize the shared memory map and start the forkserver */
+  __afl_map_shm();
+  __afl_start_forkserver();
+
+  while ((len = __afl_next_testcase(buf, sizeof(buf))) > 0) {
+
+    /* here you have to create the magic that feeds the buf/len to the
+       target and write the coverage to __afl_area_ptr */
+
+    // ... the magic ...
+
+    /* report the test case is done and wait for the next */
+    __afl_end_testcase();
+
+  }
+
+  return 0;
+
+}
+