diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 3f8b519b..f55a5d82 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -151,6 +151,15 @@ afl_module_info_t *__afl_module_info = NULL; u32 __afl_pcmap_size = 0; uintptr_t *__afl_pcmap_ptr = NULL; + + // Maximum path length on Linux + #ifndef PATH_MAX + #define PATH_MAX 4096 + #endif + + // Maximum length of an uint32_t as string + #define START_STOP_MAX 10 + #endif // __AFL_CODE_COVERAGE /* 1 if we are running in afl, and the forkserver was started, else 0 */ @@ -1082,9 +1091,64 @@ static void __afl_start_snapshots(void) { static void __afl_start_forkserver(void) { - if (__afl_already_initialized_forkserver) return; + if (__afl_already_initialized_forkserver) { return; } __afl_already_initialized_forkserver = 1; + if (getenv("AFL_DUMP_MODULE_MAP")) { + + if (__afl_module_info) { + + int32_t cnt = 0; + afl_module_info_t *start = __afl_module_info; + + while (start) { + + ++cnt; + start = start->next; + + } + + // Allocate per entry enough space for: + // + // 1. One path + // 2. Two pcguard start/stop offsets + // 3. Two spaces and a trailing newline + // + // This is a very conservative allocation so we can just YOLO the rest. + size_t bufsize = (PATH_MAX + START_STOP_MAX * 2 + 2 + 1) * cnt + 1; + char *buf = malloc(bufsize); + char *cur = buf; + + if (!buf) { perror("malloc"); }; + + start = __afl_module_info; + + while (start) { + + size_t namelen = strlen(start->name); + + memcpy(cur, start->name, namelen); + cur += namelen; + *cur = ' '; + cur += 1; + cur += sprintf(cur, "%u %u", start->start, start->stop); + *cur = '\n'; + cur += 1; + + start = start->next; + + } + + *cur = '\0'; + + printf("%s\n", buf); + + } + + exit(-1); + + } + struct sigaction orig_action; sigaction(SIGTERM, NULL, &orig_action); old_sigterm_handler = orig_action.sa_handler; diff --git a/src/afl-cc.c b/src/afl-cc.c index 86b81459..d3541894 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1868,6 +1868,7 @@ int main(int argc, char **argv, char **envp) { instrument_mode = INSTRUMENT_LLVMNATIVE; instrument_opt_mode |= INSTRUMENT_OPT_CODECOV; + setenv("AFL_DONT_OPTIMIZE", "1", 1); } else { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index b82bcd72..4003957d 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -75,8 +75,9 @@ static u8 *in_dir = NULL, /* input folder */ static u8 outfile[PATH_MAX]; -static u8 *in_data, /* Input data */ - *coverage_map; /* Coverage map */ +static u8 *in_data; /* Input data */ + +static u8 *coverage_map; /* Coverage map */ static u64 total; /* tuple content information */ static u32 tcnt, highest; /* tuple content information */ @@ -97,7 +98,8 @@ static bool quiet_mode, /* Hide non-essential messages? */ no_classify, /* do not classify counts */ debug, /* debug mode */ print_filenames, /* print the current filename */ - wait_for_gdb; + wait_for_gdb, /* wait for gdb to allow attaching */ + code_cov; /* code coverage cmdline parameter */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ child_crashed; /* Child crashed? */ @@ -244,8 +246,15 @@ static void analyze_results(afl_forkserver_t *fsrv) { total += fsrv->trace_bits[i]; if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i]; - // if (!coverage_map[i]) { coverage_map[i] = 1; } - coverage_map[i] |= fsrv->trace_bits[i]; + if (code_cov) { + + if (coverage_map[i] < 255 && fsrv->trace_bits[i]) { coverage_map[i]++; } + + } else { + + coverage_map[i] |= fsrv->trace_bits[i]; + + } } @@ -348,6 +357,75 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { } +#if 0 +static u32 write_results_to_file32(u32 *map, u8 *outfile) { + + s32 fd; + u32 i, ret = 0; + + if (!outfile || !*outfile) { + + FATAL("Output filename not set (Bug in AFL++?)"); + + } + + if (!strncmp(outfile, "/dev/", 5)) { + + fd = open(outfile, O_WRONLY); + + if (fd < 0) { PFATAL("Unable to open '%s'", out_file); } + + } else if (!strcmp(outfile, "-")) { + + fd = dup(1); + if (fd < 0) { PFATAL("Unable to open stdout"); } + + } else { + + unlink(outfile); /* Ignore errors */ + fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); + if (fd < 0) { PFATAL("Unable to create '%s'", outfile); } + + } + + if (binary_mode) { + + for (i = 0; i < map_size; i++) { + + if (map[i]) { ret++; } + + } + + ck_write(fd, map, map_size, outfile); + close(fd); + + } else { + + FILE *f = fdopen(fd, "w"); + + if (!f) { PFATAL("fdopen() failed"); } + + for (i = 0; i < map_size; i++) { + + if (!map[i]) { continue; } + ret++; + + total += map[i]; + if (highest < map[i]) { highest = map[i]; } + + fprintf(f, "%06u:%u\n", i, map[i]); + + } + + fclose(f); + + } + + return ret; + +} +#endif + void pre_afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *mem, u32 len) { static u8 buf[MAX_FILE]; @@ -1096,10 +1174,16 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:I:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) { + while ((opt = getopt(argc, argv, "+i:I:o:f:m:t:AeqCZOH:QUWbcrshVXY")) > 0) { switch (opt) { + case 'V': + code_cov = true; + collect_coverage = true; + quiet_mode = true; + break; + case 's': no_classify = true; break; @@ -1673,8 +1757,12 @@ int main(int argc, char **argv_orig, char **envp) { } else { - if ((coverage_map = (u8 *)malloc(map_size + 64)) == NULL) + if ((coverage_map = (u8 *)malloc((map_size + 64))) == NULL) { + FATAL("coult not grab memory"); + + } + edges_only = false; raw_instr_output = true;