From 0a525f768b8b50e6f20a59489f19a4efe84ccfff Mon Sep 17 00:00:00 2001 From: van Hauser Date: Sun, 12 Apr 2020 12:13:01 +0200 Subject: [PATCH] local/global var for compare-transform-pass and code-format --- GNUmakefile | 1 + llvm_mode/afl-clang-fast.c | 8 +- llvm_mode/compare-transform-pass.so.cc | 143 ++++++++++++++++++++++--- test/test-compcov.c | 15 ++- test/test-custom-mutator.c | 19 ++-- test/test-unsigaction.c | 48 +++++---- 6 files changed, 184 insertions(+), 50 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 00b357f9..a3ac2e06 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -360,6 +360,7 @@ code-format: ./.custom-format.py -i gcc_plugin/*.cc ./.custom-format.py -i examples/*/*.c ./.custom-format.py -i examples/*/*.h + ./.custom-format.py -i test/*.c ./.custom-format.py -i qemu_mode/patches/*.h ./.custom-format.py -i qemu_mode/libcompcov/*.c ./.custom-format.py -i qemu_mode/libcompcov/*.cc diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index 2114ccf3..080c7838 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -401,9 +401,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if (getenv("AFL_NO_BUILTIN") || (instrument_mode == INSTRUMENT_LTO && - (getenv("AFL_LLVM_LTO_AUTODICTIONARY") || - getenv("AFL_LLVM_AUTODICTIONARY")))) { + if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") || + getenv("LAF_TRANSFORM_COMPARES") || + (instrument_mode == INSTRUMENT_LTO && + (getenv("AFL_LLVM_LTO_AUTODICTIONARY") || + getenv("AFL_LLVM_AUTODICTIONARY")))) { cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc index 2ca70659..84a9b8d9 100644 --- a/llvm_mode/compare-transform-pass.so.cc +++ b/llvm_mode/compare-transform-pass.so.cc @@ -112,11 +112,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const bool processStrcasecmp, const bool processStrncasecmp) { - std::vector calls; - LLVMContext & C = M.getContext(); - IntegerType * Int8Ty = IntegerType::getInt8Ty(C); - IntegerType * Int32Ty = IntegerType::getInt32Ty(C); - IntegerType * Int64Ty = IntegerType::getInt64Ty(C); + DenseMap valueMap; + std::vector calls; + LLVMContext & C = M.getContext(); + IntegerType * Int8Ty = IntegerType::getInt8Ty(C); + IntegerType * Int32Ty = IntegerType::getInt32Ty(C); + IntegerType * Int64Ty = IntegerType::getInt64Ty(C); #if LLVM_VERSION_MAJOR < 9 Constant * @@ -263,6 +264,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool isStrncmp = processStrncmp; bool isStrcasecmp = processStrcasecmp; bool isStrncasecmp = processStrncasecmp; + bool isIntMemcpy = true; + bool indirect = false; Function *Callee = callInst->getCalledFunction(); if (!Callee) continue; @@ -273,9 +276,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, isStrncmp &= !FuncName.compare(StringRef("strncmp")); isStrcasecmp &= !FuncName.compare(StringRef("strcasecmp")); isStrncasecmp &= !FuncName.compare(StringRef("strncasecmp")); + isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64"); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp) + !isStrncasecmp && !isIntMemcpy) continue; /* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function @@ -309,7 +313,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, FT->getParamType(2)->isIntegerTy(); if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp && - !isStrncasecmp) + !isStrncasecmp && !isIntMemcpy) continue; /* is a str{n,}{case,}cmp/memcmp, check if we have @@ -322,6 +326,97 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool HasStr1 = getConstantStringInfo(Str1P, Str1); bool HasStr2 = getConstantStringInfo(Str2P, Str2); + if (isIntMemcpy && HasStr2) { + + valueMap[Str1P] = new std::string(Str2.str()); + // fprintf(stderr, "saved %s for %p\n", Str2.str().c_str(), Str1P); + continue; + + } + + // not literal? maybe global or local variable + if (!(HasStr1 ^ HasStr2)) { + + auto *Ptr = dyn_cast(Str2P); + if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + + if (auto *Var = dyn_cast(Ptr->getOperand(0))) { + + if (auto *Array = + dyn_cast(Var->getInitializer())) { + + HasStr2 = true; + Str2 = Array->getAsString(); + valueMap[Str2P] = new std::string(Str2.str()); + // fprintf(stderr, "glo2 %s\n", Str2.str().c_str()); + + } + + } + + } + + if (!HasStr2) { + + auto *Ptr = dyn_cast(Str1P); + if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + + if (auto *Var = dyn_cast(Ptr->getOperand(0))) { + + if (auto *Array = + dyn_cast(Var->getInitializer())) { + + HasStr1 = true; + Str1 = Array->getAsString(); + valueMap[Str1P] = new std::string(Str1.str()); + // fprintf(stderr, "glo1 %s\n", Str1.str().c_str()); + + } + + } + + } + + } else if (isIntMemcpy) { + + valueMap[Str1P] = new std::string(Str2.str()); + // fprintf(stderr, "saved\n"); + + } + + if ((HasStr1 ^ HasStr2)) indirect = true; + + } + + if (isIntMemcpy) continue; + + if (!(HasStr1 ^ HasStr2)) { + + // do we have a saved local variable initialization? + std::string *val = valueMap[Str1P]; + if (val && !val->empty()) { + + Str1 = StringRef(*val); + HasStr1 = true; + indirect = true; + // fprintf(stderr, "loaded1 %s\n", Str1.str().c_str()); + + } else { + + val = valueMap[Str2P]; + if (val && !val->empty()) { + + Str2 = StringRef(*val); + HasStr2 = true; + indirect = true; + // fprintf(stderr, "loaded2 %s\n", Str2.str().c_str()); + + } + + } + + } + /* handle cases of one string is const, one string is variable */ if (!(HasStr1 ^ HasStr2)) continue; @@ -334,9 +429,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!ilen) continue; /* final precaution: if size of compare is larger than constant * string skip it*/ - uint64_t literalLength = - HasStr1 ? GetStringLength(Str1P) : GetStringLength(Str2P); - if (literalLength < ilen->getZExtValue()) continue; + uint64_t literalLength = HasStr1 ? Str1.size() : Str2.size(); + if (literalLength + 1 < ilen->getZExtValue()) continue; } @@ -363,9 +457,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, std::string TmpConstStr; Value * VarStr; bool HasStr1 = getConstantStringInfo(Str1P, Str1); - getConstantStringInfo(Str2P, Str2); - uint64_t constLen, sizedLen; - bool isMemcmp = + bool HasStr2 = getConstantStringInfo(Str2P, Str2); + uint64_t constLen, sizedLen; + bool isMemcmp = !callInst->getCalledFunction()->getName().compare(StringRef("memcmp")); bool isSizedcmp = isMemcmp || !callInst->getCalledFunction()->getName().compare( @@ -389,6 +483,29 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } + if (!(HasStr1 ^ HasStr2)) { + + // do we have a saved local or global variable initialization? + std::string *val = valueMap[Str1P]; + if (val && !val->empty()) { + + Str1 = StringRef(*val); + HasStr1 = true; + + } else { + + val = valueMap[Str2P]; + if (val && !val->empty()) { + + Str2 = StringRef(*val); + HasStr2 = true; + + } + + } + + } + if (HasStr1) { TmpConstStr = Str1.str(); diff --git a/test/test-compcov.c b/test/test-compcov.c index fff9c759..f1743265 100644 --- a/test/test-compcov.c +++ b/test/test-compcov.c @@ -6,27 +6,33 @@ char global_cmpval[] = "GLOBALVARIABLE"; int main(int argc, char **argv) { + char *input = argv[1], *buf, buffer[20]; - char cmpval[] = "LOCALVARIABLE"; - char shortval[4] = "abc"; + char cmpval[] = "LOCALVARIABLE"; + char shortval[4] = "abc"; if (argc < 2) { + ssize_t ret = read(0, buffer, sizeof(buffer) - 1); buffer[ret] = 0; input = buffer; + } - + if (strcmp(input, "LIBTOKENCAP") == 0) printf("your string was libtokencap\n"); else if (strcmp(input, "BUGMENOT") == 0) printf("your string was bugmenot\n"); else if (strcmp(input, "BUFFEROVERFLOW") == 0) { + buf = malloc(16); strcpy(buf, "TEST"); strcat(buf, input); printf("This will only crash with libdislocator: %s\n", buf); return 0; - } else if (*(unsigned int*)input == 0xabadcafe) + + } else if (*(unsigned int *)input == 0xabadcafe) + printf("GG you eat cmp tokens for breakfast!\n"); else if (memcmp(cmpval, input, 8) == 0) printf("local var memcmp works!\n"); @@ -40,3 +46,4 @@ int main(int argc, char **argv) { return 0; } + diff --git a/test/test-custom-mutator.c b/test/test-custom-mutator.c index 83baafab..f868550c 100644 --- a/test/test-custom-mutator.c +++ b/test/test-custom-mutator.c @@ -1,5 +1,6 @@ /** - * Reference: https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c + * Reference: + * https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/blob/master/4_libprotobuf_aflpp_custom_mutator/vuln.c */ #include @@ -8,12 +9,12 @@ #include #include -int main(int argc, char *argv[]) -{ - char str[100]; - read(0, str, 100); - if( str[6] == 'A') { - abort(); - } - return 0; +int main(int argc, char *argv[]) { + + char str[100]; + read(0, str, 100); + if (str[6] == 'A') { abort(); } + return 0; + } + diff --git a/test/test-unsigaction.c b/test/test-unsigaction.c index 1a5e4b26..8c6c7f41 100644 --- a/test/test-unsigaction.c +++ b/test/test-unsigaction.c @@ -1,25 +1,31 @@ -#include /* sigemptyset(), sigaction(), kill(), SIGUSR1 */ -#include /* exit() */ -#include /* getpid() */ -#include /* errno */ -#include /* fprintf() */ +#include /* sigemptyset(), sigaction(), kill(), SIGUSR1 */ +#include /* exit() */ +#include /* getpid() */ +#include /* errno */ +#include /* fprintf() */ + +static void mysig_handler(int sig) { + + exit(2); -static void mysig_handler(int sig) -{ - exit(2); } -int main() -{ - /* setup sig handler */ - struct sigaction sa; - sa.sa_handler = mysig_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGCHLD, &sa, NULL)) { - fprintf(stderr, "could not set signal handler %d, aborted\n", errno); - exit(1); - } - kill(getpid(), SIGCHLD); - return 0; +int main() { + + /* setup sig handler */ + struct sigaction sa; + sa.sa_handler = mysig_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCHLD, &sa, NULL)) { + + fprintf(stderr, "could not set signal handler %d, aborted\n", errno); + exit(1); + + } + + kill(getpid(), SIGCHLD); + return 0; + } +