local/global var for compare-transform-pass and code-format
MODIFY
GNUmakefile
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

MODIFY
llvm_mode/afl-clang-fast.c
llvm_mode/afl-clang-fast.c
@@ -401,7 +401,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (getenv("AFL_NO_BUILTIN") || (instrument_mode == INSTRUMENT_LTO &&
+ 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")))) {

MODIFY
llvm_mode/compare-transform-pass.so.cc
llvm_mode/compare-transform-pass.so.cc
@@ -112,6 +112,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
const bool processStrcasecmp,
const bool processStrncasecmp) {
+ DenseMap<Value *, std::string *> valueMap;
std::vector<CallInst *> calls;
LLVMContext & C = M.getContext();
IntegerType * Int8Ty = IntegerType::getInt8Ty(C);
@@ -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<ConstantExpr>(Str2P);
+ if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
+
+ if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
+
+ if (auto *Array =
+ dyn_cast<ConstantDataArray>(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<ConstantExpr>(Str1P);
+ if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
+
+ if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
+
+ if (auto *Array =
+ dyn_cast<ConstantDataArray>(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,7 +457,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
std::string TmpConstStr;
Value * VarStr;
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
- getConstantStringInfo(Str2P, Str2);
+ bool HasStr2 = getConstantStringInfo(Str2P, Str2);
uint64_t constLen, sizedLen;
bool isMemcmp =
!callInst->getCalledFunction()->getName().compare(StringRef("memcmp"));
@@ -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();

MODIFY
test/test-compcov.c
test/test-compcov.c
char global_cmpval[] = "GLOBALVARIABLE";
int main(int argc, char **argv) {
+
char *input = argv[1], *buf, buffer[20];
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)
@@ -21,12 +24,15 @@ int main(int argc, char **argv) {
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)
+
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;
}
+

MODIFY
test/test-custom-mutator.c
test/test-custom-mutator.c
/**
- * 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
+
char str[100];
read(0, str, 100);
- if( str[6] == 'A') {
- abort();
- }
+ if (str[6] == 'A') { abort(); }
return 0;
+
}
+

MODIFY
test/test-unsigaction.c
test/test-unsigaction.c
#include <errno.h> /* errno */
#include <stdio.h> /* fprintf() */
-static void mysig_handler(int sig)
-{
+static void mysig_handler(int sig) {
+
exit(2);
+
}
-int main()
-{
+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;
+
}
+

local/global var for compare-transform-pass and code-format