aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2024-01-26 12:15:42 +0100
committervanhauser-thc <vh@thc.org>2024-01-26 12:15:42 +0100
commitb0a912a83881052b3ce476459d8c8edfab59c2f9 (patch)
tree433fa8d4e78da49e06cad225b25c1636851ee99c
parent4d493452a45655073d1b7b1dfe4ad04772b3c2b8 (diff)
downloadafl++-b0a912a83881052b3ce476459d8c8edfab59c2f9.tar.gz
working ugly version
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc448
1 files changed, 330 insertions, 118 deletions
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index c74069e1..54cc1752 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -192,12 +192,14 @@ class ModuleSanitizerCoverageLTO
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
private:
- void instrumentFunction(Function &F, DomTreeCallback DTCallback,
- PostDomTreeCallback PDTCallback);
- void InjectCoverageForIndirectCalls(Function &F,
- ArrayRef<Instruction *> IndirCalls);
- bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
- bool IsLeafFunc = true);
+ void instrumentFunction(Function &F, DomTreeCallback DTCallback,
+ PostDomTreeCallback PDTCallback);
+ void InjectCoverageForIndirectCalls(Function &F,
+ ArrayRef<Instruction *> IndirCalls);
+ bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
+ bool IsLeafFunc = true);
+ bool Fake_InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
+ bool IsLeafFunc = true);
GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements,
Function &F, Type *Ty,
const char *Section);
@@ -248,6 +250,7 @@ class ModuleSanitizerCoverageLTO
uint32_t unhandled = 0;
uint32_t select_cnt = 0;
uint32_t instrument_ctx = 0;
+ uint32_t extra_ctx_inst = 0;
uint64_t map_addr = 0;
const char *skip_nozero = NULL;
const char *use_threadsafe_counters = nullptr;
@@ -259,6 +262,7 @@ class ModuleSanitizerCoverageLTO
IntegerType *Int64Tyi = NULL;
ConstantInt *Zero = NULL;
ConstantInt *One = NULL;
+ AllocaInst *CTX_add = NULL;
LLVMContext *Ct = NULL;
Module *Mo = NULL;
GlobalVariable *AFLMapPtr = NULL;
@@ -1164,9 +1168,10 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
getenv("AFL_USE_TSAN") ? ", TSAN" : "",
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
- OKF("Instrumented %u locations (%u selects) without collisions (%llu "
- "collisions have been avoided) (%s mode).",
- inst, select_cnt, calculateCollisions(inst), modeline);
+
+ OKF("Instrumented %u locations (%u selects) with %u extra map entries "
+ "for CTX (%s mode).",
+ inst, select_cnt, extra_ctx_inst, modeline);
}
@@ -1292,19 +1297,112 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
const DominatorTree *DT = DTCallback(F);
const PostDominatorTree *PDT = PDTCallback(F);
bool IsLeafFunc = true;
- uint32_t skip_next = 0, call_counter = 0;
- Value *PrevCtx = NULL;
+ uint32_t skip_next = 0;
+ uint32_t call_counter = 0;
+ uint32_t inst_save = inst;
+ uint32_t inst_in_this_func = 0;
+ LLVMContext &Context = F.getContext();
+
+ MDNode *N = MDNode::get(Context, MDString::get(Context, "nosanitize"));
+ CTX_add = NULL;
+
+ fprintf(stderr, "Function: %s\n", F.getName().str().c_str());
+
+ // Fake instrumentation so we can count how much there will be in this
+ // function
+
+ for (auto &BB : F) {
+
+ for (auto &IN : BB) {
+
+ CallInst *callInst = nullptr;
+
+ if ((callInst = dyn_cast<CallInst>(&IN))) {
+
+ Function *Callee = callInst->getCalledFunction();
+ if (!Callee) continue;
+ if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
+ StringRef FuncName = Callee->getName();
+
+ if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
+
+ ++inst;
+
+ }
+
+ SelectInst *selectInst = nullptr;
+
+ if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN)) && 1 == 0) {
+
+ uint32_t vector_cnt = 0;
+ Value *condition = selectInst->getCondition();
+ auto t = condition->getType();
+
+ if (t->getTypeID() == llvm::Type::IntegerTyID) {
+
+ skip_next = 1;
+ inst += 2;
+
+ } else
+
+#if LLVM_VERSION_MAJOR >= 14
+ if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+
+ FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
+ if (tt) {
+
+ uint32_t elements = tt->getElementCount().getFixedValue();
+ vector_cnt = elements;
+ inst += vector_cnt * 2;
- MDNode *N =
- MDNode::get(F.getContext(), MDString::get(F.getContext(), "nosanitize"));
+ }
+
+ } else
+
+#endif
+ {
+
+ continue;
+
+ }
+
+ skip_next = 1;
+
+ } else {
+
+ skip_next = 0;
+
+ }
+
+ }
+
+ if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
+ BlocksToInstrument.push_back(&BB);
+ /*
+ if (Options.IndirectCalls)
+ for (auto &Inst : BB) {
+
+ fprintf(stderr, "FUCK TODO\n");
+ CallBase *CB = dyn_cast<CallBase>(&Inst);
+ if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst);
+ /// XXX TODO!!!! set 0 !
+
+ }
+
+ */
+
+ }
+
+ Fake_InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
+
+ // CTX init
for (auto &BB : F) {
- if (/*F.size() > 1 &&*/ instrument_ctx && &BB == &F.getEntryBlock()) {
+ if (instrument_ctx && &BB == &F.getEntryBlock()) {
// we insert a CTX value in all our callers:
- LLVMContext &Context = F.getContext();
- IRBuilder<> Builder(Context);
+ IRBuilder<> Builder(Context);
for (auto *U : F.users()) {
if (auto *CI = dyn_cast<CallInst>(U)) {
@@ -1323,24 +1421,60 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
}
// We read the CTX for this call
+ Value *CTX_offset;
BasicBlock::iterator IP = BB.getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
LoadInst *PrevCtxLoad = IRB.CreateLoad(
#if LLVM_VERSION_MAJOR >= 14
- Builder.getInt32Ty(),
+ IRB.getInt32Ty(),
#endif
AFLContext);
+
PrevCtxLoad->setMetadata("nosanitize", N);
- PrevCtx = PrevCtxLoad;
+
+ if (inst == inst_save || call_counter < 2) {
+
+ fprintf(stderr, "%s: ZERO!\n", F.getName().str().c_str());
+ CTX_offset = Zero;
+
+ } else {
+
+ fprintf(stderr, "%s: %u * %u\n", F.getName().str().c_str(),
+ inst - inst_save, call_counter);
+ CTX_offset = IRB.CreateMul(
+ ConstantInt::get(Type::getInt32Ty(Context), inst - inst_save),
+ PrevCtxLoad, "CTXmul", false, true);
+
+ }
+
+ CTX_add = IRB.CreateAlloca(Type::getInt32Ty(Context), nullptr, "CTX_add");
+ auto nosan = IRB.CreateStore(CTX_offset, CTX_add);
+ nosan->setMetadata("nosanitize", N);
}
}
+ inst_in_this_func = inst - inst_save;
+ inst = inst_save;
+
+ // Now the real instrumentation
+
+ IsLeafFunc = true;
+ skip_next = 0;
+
for (auto &BB : F) {
+ // fprintf(stderr, "BB: %s\n", BB.getName().str().c_str());
+
for (auto &IN : BB) {
+ /*
+ std::string Str;
+ llvm::raw_string_ostream RSO(Str);
+ IN.print(RSO);
+ errs() << RSO.str() << "\n";
+ */
CallInst *callInst = nullptr;
if ((callInst = dyn_cast<CallInst>(&IN))) {
@@ -1363,8 +1497,16 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue;
- Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
- callInst->setOperand(1, val);
+ IRBuilder<> Builder(Context);
+ Value *val = ConstantInt::get(Int32Ty, ++afl_global_id);
+ LoadInst *CTX_load = Builder.CreateLoad(
+#if LLVM_VERSION_MAJOR >= 14
+ Builder.getInt32Ty(),
+#endif
+ CTX_add);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(CTX_load);
+ Value *val2 = Builder.CreateAdd(val, CTX_load);
+ callInst->setOperand(1, val2);
++inst;
}
@@ -1377,158 +1519,193 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
IN.print(os);
fprintf(stderr, "X(%u): %s\n", skip_next, os.str().c_str());
*/
- if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) {
+ if ((selectInst = dyn_cast<SelectInst>(&IN))) {
- uint32_t vector_cnt = 0;
- Value *condition = selectInst->getCondition();
- Value *result;
- auto t = condition->getType();
- IRBuilder<> IRB(selectInst->getNextNode());
-
- ++select_cnt;
-
- if (t->getTypeID() == llvm::Type::IntegerTyID) {
-
- Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
- Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
- result = IRB.CreateSelect(condition, val1, val2);
- skip_next = 1;
- inst += 2;
+ if (!skip_next) {
- } else
+ uint32_t vector_cnt = 0;
+ Value *condition = selectInst->getCondition();
+ Value *result;
+ auto t = condition->getType();
+ IRBuilder<> IRB(selectInst->getNextNode());
+ // fprintf(stderr, "ADDING!!!\n");
+ LoadInst *CTX_load = IRB.CreateLoad(
#if LLVM_VERSION_MAJOR >= 14
- if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+ IRB.getInt32Ty(),
+#endif
+ CTX_add);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(CTX_load);
- FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
- if (tt) {
+ ++select_cnt;
- uint32_t elements = tt->getElementCount().getFixedValue();
- vector_cnt = elements;
- inst += vector_cnt * 2;
- if (elements) {
+ if (t->getTypeID() == llvm::Type::IntegerTyID) {
- FixedVectorType *GuardPtr1 =
- FixedVectorType::get(Int32Ty, elements);
- FixedVectorType *GuardPtr2 =
- FixedVectorType::get(Int32Ty, elements);
- Value *x, *y;
+ Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val11 = IRB.CreateAdd(val1, CTX_load);
+ Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val22 = IRB.CreateAdd(val2, CTX_load);
+ result = IRB.CreateSelect(condition, val11, val22);
+ skip_next = 1;
+ inst += 2;
- Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
- Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
- x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
- y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
+ } else
+
+#if LLVM_VERSION_MAJOR >= 14
+ if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
+
+ FixedVectorType *tt = dyn_cast<FixedVectorType>(t);
+ if (tt) {
+
+ uint32_t elements = tt->getElementCount().getFixedValue();
+ vector_cnt = elements;
+ inst += vector_cnt * 2;
+ if (elements) {
+
+ FixedVectorType *GuardPtr1 =
+ FixedVectorType::get(Int32Ty, elements);
+ FixedVectorType *GuardPtr2 =
+ FixedVectorType::get(Int32Ty, elements);
+ Value *x, *y;
+
+ Value *val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val11 = IRB.CreateAdd(val1, CTX_add);
+ Value *val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ Value *val22 = IRB.CreateAdd(val2, CTX_add);
+ x = IRB.CreateInsertElement(GuardPtr1, val11, (uint64_t)0);
+ y = IRB.CreateInsertElement(GuardPtr2, val22, (uint64_t)0);
+
+ for (uint64_t i = 1; i < elements; i++) {
+
+ val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ val11 = IRB.CreateAdd(val1, CTX_add);
+ val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
+ val11 = IRB.CreateAdd(val1, CTX_add);
+ x = IRB.CreateInsertElement(GuardPtr1, val11, i);
+ y = IRB.CreateInsertElement(GuardPtr2, val22, i);
- for (uint64_t i = 1; i < elements; i++) {
+ }
- val1 = ConstantInt::get(Int32Ty, ++afl_global_id);
- val2 = ConstantInt::get(Int32Ty, ++afl_global_id);
- x = IRB.CreateInsertElement(GuardPtr1, val1, i);
- y = IRB.CreateInsertElement(GuardPtr2, val2, i);
+ result = IRB.CreateSelect(condition, x, y);
+ skip_next = 1;
}
- result = IRB.CreateSelect(condition, x, y);
- skip_next = 1;
-
}
- }
-
- } else
+ } else
#endif
- {
+ {
- unhandled++;
- continue;
+ unhandled++;
+ continue;
- }
+ }
- uint32_t vector_cur = 0;
- /* Load SHM pointer */
- LoadInst *MapPtr =
- IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
- ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr);
+ uint32_t vector_cur = 0;
+ /* Load SHM pointer */
+ LoadInst *MapPtr =
+ IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr);
- while (1) {
+ while (1) {
- /* Get CurLoc */
- Value *MapPtrIdx = nullptr;
+ /* Get CurLoc */
+ Value *MapPtrIdx = nullptr;
- /* Load counter for CurLoc */
- if (!vector_cnt) {
+ /* Load counter for CurLoc */
+ if (!vector_cnt) {
- MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, result);
+ MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, result);
- } else {
+ } else {
- auto element = IRB.CreateExtractElement(result, vector_cur++);
- MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, element);
+ auto element = IRB.CreateExtractElement(result, vector_cur++);
+ MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, element);
- }
+ }
- if (use_threadsafe_counters) {
+ if (use_threadsafe_counters) {
- IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One,
+ IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx,
+ One,
#if LLVM_VERSION_MAJOR >= 13
- llvm::MaybeAlign(1),
+ llvm::MaybeAlign(1),
#endif
- llvm::AtomicOrdering::Monotonic);
+ llvm::AtomicOrdering::Monotonic);
- } else {
+ } else {
- LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
- ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter);
+ LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter);
- /* Update bitmap */
+ /* Update bitmap */
- Value *Incr = IRB.CreateAdd(Counter, One);
+ Value *Incr = IRB.CreateAdd(Counter, One);
- if (skip_nozero == NULL) {
+ if (skip_nozero == NULL) {
- auto cf = IRB.CreateICmpEQ(Incr, Zero);
- auto carry = IRB.CreateZExt(cf, Int8Ty);
- Incr = IRB.CreateAdd(Incr, carry);
+ auto cf = IRB.CreateICmpEQ(Incr, Zero);
+ auto carry = IRB.CreateZExt(cf, Int8Ty);
+ Incr = IRB.CreateAdd(Incr, carry);
+
+ }
+
+ auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
}
- auto nosan = IRB.CreateStore(Incr, MapPtrIdx);
- ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan);
+ if (!vector_cnt || vector_cnt == vector_cur) { break; }
}
- if (!vector_cnt || vector_cnt == vector_cur) { break; }
+ skip_next = 1;
- }
+ } else {
- skip_next = 1;
+ skip_next = 0;
- } else {
-
- skip_next = 0;
+ }
}
}
- if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
- BlocksToInstrument.push_back(&BB);
- for (auto &Inst : BB) {
+ // if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
+ // BlocksToInstrument.push_back(&BB);
- if (Options.IndirectCalls) {
+ }
- CallBase *CB = dyn_cast<CallBase>(&Inst);
- if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst);
+ InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
+ // InjectCoverageForIndirectCalls(F, IndirCalls);
- }
+ if (inst_in_this_func && call_counter > 1) {
- }
+ extra_ctx_inst += inst_in_this_func * (call_counter - 1);
+ afl_global_id += inst_in_this_func * (call_counter - 1);
}
- InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
- InjectCoverageForIndirectCalls(F, IndirCalls);
+ /*
+ fprintf(stderr, "FUNCTION: %s\n", F.getName().str().c_str());
+ int n = 0;
+ for (auto &BB : F) {
+
+ fprintf(stderr, "BB %d\n", n++);
+ for (auto &IN : BB) {
+
+ std::string Str;
+ llvm::raw_string_ostream RSO(Str);
+ IN.print(RSO);
+ errs() << RSO.str() << "\n";
+
+ }
+
+ }
+
+ */
}
@@ -1654,6 +1831,36 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
}
+// Fake InjectCoverage to count the instrumentations
+bool ModuleSanitizerCoverageLTO::Fake_InjectCoverage(
+ Function &F, ArrayRef<BasicBlock *> AllBlocks, bool IsLeafFunc) {
+
+ if (AllBlocks.empty()) return false;
+
+ for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
+
+ // AFL++ START
+ if (BlockList.size()) {
+
+ int skip = 0;
+ for (uint32_t k = 0; k < BlockList.size(); k++) {
+
+ if (AllBlocks[i] == BlockList[k]) { skip = 1; }
+
+ }
+
+ if (skip) continue;
+
+ }
+
+ inst++; // InjectCoverageAtBlock()
+
+ }
+
+ return true;
+
+}
+
// On every indirect call we call a run-time function
// __sanitizer_cov_indir_call* with two parameters:
// - callee address,
@@ -1725,6 +1932,13 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
/* Set the ID of the inserted basic block */
ConstantInt *CurLoc = ConstantInt::get(Int32Tyi, afl_global_id);
+ LoadInst *CTX_load = IRB.CreateLoad(
+#if LLVM_VERSION_MAJOR >= 14
+ IRB.getInt32Ty(),
+#endif
+ CTX_add);
+ ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(CTX_load);
+ Value *offset = IRB.CreateAdd(CurLoc, CTX_load);
/* Load SHM pointer */
@@ -1732,13 +1946,13 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
if (map_addr) {
- MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtrFixed, CurLoc);
+ MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtrFixed, offset);
} else {
LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr);
- MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc);
+ MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, offset);
}
@@ -1777,8 +1991,6 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
// AFL++ END
/*
- XXXXXXXXXXXXXXXXXXX
-
auto GuardPtr = IRB.CreateIntToPtr(
IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(IntptrTy, Idx * 4)),