aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2024-05-15 14:16:44 +0200
committervanhauser-thc <vh@thc.org>2024-05-15 14:16:44 +0200
commit1db3b81d2eb855167dcf65734f8833a2329609da (patch)
treef0b32a3dc543d76791bfcbc350a41af0e11221f2
parent0a16ea74879a935bbeb33e488cd451d6d9a7e19a (diff)
downloadAFLplusplus-1db3b81d2eb855167dcf65734f8833a2329609da.tar.gz
dump cc
-rw-r--r--TODO.md1
-rw-r--r--include/envs.h24
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc6
-rw-r--r--instrumentation/afl-llvm-common.cc45
-rw-r--r--instrumentation/afl-llvm-common.h1
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