mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-23 14:34:25 +00:00
@ -57,6 +57,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- added AFL_USE_TSAN thread sanitizer support
|
||||
- llvm and LTO mode modified to work with new llvm 14-dev (again. again.)
|
||||
- fix for AFL_REAL_LD
|
||||
- make -v without options work
|
||||
- added the very good grammar mutator "GramaTron" to the
|
||||
custom_mutators
|
||||
- added optimin, a faster and better corpus minimizer by
|
||||
|
@ -397,7 +397,7 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
target. This must be equal or larger than the size the target was compiled
|
||||
with.
|
||||
|
||||
- Setting `AFL_MAX_DET_EXRAS` will change the threshold at what number of
|
||||
- Setting `AFL_MAX_DET_EXTRAS` will change the threshold at what number of
|
||||
elements in the `-x` dictionary and LTO autodict (combined) the
|
||||
probabilistic mode will kick off. In probabilistic mode, not all dictionary
|
||||
entries will be used all of the time for fuzzing mutations to not slow down
|
||||
|
@ -45,6 +45,8 @@ Deployment, management, monitoring, reporting
|
||||
parallelize afl-tmin, startup, and data collection.
|
||||
|
||||
Crash processing
|
||||
* [AFLTriage](https://github.com/quic/AFLTriage) -
|
||||
triage crashing input files using gdb.
|
||||
* [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) -
|
||||
another crash analyzer for AFL.
|
||||
* [fuzzer-utils](https://github.com/ThePatrickStar/fuzzer-utils) - a set of
|
||||
@ -54,4 +56,4 @@ Crash processing
|
||||
* [AFLize](https://github.com/d33tah/aflize) - a tool that automatically
|
||||
generates builds of debian packages suitable for AFL.
|
||||
* [afl-fid](https://github.com/FoRTE-Research/afl-fid) - a set of tools for
|
||||
working with input data.
|
||||
working with input data.
|
||||
|
@ -456,7 +456,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
PrevCaller = IRB.CreateLoad(
|
||||
#if LLVM_VERSION_MAJOR >= 14
|
||||
IRB.getInt32Ty(),
|
||||
PrevCallerTy,
|
||||
#endif
|
||||
AFLPrevCaller);
|
||||
PrevCaller->setMetadata(M.getMDKindID("nosanitize"),
|
||||
@ -628,11 +628,21 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
/* Load prev_loc */
|
||||
|
||||
LoadInst *PrevLoc = IRB.CreateLoad(
|
||||
LoadInst *PrevLoc;
|
||||
|
||||
if (ngram_size) {
|
||||
PrevLoc = IRB.CreateLoad(
|
||||
#if LLVM_VERSION_MAJOR >= 14
|
||||
PrevLocTy,
|
||||
#endif
|
||||
AFLPrevLoc);
|
||||
} else {
|
||||
PrevLoc = IRB.CreateLoad(
|
||||
#if LLVM_VERSION_MAJOR >= 14
|
||||
IRB.getInt32Ty(),
|
||||
#endif
|
||||
AFLPrevLoc);
|
||||
}
|
||||
PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
|
||||
Value *PrevLocTrans;
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#else
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/DebugInfo.h"
|
||||
@ -285,7 +286,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
IntegerType *intTyOp0 = NULL;
|
||||
IntegerType *intTyOp1 = NULL;
|
||||
unsigned max_size = 0, cast_size = 0;
|
||||
unsigned attr = 0, vector_cnt = 0;
|
||||
unsigned attr = 0, vector_cnt = 0, is_fp = 0;
|
||||
CmpInst * cmpInst = dyn_cast<CmpInst>(selectcmpInst);
|
||||
|
||||
if (!cmpInst) { continue; }
|
||||
@ -370,6 +371,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
#endif
|
||||
|
||||
attr += 8;
|
||||
is_fp = 1;
|
||||
// fprintf(stderr, "HAVE FP %u!\n", vector_cnt);
|
||||
|
||||
} else {
|
||||
|
||||
@ -453,6 +456,9 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
// XXX FIXME BUG TODO
|
||||
if (is_fp && vector_cnt) { continue; }
|
||||
|
||||
uint64_t cur = 0, last_val0 = 0, last_val1 = 0, cur_val;
|
||||
|
||||
while (1) {
|
||||
@ -464,21 +470,55 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
|
||||
op0 = IRB.CreateExtractElement(op0_saved, cur);
|
||||
op1 = IRB.CreateExtractElement(op1_saved, cur);
|
||||
ConstantInt *i0 = dyn_cast<ConstantInt>(op0);
|
||||
ConstantInt *i1 = dyn_cast<ConstantInt>(op1);
|
||||
if (i0 && i0->uge(0xffffffffffffffff) == false) {
|
||||
/*
|
||||
std::string errMsg;
|
||||
raw_string_ostream os(errMsg);
|
||||
op0_saved->print(os);
|
||||
fprintf(stderr, "X: %s\n", os.str().c_str());
|
||||
*/
|
||||
if (is_fp) {
|
||||
|
||||
cur_val = i0->getZExtValue();
|
||||
if (last_val0 && last_val0 == cur_val) { skip = 1; }
|
||||
last_val0 = cur_val;
|
||||
/*
|
||||
ConstantFP *i0 = dyn_cast<ConstantFP>(op0);
|
||||
ConstantFP *i1 = dyn_cast<ConstantFP>(op1);
|
||||
// BUG FIXME TODO: this is null ... but why?
|
||||
// fprintf(stderr, "%p %p\n", i0, i1);
|
||||
if (i0) {
|
||||
|
||||
}
|
||||
cur_val = (uint64_t)i0->getValue().convertToDouble();
|
||||
if (last_val0 && last_val0 == cur_val) { skip = 1; }
|
||||
last_val0 = cur_val;
|
||||
|
||||
if (i1 && i1->uge(0xffffffffffffffff) == false) {
|
||||
}
|
||||
|
||||
cur_val = i1->getZExtValue();
|
||||
if (last_val1 && last_val1 == cur_val) { skip = 1; }
|
||||
last_val1 = cur_val;
|
||||
if (i1) {
|
||||
|
||||
cur_val = (uint64_t)i1->getValue().convertToDouble();
|
||||
if (last_val1 && last_val1 == cur_val) { skip = 1; }
|
||||
last_val1 = cur_val;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
} else {
|
||||
|
||||
ConstantInt *i0 = dyn_cast<ConstantInt>(op0);
|
||||
ConstantInt *i1 = dyn_cast<ConstantInt>(op1);
|
||||
if (i0 && i0->uge(0xffffffffffffffff) == false) {
|
||||
|
||||
cur_val = i0->getZExtValue();
|
||||
if (last_val0 && last_val0 == cur_val) { skip = 1; }
|
||||
last_val0 = cur_val;
|
||||
|
||||
}
|
||||
|
||||
if (i1 && i1->uge(0xffffffffffffffff) == false) {
|
||||
|
||||
cur_val = i1->getZExtValue();
|
||||
if (last_val1 && last_val1 == cur_val) { skip = 1; }
|
||||
last_val1 = cur_val;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -557,6 +597,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
|
||||
++cur;
|
||||
if (cur >= vector_cnt) { break; }
|
||||
skip = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,31 +96,20 @@ static afl_forkserver_t fsrv = {0}; /* The forkserver */
|
||||
/* Classify tuple counts. This is a slow & naive version, but good enough here.
|
||||
*/
|
||||
|
||||
#define TIMES4(x) x, x, x, x
|
||||
#define TIMES8(x) TIMES4(x), TIMES4(x)
|
||||
#define TIMES16(x) TIMES8(x), TIMES8(x)
|
||||
#define TIMES32(x) TIMES16(x), TIMES16(x)
|
||||
#define TIMES64(x) TIMES32(x), TIMES32(x)
|
||||
static u8 count_class_lookup[256] = {
|
||||
|
||||
[0] = 0,
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 4,
|
||||
[4] = TIMES4(8),
|
||||
[8] = TIMES8(16),
|
||||
[16] = TIMES16(32),
|
||||
[32] = TIMES32(64),
|
||||
[128] = TIMES64(128)
|
||||
[4 ... 7] = 8,
|
||||
[8 ... 15] = 16,
|
||||
[16 ... 31] = 32,
|
||||
[32 ... 127] = 64,
|
||||
[128 ... 255] = 128
|
||||
|
||||
};
|
||||
|
||||
#undef TIMES64
|
||||
#undef TIMES32
|
||||
#undef TIMES16
|
||||
#undef TIMES8
|
||||
#undef TIMES4
|
||||
|
||||
static void kill_child() {
|
||||
|
||||
if (fsrv.child_pid > 0) {
|
||||
|
@ -695,7 +695,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
/* Detect stray -v calls from ./configure scripts. */
|
||||
|
||||
u8 skip_next = 0;
|
||||
u8 skip_next = 0, non_dash = 0;
|
||||
while (--argc) {
|
||||
|
||||
u8 *cur = *(++argv);
|
||||
@ -707,6 +707,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (cur[0] != '-') { non_dash = 1; }
|
||||
if (!strncmp(cur, "--afl", 5)) continue;
|
||||
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
|
||||
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
|
||||
@ -1025,7 +1026,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (preprocessor_only || have_c) {
|
||||
if (preprocessor_only || have_c || !non_dash) {
|
||||
|
||||
/* In the preprocessor_only case (-E), we are not actually compiling at
|
||||
all but requesting the compiler to output preprocessed sources only.
|
||||
|
@ -167,13 +167,6 @@ const u8 count_class_lookup8[256] = {
|
||||
|
||||
};
|
||||
|
||||
#undef TIMES255
|
||||
#undef TIMES64
|
||||
#undef TIMES32
|
||||
#undef TIMES16
|
||||
#undef TIMES8
|
||||
#undef TIMES4
|
||||
|
||||
u16 count_class_lookup16[65536];
|
||||
|
||||
void init_count_class16(void) {
|
||||
|
@ -103,24 +103,17 @@ static sharedmem_t * shm_fuzz;
|
||||
/* Classify tuple counts. Instead of mapping to individual bits, as in
|
||||
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
|
||||
|
||||
#define TIMES4(x) x, x, x, x
|
||||
#define TIMES8(x) TIMES4(x), TIMES4(x)
|
||||
#define TIMES16(x) TIMES8(x), TIMES8(x)
|
||||
#define TIMES32(x) TIMES16(x), TIMES16(x)
|
||||
#define TIMES64(x) TIMES32(x), TIMES32(x)
|
||||
#define TIMES96(x) TIMES64(x), TIMES32(x)
|
||||
#define TIMES128(x) TIMES64(x), TIMES64(x)
|
||||
static const u8 count_class_human[256] = {
|
||||
|
||||
[0] = 0,
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 3,
|
||||
[4] = TIMES4(4),
|
||||
[8] = TIMES8(5),
|
||||
[16] = TIMES16(6),
|
||||
[32] = TIMES96(7),
|
||||
[128] = TIMES128(8)
|
||||
[4] = 4,
|
||||
[8] = 5,
|
||||
[16] = 6,
|
||||
[32] = 7,
|
||||
[128] = 8
|
||||
|
||||
};
|
||||
|
||||
@ -130,22 +123,14 @@ static const u8 count_class_binary[256] = {
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 4,
|
||||
[4] = TIMES4(8),
|
||||
[8] = TIMES8(16),
|
||||
[16] = TIMES16(32),
|
||||
[32] = TIMES32(64),
|
||||
[128] = TIMES64(128)
|
||||
[4 ... 7] = 8,
|
||||
[8 ... 15] = 16,
|
||||
[16 ... 31] = 32,
|
||||
[32 ... 127] = 64,
|
||||
[128 ... 255] = 128
|
||||
|
||||
};
|
||||
|
||||
#undef TIMES128
|
||||
#undef TIMES96
|
||||
#undef TIMES64
|
||||
#undef TIMES32
|
||||
#undef TIMES16
|
||||
#undef TIMES8
|
||||
#undef TIMES4
|
||||
|
||||
static void kill_child() {
|
||||
|
||||
timed_out = 1;
|
||||
|
@ -95,31 +95,20 @@ static sharedmem_t * shm_fuzz;
|
||||
/* Classify tuple counts. This is a slow & naive version, but good enough here.
|
||||
*/
|
||||
|
||||
#define TIMES4(x) x, x, x, x
|
||||
#define TIMES8(x) TIMES4(x), TIMES4(x)
|
||||
#define TIMES16(x) TIMES8(x), TIMES8(x)
|
||||
#define TIMES32(x) TIMES16(x), TIMES16(x)
|
||||
#define TIMES64(x) TIMES32(x), TIMES32(x)
|
||||
static const u8 count_class_lookup[256] = {
|
||||
|
||||
[0] = 0,
|
||||
[1] = 1,
|
||||
[2] = 2,
|
||||
[3] = 4,
|
||||
[4] = TIMES4(8),
|
||||
[8] = TIMES8(16),
|
||||
[16] = TIMES16(32),
|
||||
[32] = TIMES32(64),
|
||||
[128] = TIMES64(128)
|
||||
[4 ... 7] = 8,
|
||||
[8 ... 15] = 16,
|
||||
[16 ... 31] = 32,
|
||||
[32 ... 127] = 64,
|
||||
[128 ... 255] = 128
|
||||
|
||||
};
|
||||
|
||||
#undef TIMES64
|
||||
#undef TIMES32
|
||||
#undef TIMES16
|
||||
#undef TIMES8
|
||||
#undef TIMES4
|
||||
|
||||
static void kill_child() {
|
||||
|
||||
if (fsrv->child_pid > 0) {
|
||||
|
@ -104,7 +104,7 @@ The usage of Autodict-QL is pretty easy. But let's describe it as:
|
||||
we want to compile `libxml` with codeql. Go to libxml and issue the
|
||||
following commands:
|
||||
- `./configure --disable-shared`
|
||||
- `codeql create database libxml-db --language=cpp --command=make`
|
||||
- `codeql database create libxml-db --language=cpp --command="make -j$(nproc)"`
|
||||
- Now you have the CodeQL database of the project :-)
|
||||
3. The final step is to update the CodeQL database you created in step 2
|
||||
(Suppose we are in `aflplusplus/utils/autodict_ql/` directory):
|
||||
@ -144,4 +144,4 @@ There are 2 important points to remember:
|
||||
- Do not forget to set `AFL_MAX_DET_EXTRAS` at least to the number of generated
|
||||
dictionaries. If you forget to set this environment variable, then AFL++ uses
|
||||
just 200 tokens and use the rest of them only probabilistically. So this will
|
||||
guarantee that your tokens will be used by AFL++.
|
||||
guarantee that your tokens will be used by AFL++.
|
||||
|
Reference in New Issue
Block a user