diff options
Diffstat (limited to 'src/afl-as.c')
-rw-r--r-- | src/afl-as.c | 110 |
1 files changed, 74 insertions, 36 deletions
diff --git a/src/afl-as.c b/src/afl-as.c index d0b61ac1..486a6afa 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -126,9 +126,9 @@ static void edit_params(int argc, char **argv) { is not set. We need to check these non-standard variables to properly handle the pass_thru logic later on. */ - if (!tmp_dir) tmp_dir = getenv("TEMP"); - if (!tmp_dir) tmp_dir = getenv("TMP"); - if (!tmp_dir) tmp_dir = "/tmp"; + if (!tmp_dir) { tmp_dir = getenv("TEMP"); } + if (!tmp_dir) { tmp_dir = getenv("TMP"); } + if (!tmp_dir) { tmp_dir = "/tmp"; } as_params = ck_alloc((argc + 32) * sizeof(u8 *)); @@ -138,11 +138,16 @@ static void edit_params(int argc, char **argv) { for (i = 1; i < argc - 1; i++) { - if (!strcmp(argv[i], "--64")) + if (!strcmp(argv[i], "--64")) { + use_64bit = 1; - else if (!strcmp(argv[i], "--32")) + + } else if (!strcmp(argv[i], "--32")) { + use_64bit = 0; + } + #ifdef __APPLE__ /* The Apple case is a bit different... */ @@ -195,11 +200,16 @@ static void edit_params(int argc, char **argv) { } - if (input_file[1]) + if (input_file[1]) { + FATAL("Incorrect use (not called through afl-gcc?)"); - else + + } else { + input_file = NULL; + } + } else { /* Check if this looks like a standard invocation as a part of an attempt @@ -210,11 +220,16 @@ static void edit_params(int argc, char **argv) { if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) && strncmp(input_file, "/var/tmp/", 9) && strncmp(input_file, "/tmp/", 5) && - getenv("AFL_AS_FORCE_INSTRUMENT") == NULL) + getenv("AFL_AS_FORCE_INSTRUMENT") == NULL) { + pass_thru = 1; - else if (getenv("AFL_AS_FORCE_INSTRUMENT")) + + } else if (getenv("AFL_AS_FORCE_INSTRUMENT")) { + unsetenv("AFL_AS_FORCE_INSTRUMENT"); + } + } modified_file = @@ -251,19 +266,21 @@ static void add_instrumentation(void) { if (input_file) { inf = fopen(input_file, "r"); - if (!inf) PFATAL("Unable to read '%s'", input_file); + if (!inf) { PFATAL("Unable to read '%s'", input_file); } - } else + } else { inf = stdin; + } + outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600); - if (outfd < 0) PFATAL("Unable to write to '%s'", modified_file); + if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); } outf = fdopen(outfd, "w"); - if (!outf) PFATAL("fdopen() failed"); + if (!outf) { PFATAL("fdopen() failed"); } while (fgets(line, MAX_LINE, inf)) { @@ -287,7 +304,7 @@ static void add_instrumentation(void) { fputs(line, outf); - if (pass_thru) continue; + if (pass_thru) { continue; } /* All right, this is where the actual fun begins. For one, we only want to instrument the .text section. So, let's keep track of that in processed @@ -300,9 +317,12 @@ static void add_instrumentation(void) { around them, so we use that as a signal. */ if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) && - isdigit(line[10]) && line[11] == '\n') + isdigit(line[10]) && line[11] == '\n') { + skip_next_label = 1; + } + if (!strncmp(line + 2, "text\n", 5) || !strncmp(line + 2, "section\t.text", 13) || !strncmp(line + 2, "section\t__TEXT,__text", 21) || @@ -330,23 +350,23 @@ static void add_instrumentation(void) { if (strstr(line, ".code")) { - if (strstr(line, ".code32")) skip_csect = use_64bit; - if (strstr(line, ".code64")) skip_csect = !use_64bit; + if (strstr(line, ".code32")) { skip_csect = use_64bit; } + if (strstr(line, ".code64")) { skip_csect = !use_64bit; } } /* Detect syntax changes, as could happen with hand-written assembly. Skip Intel blocks, resume instrumentation when back to AT&T. */ - if (strstr(line, ".intel_syntax")) skip_intel = 1; - if (strstr(line, ".att_syntax")) skip_intel = 0; + if (strstr(line, ".intel_syntax")) { skip_intel = 1; } + if (strstr(line, ".att_syntax")) { skip_intel = 0; } /* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */ if (line[0] == '#' || line[1] == '#') { - if (strstr(line, "#APP")) skip_app = 1; - if (strstr(line, "#NO_APP")) skip_app = 0; + if (strstr(line, "#APP")) { skip_app = 1; } + if (strstr(line, "#NO_APP")) { skip_app = 0; } } @@ -375,9 +395,12 @@ static void add_instrumentation(void) { */ if (skip_intel || skip_app || skip_csect || !instr_ok || line[0] == '#' || - line[0] == ' ') + line[0] == ' ') { + continue; + } + /* Conditional branch instruction (jnz, etc). We append the instrumentation right after the branch (to instrument the not-taken path) and at the branch destination label (handled later on). */ @@ -449,11 +472,16 @@ static void add_instrumentation(void) { .Lfunc_begin0-style exception handling calculations (a problem on MacOS X). */ - if (!skip_next_label) + if (!skip_next_label) { + instrument_next = 1; - else + + } else { + skip_next_label = 0; + } + } } else { @@ -468,17 +496,19 @@ static void add_instrumentation(void) { } - if (ins_lines) fputs(use_64bit ? main_payload_64 : main_payload_32, outf); + if (ins_lines) { fputs(use_64bit ? main_payload_64 : main_payload_32, outf); } - if (input_file) fclose(inf); + if (input_file) { fclose(inf); } fclose(outf); if (!be_quiet) { - if (!ins_lines) + if (!ins_lines) { + WARNF("No instrumentation targets found%s.", pass_thru ? " (pass-thru mode)" : ""); - else { + + } else { char modeline[100]; snprintf(modeline, sizeof(modeline), "%s%s%s%s", @@ -514,10 +544,12 @@ int main(int argc, char **argv) { SAYF(cCYA "afl-as" VERSION cRST " by Michal Zalewski\n"); - } else + } else { be_quiet = 1; + } + if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) { fprintf( @@ -565,14 +597,20 @@ int main(int argc, char **argv) { if (inst_ratio_str) { - if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || inst_ratio > 100) + if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || inst_ratio > 100) { + FATAL("Bad value of AFL_INST_RATIO (must be between 0 and 100)"); + } + } - if (getenv(AS_LOOP_ENV_VAR)) + if (getenv(AS_LOOP_ENV_VAR)) { + FATAL("Endless loop when calling 'as' (remove '.' from your PATH)"); + } + setenv(AS_LOOP_ENV_VAR, "1", 1); /* When compiling with ASAN, we don't have a particularly elegant way to skip @@ -582,11 +620,11 @@ int main(int argc, char **argv) { if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) { sanitizer = 1; - if (!getenv("AFL_INST_RATIO")) inst_ratio /= 3; + if (!getenv("AFL_INST_RATIO")) { inst_ratio /= 3; } } - if (!just_version) add_instrumentation(); + if (!just_version) { add_instrumentation(); } if (!(pid = fork())) { @@ -595,11 +633,11 @@ int main(int argc, char **argv) { } - if (pid < 0) PFATAL("fork() failed"); + if (pid < 0) { PFATAL("fork() failed"); } - if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); + if (waitpid(pid, &status, 0) <= 0) { PFATAL("waitpid() failed"); } - if (!getenv("AFL_KEEP_ASSEMBLY")) unlink(modified_file); + if (!getenv("AFL_KEEP_ASSEMBLY")) { unlink(modified_file); } exit(WEXITSTATUS(status)); |