diff options
Diffstat (limited to 'gcc_plugin')
-rw-r--r-- | gcc_plugin/Makefile | 6 | ||||
-rw-r--r-- | gcc_plugin/README.gcc.md | 8 | ||||
-rw-r--r-- | gcc_plugin/afl-gcc-fast.c | 4 | ||||
-rw-r--r-- | gcc_plugin/afl-gcc-pass.so.cc | 37 | ||||
-rw-r--r-- | gcc_plugin/afl-gcc-rt.o.c | 14 |
5 files changed, 46 insertions, 23 deletions
diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile index 287b6545..c7d9796b 100644 --- a/gcc_plugin/Makefile +++ b/gcc_plugin/Makefile @@ -71,8 +71,8 @@ endif test_deps: @echo "[*] Checking for working '$(CC)'..." @which $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 ) - @echo "[*] Checking for gcc for plugin support..." - @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) +# @echo "[*] Checking for gcc for plugin support..." +# @$(CC) -v 2>&1 | grep -q -- --enable-plugin || ( echo "[-] Oops, this gcc has not been configured with plugin support."; exit 1 ) @echo "[*] Checking for gcc plugin development header files..." @test -d `$(CC) -print-file-name=plugin`/include || ( echo "[-] Oops, can't find gcc header files. Be sure to install 'gcc-X-plugin-dev'."; exit 1 ) @echo "[*] Checking for '../afl-showmap'..." @@ -80,7 +80,7 @@ test_deps: @echo "[+] All set and ready to build." ../afl-gcc-fast: afl-gcc-fast.c | test_deps - $(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) + $(CC) -DAFL_GCC_CC=\"$(CC)\" -DAFL_GCC_CXX=\"$(CXX)\" $(CFLAGS) $< -o $@ $(LDFLAGS) ln -sf afl-gcc-fast ../afl-g++-fast ../afl-gcc-pass.so: afl-gcc-pass.so.cc | test_deps diff --git a/gcc_plugin/README.gcc.md b/gcc_plugin/README.gcc.md index 676ef427..80fccfb6 100644 --- a/gcc_plugin/README.gcc.md +++ b/gcc_plugin/README.gcc.md @@ -46,9 +46,11 @@ should be all you need. On Debian machines, these headers can be acquired by installing the `gcc-<VERSION>-plugin-dev` packages. To build the instrumentation itself, type 'make'. This will generate binaries -called afl-gcc-fast and afl-g++-fast in the parent directory. Once this -is done, you can instrument third-party code in a way similar to the standard -operating mode of AFL, e.g.: +called afl-gcc-fast and afl-g++-fast in the parent directory. +If the CC/CXX have been overridden, those compilers will be used from +those wrappers without using AFL_CXX/AFL_CC settings. +Once this is done, you can instrument third-party code in a way similar to the +standard operating mode of AFL, e.g.: CC=/path/to/afl/afl-gcc-fast ./configure [...options...] make diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index 057b44cc..68035944 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -119,12 +119,12 @@ static void edit_params(u32 argc, char** argv) { if (!strcmp(name, "afl-g++-fast")) { u8* alt_cxx = getenv("AFL_CXX"); - cc_params[0] = alt_cxx ? alt_cxx : (u8*)"g++"; + cc_params[0] = alt_cxx ? alt_cxx : (u8*)AFL_GCC_CXX; } else { u8* alt_cc = getenv("AFL_CC"); - cc_params[0] = alt_cc ? alt_cc : (u8*)"gcc"; + cc_params[0] = alt_cc ? alt_cc : (u8*)AFL_GCC_CC; } diff --git a/gcc_plugin/afl-gcc-pass.so.cc b/gcc_plugin/afl-gcc-pass.so.cc index 84e02cb8..bf16b14b 100644 --- a/gcc_plugin/afl-gcc-pass.so.cc +++ b/gcc_plugin/afl-gcc-pass.so.cc @@ -128,6 +128,7 @@ static unsigned int ext_call_instrument(function *fun) { int more_than_one = -1; edge ep; edge_iterator eip; + FOR_EACH_EDGE(ep, eip, bb->preds) { int count = 0; @@ -222,6 +223,7 @@ static unsigned int inline_instrument(function *fun) { DECL_EXTERNAL(prev_loc_g) = 1; /* External linkage */ DECL_PRESERVE_P(prev_loc_g) = 1; DECL_ARTIFICIAL(prev_loc_g) = 1; /* Injected by compiler */ + set_decl_tls_model(prev_loc_g, TLS_MODEL_REAL); /* TLS attribute */ rest_of_decl_compilation(prev_loc_g, 1, 0); FOR_EACH_BB_FN(bb, fun) { @@ -293,6 +295,7 @@ static unsigned int inline_instrument(function *fun) { gimple_seq_add_stmt(&seq, g); // map_ptr = __afl_area_ptr update_stmt(g); +#if 1 #if 0 tree addr = build2(ADDR_EXPR, map_type, map_ptr, area_off); g = gimple_build_assign(map_ptr2, MODIFY_EXPR, addr); @@ -303,12 +306,21 @@ static unsigned int inline_instrument(function *fun) { gimple_seq_add_stmt(&seq, g); // map_ptr2 = map_ptr + area_off update_stmt(g); #endif + // gimple_assign <mem_ref, _3, *p_6, NULL, NULL> tree tmp1 = create_tmp_var_raw(unsigned_char_type_node, "tmp1"); g = gimple_build_assign(tmp1, MEM_REF, map_ptr2); gimple_seq_add_stmt(&seq, g); // tmp1 = *map_ptr2 update_stmt(g); - +#else + tree atIndex = build2(PLUS_EXPR, uint32_type_node, map_ptr, area_off); + tree array_address = build1(ADDR_EXPR, map_type, atIndex); + tree array_access = build1(INDIRECT_REF, map_type, array_address); + tree tmp1 = create_tmp_var(unsigned_char_type_node, "tmp1"); + g = gimple_build_assign(tmp1, array_access); + gimple_seq_add_stmt(&seq, g); // tmp1 = *(map_ptr + area_off) + update_stmt(g); +#endif // gimple_assign <plus_expr, _4, _3, 1, NULL> tree tmp2 = create_tmp_var_raw(unsigned_char_type_node, "tmp2"); g = gimple_build_assign(tmp2, PLUS_EXPR, tmp1, one); @@ -320,8 +332,8 @@ static unsigned int inline_instrument(function *fun) { // gimple_assign <ssa_name, *p_6, _4, NULL, NULL> // tree map_ptr3 = create_tmp_var_raw(map_type, "map_ptr3"); - g = gimple_build_assign(map_ptr_g, INDIRECT_REF, tmp2); - gimple_seq_add_stmt(&seq, g); // *map_ptr3 = tmp2 + g = gimple_build_assign(map_ptr2, INDIRECT_REF, tmp2); + gimple_seq_add_stmt(&seq, g); // *map_ptr2 = tmp2 update_stmt(g); /* Set prev_loc to cur_loc >> 1 */ @@ -401,11 +413,13 @@ class afl_pass : public gimple_opt_pass { } - virtual unsigned int execute(function *fun) { + unsigned int execute(function *fun) override { if (!myWhitelist.empty()) { bool instrumentBlock = false; + std::string instFilename; + unsigned int instLine = 0; /* EXPR_FILENAME This macro returns the name of the file in which the entity was declared, @@ -417,7 +431,8 @@ class afl_pass : public gimple_opt_pass { if (0 != strncmp("<internal>", fname, 10) && 0 != strncmp("<built-in>", fname, 10)) { - std::string instFilename(fname); + instFilename = fname; + instLine = DECL_SOURCE_LINE(fun->decl); /* Continue only if we know where we actually are */ if (!instFilename.empty()) { @@ -449,7 +464,17 @@ class afl_pass : public gimple_opt_pass { /* Either we couldn't figure out our location or the location is * not whitelisted, so we skip instrumentation. */ - if (!instrumentBlock) return 0; + if (!instrumentBlock) { + + if (!be_quiet) { + if (!instFilename.empty()) + SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n", + instFilename.c_str(), instLine); + else + SAYF(cYEL "[!] " cBRI "No filename information found, skipping it"); + } + return 0; + } } diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index 5b70a247..1fb9e099 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -9,8 +9,6 @@ GCC integration design is based on the LLVM design, which comes from Laszlo Szekeres. - Copyright 2015 Google Inc. 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: @@ -55,15 +53,13 @@ __thread u32 __afl_prev_loc; #endif /* Trace a basic block with some ID */ -void __afl_trace(u32 x) { - - u32 l = __afl_prev_loc; +void __afl_trace(const u32 x) { -#if 0 /* enable for neverZero feature. By default disabled since too inefficient :-( */ - /* @Marc: avoid conditional jumps here */ - __afl_area_ptr[l ^ x] += 1 + (__afl_area_ptr[l ^ x] == (u8)~0); +#if 1 /* enable for neverZero feature. */ + __afl_area_ptr[__afl_prev_loc ^ x] += 1 + + ((u8)(1 + __afl_area_ptr[__afl_prev_loc ^ x]) == 0); #else - ++__afl_area_ptr[l ^ x]; + ++__afl_area_ptr[__afl_prev_loc ^ x]; #endif __afl_prev_loc = (x >> 1); |