diff options
-rw-r--r-- | TODO.md | 1 | ||||
-rw-r--r-- | include/envs.h | 24 | ||||
-rw-r--r-- | instrumentation/SanitizerCoveragePCGUARD.so.cc | 6 | ||||
-rw-r--r-- | instrumentation/afl-llvm-common.cc | 45 | ||||
-rw-r--r-- | instrumentation/afl-llvm-common.h | 1 |
5 files changed, 64 insertions, 13 deletions
diff --git a/TODO.md b/TODO.md index d47372b8..20f3425f 100644 --- a/TODO.md +++ b/TODO.md @@ -11,6 +11,7 @@ - afl-showmap -f support - afl-fuzz multicore wrapper script - when trimming then perform crash detection + - cyclomatic complexity: 2 + calls + edges - blocks ## Should diff --git a/include/envs.h b/include/envs.h index 2f5b0d60..5b516905 100644 --- a/include/envs.h +++ b/include/envs.h @@ -21,18 +21,18 @@ static char *afl_environment_variables[] = { "AFL_BENCH_UNTIL_CRASH", "AFL_CAL_FAST", "AFL_CC", "AFL_CC_COMPILER", "AFL_CMIN_ALLOW_ANY", "AFL_CMIN_CRASHES_ONLY", "AFL_CMPLOG_ONLY_NEW", "AFL_CODE_END", "AFL_CODE_START", "AFL_COMPCOV_BINNAME", - "AFL_CMPLOG_MAX_LEN", "AFL_COMPCOV_LEVEL", "AFL_CRASH_EXITCODE", - "AFL_CRASHING_SEEDS_AS_NEW_CRASH", "AFL_CUSTOM_MUTATOR_LIBRARY", - "AFL_CUSTOM_MUTATOR_ONLY", "AFL_CUSTOM_INFO_PROGRAM", - "AFL_CUSTOM_INFO_PROGRAM_ARGV", "AFL_CUSTOM_INFO_PROGRAM_INPUT", - "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", - "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", "AFL_DEBUG_UNICORN", - "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", "AFL_DISABLE_TRIM", - "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", "AFL_DONT_OPTIMIZE", - "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV", - "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", - "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL", - "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", + "AFL_DUMP_CYCLOMATIC_COMPLEXITY", "AFL_CMPLOG_MAX_LEN", "AFL_COMPCOV_LEVEL", + "AFL_CRASH_EXITCODE", "AFL_CRASHING_SEEDS_AS_NEW_CRASH", + "AFL_CUSTOM_MUTATOR_LIBRARY", "AFL_CUSTOM_MUTATOR_ONLY", + "AFL_CUSTOM_INFO_PROGRAM", "AFL_CUSTOM_INFO_PROGRAM_ARGV", + "AFL_CUSTOM_INFO_PROGRAM_INPUT", "AFL_CUSTOM_INFO_OUT", "AFL_CXX", + "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", + "AFL_DEBUG_UNICORN", "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", + "AFL_DISABLE_TRIM", "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", + "AFL_DONT_OPTIMIZE", "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", + "AFL_DUMB_FORKSRV", "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", + "AFL_EXIT_WHEN_DONE", "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", + "AFL_FAST_CAL", "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_ABSOLUTE", "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index f88ce126..01881f28 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -195,7 +195,7 @@ class ModuleSanitizerCoverageAFL SanitizerCoverageOptions Options; - uint32_t instr = 0, selects = 0, unhandled = 0; + uint32_t instr = 0, selects = 0, unhandled = 0, dump_cc = 0; GlobalVariable *AFLMapPtr = NULL; ConstantInt *One = NULL; ConstantInt *Zero = NULL; @@ -330,6 +330,8 @@ bool ModuleSanitizerCoverageAFL::instrumentModule( if (getenv("AFL_DEBUG")) { debug = 1; } + if (getenv("AFL_DUMP_CYCLOMATIC_COMPLEXITY")) { dump_cc = 1; } + if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { SAYF(cCYA "SanitizerCoveragePCGUARD" VERSION cRST "\n"); @@ -638,6 +640,8 @@ void ModuleSanitizerCoverageAFL::instrumentFunction( // InjectTraceForCmp(F, CmpTraceTargets); // InjectTraceForSwitch(F, SwitchTraceTargets); + if (dump_cc) { calcCyclomaticComplexity(&F); } + } GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection( diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index 8e9e7800..ed9268dc 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -26,6 +26,51 @@ static std::list<std::string> allowListFunctions; static std::list<std::string> denyListFiles; static std::list<std::string> denyListFunctions; +unsigned int calcCyclomaticComplexity(llvm::Function *F) { + + unsigned int numBlocks = 0; + unsigned int numEdges = 0; + unsigned int numCalls = 0; + + // Iterate through each basic block in the function + for (BasicBlock &BB : *F) { + + // count all nodes == basic blocks + numBlocks++; + // Count the number of successors (outgoing edges) + for (BasicBlock *Succ : successors(&BB)) { + + // count edges for CC + numEdges++; + (void)(Succ); + + } + + for (Instruction &I : BB) { + + // every call is also an edge, so we need to count the calls too + if (isa<CallInst>(&I) || isa<InvokeInst>(&I)) { numCalls++; } + + } + + } + + // Cyclomatic Complexity V(G) = E - N + 2P + // For a single function, P (number of connected components) is 1 + // Calls are considered to be an edge + unsigned int CC = 2 + numCalls + numEdges - numBlocks; + + // if (debug) { + + fprintf(stderr, "CyclomaticComplexity for %s: %u\n", + F->getName().str().c_str(), CC); + + //} + + return CC; + +} + char *getBBName(const llvm::BasicBlock *BB) { static char *name; diff --git a/instrumentation/afl-llvm-common.h b/instrumentation/afl-llvm-common.h index 23f67179..6b628d64 100644 --- a/instrumentation/afl-llvm-common.h +++ b/instrumentation/afl-llvm-common.h @@ -55,6 +55,7 @@ void initInstrumentList(); bool isInInstrumentList(llvm::Function *F, std::string Filename); unsigned long long int calculateCollisions(uint32_t edges); void scanForDangerousFunctions(llvm::Module *M); +unsigned int calcCyclomaticComplexity(llvm::Function *F); #ifndef IS_EXTERN #define IS_EXTERN |