about summary refs log tree commit diff
path: root/libafldyninst.cc
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2024-11-04 16:49:47 +0900
committerNguyễn Gia Phong <cnx@loang.net>2024-11-04 17:10:03 +0900
commitf9d644e7f357a21aa64a5de27408b74cbd345dc8 (patch)
tree7829136efbd1f4b12816f884af2c053b54a7704f /libafldyninst.cc
parentcff2d88f97f983683f4caf0e8f87a4f858b486be (diff)
downloadafl-dyninst-f9d644e7f357a21aa64a5de27408b74cbd345dc8.tar.gz
Rework build recipe
Diffstat (limited to 'libafldyninst.cc')
-rw-r--r--libafldyninst.cc200
1 files changed, 200 insertions, 0 deletions
diff --git a/libafldyninst.cc b/libafldyninst.cc
new file mode 100644
index 0000000..2919c5c
--- /dev/null
+++ b/libafldyninst.cc
@@ -0,0 +1,200 @@
+// Instrumentation library
+//
+// SPDX-FileCopyrightText: 2016 Aleksandar Nikolic <anikolich@sourcefire.com>
+// SPDX-FileCopyrightText: 2018, 2020, 2021 Marc "van Hauser" Heuse <vh@thc.org>
+// SPDX-License-Identifier: Apache-2.0
+//
+// SPDX-FileCopyrightText: 2024 Nguyễn Gia Phong <cnx@loang.net>
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+#include "afl/config.h"
+#include "afl/types.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <fcntl.h>
+#include <iostream>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <vector>
+
+using namespace std;
+
+static u8 dummy[65536];
+static u8 *__afl_area_ptr = dummy; // this saves a test + jz instruction
+static s32 shm_id;
+static int __afl_temp_data;
+static pid_t __afl_fork_pid;
+static unsigned short int prev_id = 0;
+static bool forkserver_installed = false;
+
+#define PRINT_ERROR(string) (void)(write(2, string, strlen(string)) + 1) // the (...+1) weirdness is so we do not get an ignoring return value warning
+
+void initAflForkServer() {
+  if (forkserver_installed == true)
+    return;
+  forkserver_installed = true;
+
+  // we can not use fprint* stdout/stderr functions here, it fucks up some programs
+  char *shm_env_var = getenv(SHM_ENV_VAR);
+
+  if (!shm_env_var) {
+    PRINT_ERROR("Error getting shm\n");
+    return;
+  }
+  shm_id = atoi(shm_env_var);
+  __afl_area_ptr = (u8 *)shmat(shm_id, NULL, 0);
+  if (__afl_area_ptr == (u8 *)-1) {
+    PRINT_ERROR("Error: shmat\n");
+    return;
+  }
+  // enter fork() server thyme!
+  int n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+
+  if (n != 4) {
+    PRINT_ERROR("Error writing fork server\n");
+    return;
+  }
+  while (1) {
+    n = read(FORKSRV_FD, &__afl_temp_data, 4);
+    if (n != 4) {
+      PRINT_ERROR("Error reading fork server\n");
+      return;
+    }
+
+    __afl_fork_pid = fork();
+    if (__afl_fork_pid < 0) {
+      PRINT_ERROR("Error on fork()\n");
+      return;
+    }
+    if (__afl_fork_pid == 0) {
+      close(FORKSRV_FD);
+      close(FORKSRV_FD + 1);
+      prev_id = 0;
+      break;
+    } else {
+      // parrent stuff
+      n = write(FORKSRV_FD + 1, &__afl_fork_pid, 4);
+      pid_t temp_pid = waitpid(__afl_fork_pid, &__afl_temp_data, 2);
+
+      if (temp_pid == 0) {
+        return;
+      }
+      n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+    }
+  }
+}
+
+// Should be called on basic block entry
+void bbCallback(unsigned short id) {
+  __afl_area_ptr[prev_id ^ id]++;
+  prev_id = id >> 1;
+}
+
+void forceCleanExit() { exit(0); }
+
+void initOnlyAflForkServer() {
+  if (forkserver_installed == true)
+    return;
+  forkserver_installed = true;
+
+  // enter fork() server thyme!
+  int n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+
+  if (n != 4) {
+    PRINT_ERROR("Error writting fork server\n");
+    return;
+  }
+  while (1) {
+    n = read(FORKSRV_FD, &__afl_temp_data, 4);
+    if (n != 4) {
+      PRINT_ERROR("Error reading fork server\n");
+      return;
+    }
+
+    __afl_fork_pid = fork();
+    if (__afl_fork_pid < 0) {
+      PRINT_ERROR("Error on fork()\n");
+      return;
+    }
+    if (__afl_fork_pid == 0) {
+      close(FORKSRV_FD);
+      close(FORKSRV_FD + 1);
+      prev_id = 0;
+      break;
+    } else {
+      // parrent stuff
+      n = write(FORKSRV_FD + 1, &__afl_fork_pid, 4);
+      pid_t temp_pid = waitpid(__afl_fork_pid, &__afl_temp_data, 2);
+
+      if (temp_pid == 0) {
+        return;
+      }
+      n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+    }
+  }
+}
+
+void initAflForkServerVar(u8 *map) {
+  // we can not use fprint* stdout/stderr functions here, it fucks up some programs
+  if (forkserver_installed == true)
+    return;
+  forkserver_installed = true;
+
+  u8 **ptr = (u8 **)map;
+  char *shm_env_var = getenv(SHM_ENV_VAR);
+  if (!shm_env_var) {
+    char buf[256];
+    PRINT_ERROR("Error getting shm\n");
+    snprintf(buf, sizeof(buf), "__afl_area_ptr: %p\n", ptr);
+    PRINT_ERROR(buf);
+    return;
+  }
+
+  shm_id = atoi(shm_env_var);
+  *ptr = (u8 *)shmat(shm_id, NULL, 0);
+  if ((u8 *)*ptr == (u8 *)-1) {
+    PRINT_ERROR("Error: shmat\n");
+    return;
+  }
+  // enter fork() server thyme!
+  int n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+
+  if (n != 4) {
+    PRINT_ERROR("Error writing fork server\n");
+    return;
+  }
+  while (1) {
+    n = read(FORKSRV_FD, &__afl_temp_data, 4);
+    if (n != 4) {
+      PRINT_ERROR("Error reading fork server\n");
+      return;
+    }
+
+    __afl_fork_pid = fork();
+    if (__afl_fork_pid < 0) {
+      PRINT_ERROR("Error on fork()\n");
+      return;
+    }
+    if (__afl_fork_pid == 0) {
+      close(FORKSRV_FD);
+      close(FORKSRV_FD + 1);
+      prev_id = 0;
+      break;
+    } else {
+      // parrent stuff
+      n = write(FORKSRV_FD + 1, &__afl_fork_pid, 4);
+      pid_t temp_pid = waitpid(__afl_fork_pid, &__afl_temp_data, 2);
+
+      if (temp_pid == 0) {
+        return;
+      }
+      n = write(FORKSRV_FD + 1, &__afl_temp_data, 4);
+    }
+  }
+}