mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-11 01:31:37 +00:00
Merge branch 'dev' of github.com:aflplusplus/aflplusplus into dev
This commit is contained in:
commit
a22c8ffdf2
@ -32,6 +32,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- fixed endless loop for allow/blocklist lines starting with a
|
- fixed endless loop for allow/blocklist lines starting with a
|
||||||
comment (thanks to Zherya for reporting)
|
comment (thanks to Zherya for reporting)
|
||||||
- cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit
|
- cmplog/redqueen now also tracks floating point, _ExtInt() + 128bit
|
||||||
|
- cmplog/redqueen can now process basic libc++ and libstdc++
|
||||||
|
std::string comparisons (though no position or length type variants)
|
||||||
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
||||||
support (less performant than our own), GCC for old afl-gcc and
|
support (less performant than our own), GCC for old afl-gcc and
|
||||||
CLANG for old afl-clang
|
CLANG for old afl-clang
|
||||||
|
@ -1549,10 +1549,10 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
|
|||||||
u32 i;
|
u32 i;
|
||||||
if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return;
|
if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return;
|
||||||
fprintf(stderr, "rtn arg0=");
|
fprintf(stderr, "rtn arg0=");
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 24; i++)
|
||||||
fprintf(stderr, "%02x", ptr1[i]);
|
fprintf(stderr, "%02x", ptr1[i]);
|
||||||
fprintf(stderr, " arg1=");
|
fprintf(stderr, " arg1=");
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 24; i++)
|
||||||
fprintf(stderr, "%02x", ptr2[i]);
|
fprintf(stderr, "%02x", ptr2[i]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
*/
|
*/
|
||||||
@ -1594,6 +1594,71 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gcc libstdc++
|
||||||
|
// _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc
|
||||||
|
static u8 *get_gcc_stdstring(u8 *string) {
|
||||||
|
|
||||||
|
u32 *len = (u32 *)(string + 8);
|
||||||
|
|
||||||
|
if (*len < 16) { // in structure
|
||||||
|
|
||||||
|
return (string + 16);
|
||||||
|
|
||||||
|
} else { // in memory
|
||||||
|
|
||||||
|
u8 **ptr = (u8 **)string;
|
||||||
|
return (*ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// llvm libc++ _ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocator
|
||||||
|
// IcEEE7compareEmmPKcm
|
||||||
|
static u8 *get_llvm_stdstring(u8 *string) {
|
||||||
|
|
||||||
|
// length is in: if ((string[0] & 1) == 0) u8 len = (string[0] >> 1);
|
||||||
|
// or: if (string[0] & 1) u32 *len = (u32 *) (string + 8);
|
||||||
|
|
||||||
|
if (string[0] & 1) { // in memory
|
||||||
|
|
||||||
|
u8 **ptr = (u8 **)(string + 16);
|
||||||
|
return (*ptr);
|
||||||
|
|
||||||
|
} else { // in structure
|
||||||
|
|
||||||
|
return (string + 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cmplog_rtn_gcc_stdstring_cstring(u8 *stdstring, u8 *cstring) {
|
||||||
|
|
||||||
|
__cmplog_rtn_hook(get_gcc_stdstring(stdstring), cstring);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cmplog_rtn_gcc_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) {
|
||||||
|
|
||||||
|
__cmplog_rtn_hook(get_gcc_stdstring(stdstring1),
|
||||||
|
get_gcc_stdstring(stdstring2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cmplog_rtn_llvm_stdstring_cstring(u8 *stdstring, u8 *cstring) {
|
||||||
|
|
||||||
|
__cmplog_rtn_hook(get_llvm_stdstring(stdstring), cstring);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cmplog_rtn_llvm_stdstring_stdstring(u8 *stdstring1, u8 *stdstring2) {
|
||||||
|
|
||||||
|
__cmplog_rtn_hook(get_llvm_stdstring(stdstring1),
|
||||||
|
get_llvm_stdstring(stdstring2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* COVERAGE manipulation features */
|
/* COVERAGE manipulation features */
|
||||||
|
|
||||||
// this variable is then used in the shm setup to create an additional map
|
// this variable is then used in the shm setup to create an additional map
|
||||||
|
@ -87,7 +87,7 @@ char CmpLogRoutines::ID = 0;
|
|||||||
|
|
||||||
bool CmpLogRoutines::hookRtns(Module &M) {
|
bool CmpLogRoutines::hookRtns(Module &M) {
|
||||||
|
|
||||||
std::vector<CallInst *> calls;
|
std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC;
|
||||||
LLVMContext & C = M.getContext();
|
LLVMContext & C = M.getContext();
|
||||||
|
|
||||||
Type *VoidTy = Type::getVoidTy(C);
|
Type *VoidTy = Type::getVoidTy(C);
|
||||||
@ -112,6 +112,78 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
FunctionCallee cmplogHookFn = c;
|
FunctionCallee cmplogHookFn = c;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Constant *
|
||||||
|
#else
|
||||||
|
FunctionCallee
|
||||||
|
#endif
|
||||||
|
c1 = M.getOrInsertFunction("__cmplog_rtn_llvm_stdstring_stdstring",
|
||||||
|
VoidTy, i8PtrTy, i8PtrTy
|
||||||
|
#if LLVM_VERSION_MAJOR < 5
|
||||||
|
,
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Function *cmplogLlvmStdStd = cast<Function>(c1);
|
||||||
|
#else
|
||||||
|
FunctionCallee cmplogLlvmStdStd = c1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Constant *
|
||||||
|
#else
|
||||||
|
FunctionCallee
|
||||||
|
#endif
|
||||||
|
c2 = M.getOrInsertFunction("__cmplog_rtn_llvm_stdstring_cstring", VoidTy,
|
||||||
|
i8PtrTy, i8PtrTy
|
||||||
|
#if LLVM_VERSION_MAJOR < 5
|
||||||
|
,
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Function *cmplogLlvmStdC = cast<Function>(c2);
|
||||||
|
#else
|
||||||
|
FunctionCallee cmplogLlvmStdC = c2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Constant *
|
||||||
|
#else
|
||||||
|
FunctionCallee
|
||||||
|
#endif
|
||||||
|
c3 = M.getOrInsertFunction("__cmplog_rtn_gcc_stdstring_stdstring", VoidTy,
|
||||||
|
i8PtrTy, i8PtrTy
|
||||||
|
#if LLVM_VERSION_MAJOR < 5
|
||||||
|
,
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Function *cmplogGccStdStd = cast<Function>(c3);
|
||||||
|
#else
|
||||||
|
FunctionCallee cmplogGccStdStd = c3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Constant *
|
||||||
|
#else
|
||||||
|
FunctionCallee
|
||||||
|
#endif
|
||||||
|
c4 = M.getOrInsertFunction("__cmplog_rtn_gcc_stdstring_cstring", VoidTy,
|
||||||
|
i8PtrTy, i8PtrTy
|
||||||
|
#if LLVM_VERSION_MAJOR < 5
|
||||||
|
,
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
Function *cmplogGccStdC = cast<Function>(c4);
|
||||||
|
#else
|
||||||
|
FunctionCallee cmplogGccStdC = c4;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* iterate over all functions, bbs and instruction and add suitable calls */
|
/* iterate over all functions, bbs and instruction and add suitable calls */
|
||||||
for (auto &F : M) {
|
for (auto &F : M) {
|
||||||
|
|
||||||
@ -136,9 +208,64 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
FT->getParamType(0) == FT->getParamType(1) &&
|
FT->getParamType(0) == FT->getParamType(1) &&
|
||||||
FT->getParamType(0)->isPointerTy();
|
FT->getParamType(0)->isPointerTy();
|
||||||
|
|
||||||
if (!isPtrRtn) continue;
|
bool isGccStdStringStdString =
|
||||||
|
Callee->getName().find("__is_charIT_EE7__value") !=
|
||||||
|
std::string::npos &&
|
||||||
|
Callee->getName().find(
|
||||||
|
"St7__cxx1112basic_stringIS2_St11char_traits") !=
|
||||||
|
std::string::npos &&
|
||||||
|
FT->getNumParams() >= 2 &&
|
||||||
|
FT->getParamType(0) == FT->getParamType(1) &&
|
||||||
|
FT->getParamType(0)->isPointerTy();
|
||||||
|
|
||||||
calls.push_back(callInst);
|
bool isGccStdStringCString =
|
||||||
|
Callee->getName().find(
|
||||||
|
"St7__cxx1112basic_stringIcSt11char_"
|
||||||
|
"traitsIcESaIcEE7compareEPK") != std::string::npos &&
|
||||||
|
FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
|
||||||
|
FT->getParamType(1)->isPointerTy();
|
||||||
|
|
||||||
|
bool isLlvmStdStringStdString =
|
||||||
|
Callee->getName().find("_ZNSt3__1eqI") != std::string::npos &&
|
||||||
|
Callee->getName().find("_12basic_stringI") != std::string::npos &&
|
||||||
|
Callee->getName().find("_11char_traits") != std::string::npos &&
|
||||||
|
FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
|
||||||
|
FT->getParamType(1)->isPointerTy();
|
||||||
|
|
||||||
|
bool isLlvmStdStringCString =
|
||||||
|
Callee->getName().find("_ZNSt3__1eqI") != std::string::npos &&
|
||||||
|
Callee->getName().find("_12basic_stringI") != std::string::npos &&
|
||||||
|
FT->getNumParams() >= 2 && FT->getParamType(0)->isPointerTy() &&
|
||||||
|
FT->getParamType(1)->isPointerTy();
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stderr, "F:%s C:%s argc:%u\n",
|
||||||
|
F.getName().str().c_str(),
|
||||||
|
Callee->getName().str().c_str(), FT->getNumParams());
|
||||||
|
fprintf(stderr, "ptr0:%u ptr1:%u ptr2:%u\n",
|
||||||
|
FT->getParamType(0)->isPointerTy(),
|
||||||
|
FT->getParamType(1)->isPointerTy(),
|
||||||
|
FT->getNumParams() > 2 ?
|
||||||
|
FT->getParamType(2)->isPointerTy() : 22 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (isGccStdStringCString || isGccStdStringStdString ||
|
||||||
|
isLlvmStdStringStdString || isLlvmStdStringCString) {
|
||||||
|
|
||||||
|
isPtrRtn = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPtrRtn) { calls.push_back(callInst); }
|
||||||
|
if (isGccStdStringStdString) { gccStdStd.push_back(callInst); }
|
||||||
|
if (isGccStdStringCString) { gccStdC.push_back(callInst); }
|
||||||
|
if (isLlvmStdStringStdString) { llvmStdStd.push_back(callInst); }
|
||||||
|
if (isLlvmStdStringCString) { llvmStdC.push_back(callInst); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +275,10 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!calls.size()) return false;
|
if (!calls.size() && !gccStdStd.size() && !gccStdC.size() &&
|
||||||
|
!llvmStdStd.size() && !llvmStdC.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (!be_quiet)
|
if (!be_quiet)
|
||||||
errs() << "Hooking " << calls.size()
|
errs() << "Hooking " << calls.size()
|
||||||
@ -174,6 +304,82 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &callInst : gccStdStd) {
|
||||||
|
|
||||||
|
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
|
||||||
|
|
||||||
|
IRBuilder<> IRB(callInst->getParent());
|
||||||
|
IRB.SetInsertPoint(callInst);
|
||||||
|
|
||||||
|
std::vector<Value *> args;
|
||||||
|
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||||
|
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||||
|
args.push_back(v1Pcasted);
|
||||||
|
args.push_back(v2Pcasted);
|
||||||
|
|
||||||
|
IRB.CreateCall(cmplogGccStdStd, args);
|
||||||
|
|
||||||
|
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &callInst : gccStdC) {
|
||||||
|
|
||||||
|
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
|
||||||
|
|
||||||
|
IRBuilder<> IRB(callInst->getParent());
|
||||||
|
IRB.SetInsertPoint(callInst);
|
||||||
|
|
||||||
|
std::vector<Value *> args;
|
||||||
|
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||||
|
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||||
|
args.push_back(v1Pcasted);
|
||||||
|
args.push_back(v2Pcasted);
|
||||||
|
|
||||||
|
IRB.CreateCall(cmplogGccStdC, args);
|
||||||
|
|
||||||
|
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &callInst : llvmStdStd) {
|
||||||
|
|
||||||
|
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
|
||||||
|
|
||||||
|
IRBuilder<> IRB(callInst->getParent());
|
||||||
|
IRB.SetInsertPoint(callInst);
|
||||||
|
|
||||||
|
std::vector<Value *> args;
|
||||||
|
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||||
|
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||||
|
args.push_back(v1Pcasted);
|
||||||
|
args.push_back(v2Pcasted);
|
||||||
|
|
||||||
|
IRB.CreateCall(cmplogLlvmStdStd, args);
|
||||||
|
|
||||||
|
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &callInst : llvmStdC) {
|
||||||
|
|
||||||
|
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
|
||||||
|
|
||||||
|
IRBuilder<> IRB(callInst->getParent());
|
||||||
|
IRB.SetInsertPoint(callInst);
|
||||||
|
|
||||||
|
std::vector<Value *> args;
|
||||||
|
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||||
|
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||||
|
args.push_back(v1Pcasted);
|
||||||
|
args.push_back(v2Pcasted);
|
||||||
|
|
||||||
|
IRB.CreateCall(cmplogLlvmStdC, args);
|
||||||
|
|
||||||
|
// errs() << callInst->getCalledFunction()->getName() << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
|
|
||||||
while (q) {
|
while (q) {
|
||||||
|
|
||||||
u8 use_mem[MAX_FILE];
|
u8 *use_mem = afl_realloc(AFL_BUF_PARAM(in), MAX_FILE);
|
||||||
u8 res;
|
u8 res;
|
||||||
s32 fd;
|
s32 fd;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user