Skip to content

Commit

Permalink
Make E9AFL compatible with statically linked exes
Browse files Browse the repository at this point in the history
Previously, these would crash due to TLS being
uninitialized.
  • Loading branch information
GJDuck committed Sep 23, 2021
1 parent 4ec3e67 commit 3c9ccd2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
39 changes: 34 additions & 5 deletions afl-rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include "e9loader.h"

#define FORKSRV_FD 198
#define AREA_BASE ((uint8_t *)0x200000)
#define AREA_BASE ((uint8_t *)0x1A0000)
#define AREA_SIZE ((size_t)1 << 16)

static FILE *log = NULL;
Expand Down Expand Up @@ -65,7 +65,7 @@ static void print_message(bool fatal, const char *msg, ...)
print_message(false, "e9afl log: " msg "\n", ## __VA_ARGS__)

/* SHM setup. */
static void __afl_map_shm(void)
static bool __afl_map_shm(void)
{
const char *id_str = getenv("__AFL_SHM_ID");

Expand All @@ -77,11 +77,13 @@ static void __afl_map_shm(void)
*/
intptr_t afl_area_ptr = 0x0;
uint32_t shm_id = 0;
bool enabled = false;
if (id_str != NULL)
{
shm_id = (uint32_t)atoi(id_str);
(void)munmap(AREA_BASE, AREA_SIZE);
afl_area_ptr = (intptr_t)shmat(shm_id, AREA_BASE, 0);
enabled = true;
}
else
{
Expand All @@ -99,6 +101,30 @@ static void __afl_map_shm(void)
if (afl_area_ptr != (intptr_t)AREA_BASE)
error("failed to map AFL area (shm_id=%s): %s", id_str,
strerror(errno));
return enabled;
}

/* Init TLS if necessary. */
#include <asm/prctl.h>
static void __afl_init_tls(void)
{
uintptr_t val;
int r = (int)syscall(SYS_arch_prctl, ARCH_GET_FS, &val);
if (r < 0)
error("failed to get TLS base address: %s", strerror(errno));
if (val == 0x0)
{
/*
* If glibc is not dynamically linked then %fs may be uninitialized.
* Since the instrumentation uses TLS, this will cause the binary to
* crash. We fix this using a "dummy" TLS.
*/
static uint8_t dummy_tls[128] = {0};
r = (int)syscall(SYS_arch_prctl, ARCH_SET_FS,
dummy_tls + sizeof(dummy_tls));
if (r < 0)
error("failed to set TLS base address: %s", strerror(errno));
}
}

/* Fork server logic. */
Expand Down Expand Up @@ -174,6 +200,7 @@ static void __afl_start_forkserver(void)
void init(int argc, const char **argv, char **envp, void *_unused,
const struct e9_config_s *config)
{
__afl_init_tls();
if ((config->flags & E9_FLAG_EXE) == 0)
{
/*
Expand All @@ -186,10 +213,12 @@ void init(int argc, const char **argv, char **envp, void *_unused,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
return;
}
log("fuzzing binary %s", argv[0]);
environ = envp;
__afl_map_shm();
__afl_start_forkserver();
if (__afl_map_shm())
{
log("fuzzing binary %s", argv[0]);
__afl_start_forkserver();
}
}

/*
Expand Down
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fi

set -e

VERSION=1c22e063f4d6cec3a927cff495a5c6c4b0d03d67
VERSION=be65ee50cf7efbd00f70bedb50b38de9f0e4abaf

# STEP (1): install e9patch if necessary:
if [ ! -x e9patch-$VERSION/e9patch ]
Expand Down Expand Up @@ -66,7 +66,7 @@ chmod a-x e9AFLPlugin.so
# STEP (3): build the runtime:
echo -e "${GREEN}$0${OFF}: building the e9afl runtime..."
e9patch-$VERSION/e9compile.sh afl-rt.c -I e9patch-$VERSION/examples/ \
-I e9patch-$VERSION/src/e9patch/
-I e9patch-$VERSION/src/e9patch/ -DNO_GLIBC=1
chmod a-x afl-rt

# STEP (4): build the driver:
Expand Down
2 changes: 1 addition & 1 deletion e9AFLPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

using namespace e9frontend;

#define AREA_BASE 0x200000
#define AREA_BASE 0x1A0000
#define AREA_SIZE ((size_t)1 << 16)

/*
Expand Down

0 comments on commit 3c9ccd2

Please sign in to comment.