mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 02:28:09 +00:00
local/global var for compare-transform-pass and code-format
This commit is contained in:
@ -360,6 +360,7 @@ code-format:
|
|||||||
./.custom-format.py -i gcc_plugin/*.cc
|
./.custom-format.py -i gcc_plugin/*.cc
|
||||||
./.custom-format.py -i examples/*/*.c
|
./.custom-format.py -i examples/*/*.c
|
||||||
./.custom-format.py -i examples/*/*.h
|
./.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/patches/*.h
|
||||||
./.custom-format.py -i qemu_mode/libcompcov/*.c
|
./.custom-format.py -i qemu_mode/libcompcov/*.c
|
||||||
./.custom-format.py -i qemu_mode/libcompcov/*.cc
|
./.custom-format.py -i qemu_mode/libcompcov/*.cc
|
||||||
|
@ -401,9 +401,11 @@ 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("AFL_LLVM_LTO_AUTODICTIONARY") ||
|
getenv("LAF_TRANSFORM_COMPARES") ||
|
||||||
getenv("AFL_LLVM_AUTODICTIONARY")))) {
|
(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-strcmp";
|
||||||
cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
|
cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
|
||||||
|
@ -112,11 +112,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
const bool processStrcasecmp,
|
const bool processStrcasecmp,
|
||||||
const bool processStrncasecmp) {
|
const bool processStrncasecmp) {
|
||||||
|
|
||||||
std::vector<CallInst *> calls;
|
DenseMap<Value *, std::string *> valueMap;
|
||||||
LLVMContext & C = M.getContext();
|
std::vector<CallInst *> calls;
|
||||||
IntegerType * Int8Ty = IntegerType::getInt8Ty(C);
|
LLVMContext & C = M.getContext();
|
||||||
IntegerType * Int32Ty = IntegerType::getInt32Ty(C);
|
IntegerType * Int8Ty = IntegerType::getInt8Ty(C);
|
||||||
IntegerType * Int64Ty = IntegerType::getInt64Ty(C);
|
IntegerType * Int32Ty = IntegerType::getInt32Ty(C);
|
||||||
|
IntegerType * Int64Ty = IntegerType::getInt64Ty(C);
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 9
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
Constant *
|
Constant *
|
||||||
@ -263,6 +264,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
bool isStrncmp = processStrncmp;
|
bool isStrncmp = processStrncmp;
|
||||||
bool isStrcasecmp = processStrcasecmp;
|
bool isStrcasecmp = processStrcasecmp;
|
||||||
bool isStrncasecmp = processStrncasecmp;
|
bool isStrncasecmp = processStrncasecmp;
|
||||||
|
bool isIntMemcpy = true;
|
||||||
|
bool indirect = false;
|
||||||
|
|
||||||
Function *Callee = callInst->getCalledFunction();
|
Function *Callee = callInst->getCalledFunction();
|
||||||
if (!Callee) continue;
|
if (!Callee) continue;
|
||||||
@ -273,9 +276,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
isStrncmp &= !FuncName.compare(StringRef("strncmp"));
|
isStrncmp &= !FuncName.compare(StringRef("strncmp"));
|
||||||
isStrcasecmp &= !FuncName.compare(StringRef("strcasecmp"));
|
isStrcasecmp &= !FuncName.compare(StringRef("strcasecmp"));
|
||||||
isStrncasecmp &= !FuncName.compare(StringRef("strncasecmp"));
|
isStrncasecmp &= !FuncName.compare(StringRef("strncasecmp"));
|
||||||
|
isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64");
|
||||||
|
|
||||||
if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
|
if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
|
||||||
!isStrncasecmp)
|
!isStrncasecmp && !isIntMemcpy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function
|
/* Verify the strcmp/memcmp/strncmp/strcasecmp/strncasecmp function
|
||||||
@ -309,7 +313,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
FT->getParamType(2)->isIntegerTy();
|
FT->getParamType(2)->isIntegerTy();
|
||||||
|
|
||||||
if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
|
if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
|
||||||
!isStrncasecmp)
|
!isStrncasecmp && !isIntMemcpy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* is a str{n,}{case,}cmp/memcmp, check if we have
|
/* 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 HasStr1 = getConstantStringInfo(Str1P, Str1);
|
||||||
bool HasStr2 = getConstantStringInfo(Str2P, Str2);
|
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 */
|
/* handle cases of one string is const, one string is variable */
|
||||||
if (!(HasStr1 ^ HasStr2)) continue;
|
if (!(HasStr1 ^ HasStr2)) continue;
|
||||||
|
|
||||||
@ -334,9 +429,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
if (!ilen) continue;
|
if (!ilen) continue;
|
||||||
/* final precaution: if size of compare is larger than constant
|
/* final precaution: if size of compare is larger than constant
|
||||||
* string skip it*/
|
* string skip it*/
|
||||||
uint64_t literalLength =
|
uint64_t literalLength = HasStr1 ? Str1.size() : Str2.size();
|
||||||
HasStr1 ? GetStringLength(Str1P) : GetStringLength(Str2P);
|
if (literalLength + 1 < ilen->getZExtValue()) continue;
|
||||||
if (literalLength < ilen->getZExtValue()) continue;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,9 +457,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
std::string TmpConstStr;
|
std::string TmpConstStr;
|
||||||
Value * VarStr;
|
Value * VarStr;
|
||||||
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
|
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
|
||||||
getConstantStringInfo(Str2P, Str2);
|
bool HasStr2 = getConstantStringInfo(Str2P, Str2);
|
||||||
uint64_t constLen, sizedLen;
|
uint64_t constLen, sizedLen;
|
||||||
bool isMemcmp =
|
bool isMemcmp =
|
||||||
!callInst->getCalledFunction()->getName().compare(StringRef("memcmp"));
|
!callInst->getCalledFunction()->getName().compare(StringRef("memcmp"));
|
||||||
bool isSizedcmp = isMemcmp ||
|
bool isSizedcmp = isMemcmp ||
|
||||||
!callInst->getCalledFunction()->getName().compare(
|
!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) {
|
if (HasStr1) {
|
||||||
|
|
||||||
TmpConstStr = Str1.str();
|
TmpConstStr = Str1.str();
|
||||||
|
@ -6,27 +6,33 @@
|
|||||||
char global_cmpval[] = "GLOBALVARIABLE";
|
char global_cmpval[] = "GLOBALVARIABLE";
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
char *input = argv[1], *buf, buffer[20];
|
char *input = argv[1], *buf, buffer[20];
|
||||||
char cmpval[] = "LOCALVARIABLE";
|
char cmpval[] = "LOCALVARIABLE";
|
||||||
char shortval[4] = "abc";
|
char shortval[4] = "abc";
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
|
||||||
ssize_t ret = read(0, buffer, sizeof(buffer) - 1);
|
ssize_t ret = read(0, buffer, sizeof(buffer) - 1);
|
||||||
buffer[ret] = 0;
|
buffer[ret] = 0;
|
||||||
input = buffer;
|
input = buffer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(input, "LIBTOKENCAP") == 0)
|
if (strcmp(input, "LIBTOKENCAP") == 0)
|
||||||
printf("your string was libtokencap\n");
|
printf("your string was libtokencap\n");
|
||||||
else if (strcmp(input, "BUGMENOT") == 0)
|
else if (strcmp(input, "BUGMENOT") == 0)
|
||||||
printf("your string was bugmenot\n");
|
printf("your string was bugmenot\n");
|
||||||
else if (strcmp(input, "BUFFEROVERFLOW") == 0) {
|
else if (strcmp(input, "BUFFEROVERFLOW") == 0) {
|
||||||
|
|
||||||
buf = malloc(16);
|
buf = malloc(16);
|
||||||
strcpy(buf, "TEST");
|
strcpy(buf, "TEST");
|
||||||
strcat(buf, input);
|
strcat(buf, input);
|
||||||
printf("This will only crash with libdislocator: %s\n", buf);
|
printf("This will only crash with libdislocator: %s\n", buf);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (*(unsigned int*)input == 0xabadcafe)
|
|
||||||
|
} else if (*(unsigned int *)input == 0xabadcafe)
|
||||||
|
|
||||||
printf("GG you eat cmp tokens for breakfast!\n");
|
printf("GG you eat cmp tokens for breakfast!\n");
|
||||||
else if (memcmp(cmpval, input, 8) == 0)
|
else if (memcmp(cmpval, input, 8) == 0)
|
||||||
printf("local var memcmp works!\n");
|
printf("local var memcmp works!\n");
|
||||||
@ -40,3 +46,4 @@ int main(int argc, char **argv) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 <stdio.h>
|
#include <stdio.h>
|
||||||
@ -8,12 +9,12 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[]) {
|
||||||
{
|
|
||||||
char str[100];
|
char str[100];
|
||||||
read(0, str, 100);
|
read(0, str, 100);
|
||||||
if( str[6] == 'A') {
|
if (str[6] == 'A') { abort(); }
|
||||||
abort();
|
return 0;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,31 @@
|
|||||||
#include <signal.h> /* sigemptyset(), sigaction(), kill(), SIGUSR1 */
|
#include <signal.h> /* sigemptyset(), sigaction(), kill(), SIGUSR1 */
|
||||||
#include <stdlib.h> /* exit() */
|
#include <stdlib.h> /* exit() */
|
||||||
#include <unistd.h> /* getpid() */
|
#include <unistd.h> /* getpid() */
|
||||||
#include <errno.h> /* errno */
|
#include <errno.h> /* errno */
|
||||||
#include <stdio.h> /* fprintf() */
|
#include <stdio.h> /* fprintf() */
|
||||||
|
|
||||||
|
static void mysig_handler(int sig) {
|
||||||
|
|
||||||
|
exit(2);
|
||||||
|
|
||||||
static void mysig_handler(int sig)
|
|
||||||
{
|
|
||||||
exit(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
/* setup sig handler */
|
/* setup sig handler */
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_handler = mysig_handler;
|
sa.sa_handler = mysig_handler;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
if (sigaction(SIGCHLD, &sa, NULL)) {
|
if (sigaction(SIGCHLD, &sa, NULL)) {
|
||||||
fprintf(stderr, "could not set signal handler %d, aborted\n", errno);
|
|
||||||
exit(1);
|
fprintf(stderr, "could not set signal handler %d, aborted\n", errno);
|
||||||
}
|
exit(1);
|
||||||
kill(getpid(), SIGCHLD);
|
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
kill(getpid(), SIGCHLD);
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user