diff options
author | van Hauser <vh@thc.org> | 2020-08-11 02:05:39 +0200 |
---|---|---|
committer | van Hauser <vh@thc.org> | 2020-08-11 02:05:39 +0200 |
commit | 50e76fce123f01ec83024f3bbd3190f2e1a6d387 (patch) | |
tree | 4d701919ada33e3c26a078bc571903abd4e258e0 | |
parent | 432638404f40594ae163b6e1b92fcfd51b59d59a (diff) | |
download | afl++-50e76fce123f01ec83024f3bbd3190f2e1a6d387.tar.gz |
adding ctor function skipping in LTO fixed map mode
-rw-r--r-- | docs/Changelog.md | 1 | ||||
-rw-r--r-- | include/debug.h | 52 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-lto-instrumentation.so.cc | 76 |
3 files changed, 90 insertions, 39 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md index 182a15b8..25c7a761 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -30,6 +30,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. reporting) - LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR for a fixed map address (eg. 0x10000) + - LTO: skipping ctors and ifuncs in fix map address instrumentation - LTO: autodictionary mode is a default - LTO: instrim instrumentation disabled, only classic support used as it is always better diff --git a/include/debug.h b/include/debug.h index 6cc26ec2..f9ebce58 100644 --- a/include/debug.h +++ b/include/debug.h @@ -218,43 +218,43 @@ /* Die with a verbose non-OS fatal error message. */ -#define FATAL(x...) \ - do { \ - \ - SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ +#define FATAL(x...) \ + do { \ + \ + SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \ - __FILE__, __LINE__); \ - exit(1); \ - \ + __FILE__, __LINE__); \ + exit(1); \ + \ } while (0) /* Die by calling abort() to provide a core dump. */ -#define ABORT(x...) \ - do { \ - \ - SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] PROGRAM ABORT : " cRST x); \ +#define ABORT(x...) \ + do { \ + \ + SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ + "\n[-] PROGRAM ABORT : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \ - __FILE__, __LINE__); \ - abort(); \ - \ + __FILE__, __LINE__); \ + abort(); \ + \ } while (0) /* Die while also including the output of perror(). */ -#define PFATAL(x...) \ - do { \ - \ - fflush(stdout); \ - SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ - "\n[-] SYSTEM ERROR : " cRST x); \ +#define PFATAL(x...) \ + do { \ + \ + fflush(stdout); \ + SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \ + "\n[-] SYSTEM ERROR : " cRST x); \ SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \ - __FILE__, __LINE__); \ - SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ - exit(1); \ - \ + __FILE__, __LINE__); \ + SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ + exit(1); \ + \ } while (0) /* Die with FATAL() or PFATAL() depending on the value of res (used to diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index abc836aa..fd8e48a7 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -224,22 +224,70 @@ bool AFLLTOPass::runOnModule(Module &M) { if (map_addr) { for (GlobalIFunc &IF : M.ifuncs()) { - + StringRef ifunc_name = IF.getName(); Constant *r = IF.getResolver(); StringRef r_name = cast<Function>(r->getOperand(0))->getName(); if (!be_quiet) - fprintf(stderr, "Found an ifunc with name %s that points to resolver function %s, we cannot instrument this, putting it into a block list.\n", + fprintf(stderr, + "Warning: Found an ifunc with name %s that points to resolver " + "function %s, we cannot instrument this, putting it into a " + "block list.\n", ifunc_name.str().c_str(), r_name.str().c_str()); - module_block_list.push_back(r_name.str()); } - // next up: ctors run before __afl_init() - - // TODO + GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors"); + if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) { + + ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer()); + + if (InitList) { + + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + + if (ConstantStruct *CS = + dyn_cast<ConstantStruct>(InitList->getOperand(i))) { + + if (CS->getNumOperands() >= 2) { + if (CS->getOperand(1)->isNullValue()) + break; // Found a null terminator, stop here. + + ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0)); + int Priority = CI ? CI->getSExtValue() : 0; + + Constant *FP = CS->getOperand(1); + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP)) + if (CE->isCast()) FP = CE->getOperand(0); + if (Function *F = dyn_cast<Function>(FP)) { + + if (!F->isDeclaration() && + strncmp(F->getName().str().c_str(), "__afl", 5) != 0 && + Priority <= 5) { + + if (!be_quiet) + fprintf(stderr, + "Warning: Found constructor function %s with prio " + "%u, we cannot instrument this, putting it into a " + "block list.\n", + F->getName().str().c_str(), Priority); + module_block_list.push_back(F->getName().str()); + + } + + } + + } + + } + + } + + } + + } } @@ -260,21 +308,23 @@ bool AFLLTOPass::runOnModule(Module &M) { if (isIgnoreFunction(&F)) continue; if (module_block_list.size()) { - + for (auto bname : module_block_list) { std::string fname = F.getName().str(); if (fname.compare(bname) == 0) { - + if (!be_quiet) - WARNF("Skipping instrumentation of ifunc resolver function %s", - fname.c_str()); - + WARNF( + "Skipping instrumentation of dangerous early running function " + "%s", + fname.c_str()); + } - + } - + } // the instrument file list check |