mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-17 04:18:06 +00:00
Merge branch 'dev' into newpm2
This commit is contained in:
28
GNUmakefile
28
GNUmakefile
@ -76,9 +76,9 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
|
||||
endif
|
||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) -fno-move-loop-invariants -fdisable-tree-cunrolli -x c - -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
# SPECIAL_PERFORMANCE += -fno-move-loop-invariants -fdisable-tree-cunrolli
|
||||
#endif
|
||||
|
||||
#ifeq "$(shell echo 'int main() {return 0; }' | $(CC) $(CFLAGS) -Werror -x c - -march=native -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
|
||||
# ifndef SOURCE_DATE_EPOCH
|
||||
@ -92,12 +92,10 @@ ifneq "$(SYS)" "Darwin"
|
||||
# SPECIAL_PERFORMANCE += -march=native
|
||||
#endif
|
||||
# OS X does not like _FORTIFY_SOURCE=2
|
||||
ifndef DEBUG
|
||||
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(SYS)" "Darwin"
|
||||
ifndef DEBUG
|
||||
CFLAGS_OPT += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
else
|
||||
# On some odd MacOS system configurations, the Xcode sdk path is not set correctly
|
||||
SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
|
||||
LDFLAGS += $(SDK_LD)
|
||||
@ -144,12 +142,13 @@ ifdef DEBUG
|
||||
$(info Compiling DEBUG version of binaries)
|
||||
override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror $(CFLAGS_OPT)
|
||||
else
|
||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
||||
CFLAGS ?= -O2 $(CFLAGS_OPT) # -funroll-loops is slower on modern compilers
|
||||
endif
|
||||
|
||||
override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wpointer-arith \
|
||||
-fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||
# -fstack-protector
|
||||
|
||||
ifeq "$(SYS)" "FreeBSD"
|
||||
override CFLAGS += -I /usr/local/include/
|
||||
@ -175,7 +174,7 @@ ifeq "$(SYS)" "Haiku"
|
||||
SHMAT_OK=0
|
||||
override CFLAGS += -DUSEMMAP=1 -Wno-error=format
|
||||
override LDFLAGS += -Wno-deprecated-declarations -lgnu -lnetwork
|
||||
SPECIAL_PERFORMANCE += -DUSEMMAP=1
|
||||
#SPECIAL_PERFORMANCE += -DUSEMMAP=1
|
||||
endif
|
||||
|
||||
AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
|
||||
@ -247,9 +246,6 @@ else
|
||||
endif
|
||||
|
||||
ifneq "$(filter Linux GNU%,$(SYS))" ""
|
||||
ifndef DEBUG
|
||||
override CFLAGS += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
override LDFLAGS += -ldl -lrt -lm
|
||||
endif
|
||||
|
||||
@ -426,7 +422,7 @@ afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
|
||||
@ln -sf afl-as as
|
||||
|
||||
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||
$(CC) $(CFLAGS) -Iinclude $(SPECIAL_PERFORMANCE) -O3 -fno-unroll-loops -c src/afl-performance.c -o src/afl-performance.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_OPT) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
|
||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) -c src/afl-common.c -o src/afl-common.o
|
||||
|
@ -112,7 +112,7 @@ Step-by-step quick start:
|
||||
|
||||
5. You will find found crashes and hangs in the subdirectories `crashes/` and
|
||||
`hangs/` in the `-o output_dir` directory. You can replay the crashes by
|
||||
feeding them to the target, e.g.:
|
||||
feeding them to the target, e.g. if your target is using stdin:
|
||||
|
||||
```
|
||||
cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...]
|
||||
|
@ -12,6 +12,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- fix */build_...sh scripts to work outside of git
|
||||
- new custom_mutator: libafl with token fuzzing :)
|
||||
- afl-fuzz:
|
||||
- when you just want to compile once and set CMPLOG, then just
|
||||
set -c 0 to tell afl-fuzz that the fuzzing binary is also for
|
||||
CMPLOG.
|
||||
- new commandline options -g/G to set min/max length of generated
|
||||
fuzz inputs
|
||||
- reintroduced AFL_PERSISTENT and AFL_DEFER_FORKSRV to allow
|
||||
|
@ -48,11 +48,12 @@ The following setup to use QEMU mode is recommended:
|
||||
|
||||
Then run as many instances as you have cores left with either -Q mode or - even
|
||||
better - use a binary rewriter like Dyninst, RetroWrite, ZAFL, etc.
|
||||
The binary rewriters all have their own advantages and caveats.
|
||||
ZAFL is the best but cannot be used in a business/commercial context.
|
||||
|
||||
If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for your
|
||||
binary, then you can use afl-fuzz normally and it will have twice the speed
|
||||
compared to QEMU mode (but slower than QEMU persistent mode). Note that several
|
||||
other binary rewriters exist, all with their advantages and caveats.
|
||||
If a binary rewriter works for your target then you can use afl-fuzz normally
|
||||
and it will have twice the speed compared to QEMU mode (but slower than QEMU
|
||||
persistent mode).
|
||||
|
||||
The speed decrease of QEMU mode is at about 50%. However, various options exist
|
||||
to increase the speed:
|
||||
|
@ -817,9 +817,9 @@ Here are some of the most important caveats for AFL++:
|
||||
|
||||
- There is no direct support for fuzzing network services, background daemons,
|
||||
or interactive apps that require UI interaction to work. You may need to make
|
||||
simple code changes to make them behave in a more traditional way. Preeny may
|
||||
simple code changes to make them behave in a more traditional way. Preeny or libdesock may
|
||||
offer a relatively simple option, too - see:
|
||||
[https://github.com/zardus/preeny](https://github.com/zardus/preeny)
|
||||
[https://github.com/zardus/preeny](https://github.com/zardus/preeny) or [https://github.com/fkie-cad/libdesock](https://github.com/fkie-cad/libdesock)
|
||||
|
||||
Some useful tips for modifying network-based services can be also found at:
|
||||
[https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop](https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop)
|
||||
|
@ -151,25 +151,25 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
|
||||
* `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks
|
||||
and their instrumented counterparts during block compilation.
|
||||
|
||||
```
|
||||
***
|
||||
Creating block for 0x7ffff7953313:
|
||||
0x7ffff7953313 mov qword ptr [rax], 0
|
||||
0x7ffff795331a add rsp, 8
|
||||
0x7ffff795331e ret
|
||||
|
||||
Creating block for 0x7ffff7953313:
|
||||
0x7ffff7953313 mov qword ptr [rax], 0
|
||||
0x7ffff795331a add rsp, 8
|
||||
0x7ffff795331e ret
|
||||
Generated block 0x7ffff75e98e2
|
||||
0x7ffff75e98e2 mov qword ptr [rax], 0
|
||||
0x7ffff75e98e9 add rsp, 8
|
||||
0x7ffff75e98ed lea rsp, [rsp - 0x80]
|
||||
0x7ffff75e98f5 push rcx
|
||||
0x7ffff75e98f6 movabs rcx, 0x7ffff795331e
|
||||
0x7ffff75e9900 jmp 0x7ffff75e9384
|
||||
|
||||
Generated block 0x7ffff75e98e2
|
||||
0x7ffff75e98e2 mov qword ptr [rax], 0
|
||||
0x7ffff75e98e9 add rsp, 8
|
||||
0x7ffff75e98ed lea rsp, [rsp - 0x80]
|
||||
0x7ffff75e98f5 push rcx
|
||||
0x7ffff75e98f6 movabs rcx, 0x7ffff795331e
|
||||
0x7ffff75e9900 jmp 0x7ffff75e9384
|
||||
|
||||
***
|
||||
```
|
||||
|
||||
* `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used
|
||||
as a look-up table to cache real to instrumented address block translations.
|
||||
Default is 256Mb.
|
||||
* `AFL_FRIDA_INST_INSN` - Generate instrumentation for conditional
|
||||
instructions (e.g. `CMOV` instructions on x64).
|
||||
* `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled
|
||||
@ -178,6 +178,8 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
|
||||
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
|
||||
instrumentation (the default where available). Required to use
|
||||
`AFL_FRIDA_INST_TRACE`.
|
||||
* `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to
|
||||
instrumented address block translations.
|
||||
* `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will
|
||||
report instrumented blocks back to the parent so that it can also instrument
|
||||
them and they be inherited by the next child on fork, implies
|
||||
|
@ -9,8 +9,10 @@
|
||||
js_api_done;
|
||||
js_api_error;
|
||||
js_api_set_backpatch_disable;
|
||||
js_api_set_cache_disable;
|
||||
js_api_set_debug_maps;
|
||||
js_api_set_entrypoint;
|
||||
js_api_set_instrument_cache_size;
|
||||
js_api_set_instrument_coverage_file;
|
||||
js_api_set_instrument_debug_file;
|
||||
js_api_set_instrument_jit;
|
||||
|
@ -22,6 +22,9 @@ extern uint32_t __afl_map_size;
|
||||
|
||||
extern __thread guint64 *instrument_previous_pc_addr;
|
||||
|
||||
extern gboolean instrument_cache_enabled;
|
||||
extern gsize instrument_cache_size;
|
||||
|
||||
void instrument_config(void);
|
||||
|
||||
void instrument_init(void);
|
||||
@ -59,5 +62,10 @@ void instrument_on_fork(void);
|
||||
|
||||
guint64 instrument_get_offset_hash(GumAddress current_rip);
|
||||
|
||||
void instrument_cache_config(void);
|
||||
void instrument_cache_init(void);
|
||||
void instrument_cache_insert(gpointer real_address, gpointer code_address);
|
||||
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -5,6 +5,14 @@
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef MAP_FIXED_NOREPLACE
|
||||
#ifdef MAP_EXCL
|
||||
#define MAP_FIXED_NOREPLACE MAP_EXCL | MAP_FIXED
|
||||
#else
|
||||
#define MAP_FIXED_NOREPLACE MAP_FIXED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define UNUSED_PARAMETER(x) (void)(x)
|
||||
#define IGNORED_RETURN(x) (void)!(x)
|
||||
|
||||
|
@ -249,6 +249,8 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
|
||||
|
||||
}
|
||||
|
||||
instrument_cache(instr, output);
|
||||
|
||||
if (js_stalker_callback(instr, begin, excluded, output)) {
|
||||
|
||||
gum_stalker_iterator_keep(iterator);
|
||||
@ -282,6 +284,7 @@ void instrument_config(void) {
|
||||
instrument_coverage_config();
|
||||
asan_config();
|
||||
cmplog_config();
|
||||
instrument_cache_config();
|
||||
|
||||
}
|
||||
|
||||
@ -392,6 +395,7 @@ void instrument_init(void) {
|
||||
instrument_coverage_init();
|
||||
instrument_coverage_optimize_init();
|
||||
instrument_debug_init();
|
||||
instrument_cache_init();
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
gboolean instrument_cache_enabled = FALSE;
|
||||
gsize instrument_cache_size = 0;
|
||||
|
||||
gboolean instrument_is_coverage_optimize_supported(void) {
|
||||
|
||||
return false;
|
||||
@ -55,5 +58,27 @@ gpointer instrument_cur(GumStalkerOutput *output) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_config(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_init(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_insert(gpointer real_address, gpointer code_address) {
|
||||
|
||||
UNUSED_PARAMETER(real_address);
|
||||
UNUSED_PARAMETER(code_address);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
UNUSED_PARAMETER(output);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -379,5 +379,27 @@ gpointer instrument_cur(GumStalkerOutput *output) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_config(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_init(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_insert(gpointer real_address, gpointer code_address) {
|
||||
|
||||
UNUSED_PARAMETER(real_address);
|
||||
UNUSED_PARAMETER(code_address);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
UNUSED_PARAMETER(output);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -202,10 +202,17 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
|
||||
}
|
||||
|
||||
if (op[0].type != X86_OP_IMM) { return; }
|
||||
if (op[0].type != X86_OP_IMM) {
|
||||
|
||||
instrument_cache_insert(start_address, *target);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case X86_INS_RET:
|
||||
instrument_cache_insert(start_address,
|
||||
(guint8 *)*target + sizeof(afl_log_code));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
435
frida_mode/src/instrument/instrument_x64_cache.c
Normal file
435
frida_mode/src/instrument/instrument_x64_cache.c
Normal file
@ -0,0 +1,435 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "instrument.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(__x86_64__)
|
||||
|
||||
#define INVALID 1
|
||||
#define DEFAULT_CACHE_SIZE (256ULL << 20)
|
||||
|
||||
gboolean instrument_cache_enabled = TRUE;
|
||||
gsize instrument_cache_size = DEFAULT_CACHE_SIZE;
|
||||
static gpointer *map_base = MAP_FAILED;
|
||||
|
||||
void instrument_cache_config(void) {
|
||||
|
||||
instrument_cache_enabled = (getenv("AFL_FRIDA_INST_NO_CACHE") == NULL);
|
||||
|
||||
if (getenv("AFL_FRIDA_INST_CACHE_SIZE") != NULL) {
|
||||
|
||||
if (!instrument_cache_enabled) {
|
||||
|
||||
FFATAL(
|
||||
"AFL_FRIDA_INST_CACHE_SIZE incomatible with "
|
||||
"AFL_FRIDA_INST_NO_CACHE");
|
||||
|
||||
}
|
||||
|
||||
instrument_cache_size =
|
||||
util_read_address("AFL_FRIDA_INST_CACHE_SIZE", DEFAULT_CACHE_SIZE);
|
||||
util_log2(instrument_cache_size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_init(void) {
|
||||
|
||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache:" cYEL " [%c]",
|
||||
instrument_cache_enabled ? 'X' : ' ');
|
||||
if (!instrument_cache_enabled) { return; }
|
||||
|
||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache size:" cYEL " [0x%016lX]",
|
||||
instrument_cache_size);
|
||||
|
||||
const struct rlimit data_limit = {.rlim_cur = RLIM_INFINITY,
|
||||
.rlim_max = RLIM_INFINITY};
|
||||
|
||||
if (setrlimit(RLIMIT_AS, &data_limit) != 0) {
|
||||
|
||||
FFATAL("Failed to setrlimit: %d", errno);
|
||||
|
||||
}
|
||||
|
||||
map_base =
|
||||
gum_memory_allocate(NULL, instrument_cache_size, instrument_cache_size,
|
||||
GUM_PAGE_READ | GUM_PAGE_WRITE);
|
||||
if (map_base == MAP_FAILED) { FFATAL("Failed to map segment: %d", errno); }
|
||||
|
||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache addr:" cYEL " [0x%016lX]",
|
||||
GUM_ADDRESS(map_base));
|
||||
|
||||
}
|
||||
|
||||
static gpointer *instrument_cache_get_addr(gpointer addr) {
|
||||
|
||||
gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1;
|
||||
return &map_base[GPOINTER_TO_SIZE(addr) & mask];
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_insert(gpointer real_address, gpointer code_address) {
|
||||
|
||||
if (!instrument_cache_enabled) { return; }
|
||||
|
||||
gpointer *target = instrument_cache_get_addr(real_address);
|
||||
if (*target == code_address) {
|
||||
|
||||
return;
|
||||
|
||||
} else if (*target == NULL) {
|
||||
|
||||
*target = code_address;
|
||||
|
||||
} else {
|
||||
|
||||
*target = GSIZE_TO_POINTER(INVALID);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static gboolean instrument_cache_relocate(GumAddress old_pc, GumAddress new_pc,
|
||||
gint32 old_offset,
|
||||
gint32 *new_offset) {
|
||||
|
||||
guint64 old_target = old_pc + old_offset;
|
||||
gint64 relocated = old_target - new_pc;
|
||||
|
||||
if (relocated > G_MAXINT32 || relocated < G_MININT32) { return FALSE; }
|
||||
|
||||
*new_offset = relocated;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
static void instrument_cache_rewrite_branch_insn(const cs_insn * instr,
|
||||
GumStalkerOutput *output) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
guint8 modified[sizeof(instr->bytes)] = {0};
|
||||
guint8 offset = 0;
|
||||
guint8 skip = 0;
|
||||
|
||||
g_assert(sizeof(x86->prefix) == 4);
|
||||
g_assert(sizeof(x86->opcode) == 4);
|
||||
|
||||
/*
|
||||
* If the target is simply RAX, we can skip writing the code to load the
|
||||
* RIP
|
||||
*/
|
||||
if (x86->operands[0].type == X86_OP_REG ||
|
||||
x86->operands[0].reg == X86_REG_RAX) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Write the prefix */
|
||||
for (gsize i = 0; i < sizeof(x86->prefix); i++) {
|
||||
|
||||
if (x86->prefix[i] != 0) {
|
||||
|
||||
if (x86->prefix[i] == 0xf2) {
|
||||
|
||||
skip++;
|
||||
|
||||
} else {
|
||||
|
||||
modified[offset++] = x86->prefix[i];
|
||||
skip++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Write the REX */
|
||||
if (x86->rex == 0) {
|
||||
|
||||
/*
|
||||
* CALL (near) and JMP (near) default to 64-bit operands, MOV does not,
|
||||
* write REX.W
|
||||
*/
|
||||
modified[offset++] = 0x48;
|
||||
|
||||
} else {
|
||||
|
||||
if ((x86->rex & 0xF8) != 0x40) {
|
||||
|
||||
FATAL("Unexpected REX byte: 0x%02x", x86->rex);
|
||||
|
||||
}
|
||||
|
||||
modified[offset++] = x86->rex | 0x08;
|
||||
skip++;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* CALL is FF /2, JMP is FF /4. The remaining op-code fields should thus be
|
||||
* unused
|
||||
*/
|
||||
|
||||
if (x86->opcode[0] != 0xFF || x86->opcode[1] != 0x00 ||
|
||||
x86->opcode[2] != 0x00 || x86->opcode[3] != 0x00) {
|
||||
|
||||
FFATAL("Unexpected Op-code: 0x%02x 0x%02x 0x%02x 0x%02x", x86->opcode[0],
|
||||
x86->opcode[1], x86->opcode[2], x86->opcode[3]);
|
||||
|
||||
}
|
||||
|
||||
/* The reg field of the ModRM should be set to 2 for CALL and 4 for JMP */
|
||||
guint8 reg = (x86->modrm >> 3) & 7;
|
||||
if (reg != 0x4 && reg != 0x2) {
|
||||
|
||||
FFATAL("Unexpected Reg: 0x%02x, ModRM: 0x%02x", reg, x86->modrm);
|
||||
|
||||
}
|
||||
|
||||
/* MOV */
|
||||
modified[offset++] = 0x8b;
|
||||
skip++;
|
||||
|
||||
/* Clear the reg field (RAX) */
|
||||
modified[offset++] = x86->modrm & 0xc7;
|
||||
skip++;
|
||||
|
||||
/* Operands */
|
||||
guint8 op_len = instr->size - skip;
|
||||
|
||||
/* If our branch was RIP relative, we'll need to fix-up the offset */
|
||||
if (x86->operands[0].type == X86_OP_MEM &&
|
||||
x86->operands[0].mem.base == X86_REG_RIP) {
|
||||
|
||||
/* RIP relative offsets should be 32-bits */
|
||||
if (op_len != sizeof(gint32)) {
|
||||
|
||||
FFATAL("Unexpected operand length: %d\n", op_len);
|
||||
|
||||
}
|
||||
|
||||
gint32 old_offset = *(gint32 *)&instr->bytes[skip];
|
||||
gint32 new_offset = 0;
|
||||
if (instrument_cache_relocate(instr->address, cw->pc, old_offset,
|
||||
&new_offset)) {
|
||||
|
||||
gint32 *output = (gint32 *)&modified[offset];
|
||||
*output = new_offset;
|
||||
offset += sizeof(gint32);
|
||||
|
||||
} else {
|
||||
|
||||
GumAddress target = instr->address + old_offset;
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, target);
|
||||
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_RAX, GUM_REG_RAX);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (int i = 0; i < op_len; i++) {
|
||||
|
||||
guint8 val = instr->bytes[i + skip];
|
||||
modified[offset++] = val;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gum_x86_writer_put_bytes(cw, modified, offset);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_cache_write_push_frame(GumX86Writer *cw) {
|
||||
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
gum_x86_writer_put_lahf(cw);
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))),
|
||||
GUM_REG_XBX);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_cache_write_pop_frame(GumX86Writer *cw) {
|
||||
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(
|
||||
cw, GUM_REG_XBX, GUM_REG_XSP,
|
||||
-(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))));
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(
|
||||
cw, GUM_REG_XAX, GUM_REG_XSP,
|
||||
-(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))));
|
||||
gum_x86_writer_put_sahf(cw);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(
|
||||
cw, GUM_REG_XAX, GUM_REG_XSP,
|
||||
-(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))));
|
||||
|
||||
}
|
||||
|
||||
static void instrument_cache_write_lookup(GumX86Writer *cw) {
|
||||
|
||||
/* &map_base[GPOINTER_TO_SIZE(addr) & MAP_MASK]; */
|
||||
|
||||
gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1;
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, mask);
|
||||
gum_x86_writer_put_and_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX);
|
||||
gum_x86_writer_put_shl_reg_u8(cw, GUM_REG_XAX, util_log2(sizeof(gpointer)));
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, GPOINTER_TO_SIZE(map_base));
|
||||
gum_x86_writer_put_add_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX);
|
||||
|
||||
/* Read the return address lookup */
|
||||
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XAX);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
|
||||
if (x86->op_count != 1) { FFATAL("Unexpected operand count"); }
|
||||
|
||||
if (x86->operands[0].type == X86_OP_IMM) { return; }
|
||||
|
||||
gconstpointer null = cw->code;
|
||||
|
||||
instrument_cache_write_push_frame(cw);
|
||||
|
||||
/*
|
||||
* We are about to re-write the CALL or JMP instruction, but replace the
|
||||
* op-code with that for a MOV into RAX. Since we are keeping the operand from
|
||||
* the JMP exactly the same, it is imperative that the target register state
|
||||
* be exactly the same as how the target left it. Since `LAHF` spoils `RAX` we
|
||||
* must restore it from the stack. We also must avoid adjusting `RSP`, so we
|
||||
* use `MOV` instructions to store our context into the stack beyond the
|
||||
* red-zone.
|
||||
*/
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(
|
||||
cw, GUM_REG_XAX, GUM_REG_XSP,
|
||||
-(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))));
|
||||
|
||||
instrument_cache_rewrite_branch_insn(instr, output);
|
||||
|
||||
instrument_cache_write_lookup(cw);
|
||||
|
||||
/* Test if its set*/
|
||||
gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID);
|
||||
gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY);
|
||||
|
||||
/* If it's set, then stash the address beyond the red-zone */
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
|
||||
if (instr->id == X86_INS_JMP) {
|
||||
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
gum_x86_writer_put_jmp_reg_offset_ptr(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))));
|
||||
|
||||
} else {
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(
|
||||
cw, GUM_REG_XAX, GUM_ADDRESS(instr->address + instr->size));
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_XSP,
|
||||
-sizeof(gpointer), GUM_REG_XAX);
|
||||
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
|
||||
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_XSP, GUM_REG_XSP,
|
||||
-sizeof(gpointer));
|
||||
gum_x86_writer_put_jmp_reg_offset_ptr(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + ((4 - 1) * sizeof(gpointer))));
|
||||
|
||||
}
|
||||
|
||||
/* Tidy up our mess and let FRIDA handle it */
|
||||
gum_x86_writer_put_label(cw, null);
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_ret(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
guint16 n = 0;
|
||||
|
||||
if (x86->op_count != 0) {
|
||||
|
||||
if (x86->operands[0].type != X86_OP_IMM) {
|
||||
|
||||
FFATAL("Unexpected operand type");
|
||||
|
||||
}
|
||||
|
||||
n = x86->operands[0].imm;
|
||||
|
||||
}
|
||||
|
||||
gconstpointer null = cw->code;
|
||||
|
||||
instrument_cache_write_push_frame(cw);
|
||||
|
||||
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XSP);
|
||||
|
||||
instrument_cache_write_lookup(cw);
|
||||
|
||||
/* Test if its set*/
|
||||
gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID);
|
||||
gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY);
|
||||
|
||||
/* If it's set, then overwrite our return address and return */
|
||||
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_XSP, GUM_REG_XAX);
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
|
||||
if (n == 0) {
|
||||
|
||||
gum_x86_writer_put_ret(cw);
|
||||
|
||||
} else {
|
||||
|
||||
gum_x86_writer_put_ret_imm(cw, n);
|
||||
|
||||
}
|
||||
|
||||
/* Tidy up our mess and let FRIDA handle it */
|
||||
gum_x86_writer_put_label(cw, null);
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
if (!instrument_cache_enabled) { return; }
|
||||
|
||||
switch (instr->id) {
|
||||
|
||||
case X86_INS_RET:
|
||||
instrument_cache_ret(instr, output);
|
||||
break;
|
||||
|
||||
case X86_INS_CALL:
|
||||
case X86_INS_JMP:
|
||||
instrument_cache_jmp_call(instr, output);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
gboolean instrument_cache_enabled = FALSE;
|
||||
gsize instrument_cache_size = 0;
|
||||
|
||||
static GHashTable *coverage_blocks = NULL;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@ -242,5 +245,27 @@ gpointer instrument_cur(GumStalkerOutput *output) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_config(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_init(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache_insert(gpointer real_address, gpointer code_address) {
|
||||
|
||||
UNUSED_PARAMETER(real_address);
|
||||
UNUSED_PARAMETER(code_address);
|
||||
|
||||
}
|
||||
|
||||
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
UNUSED_PARAMETER(output);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -68,6 +68,12 @@ class Afl {
|
||||
static setBackpatchDisable() {
|
||||
Afl.jsApiSetBackpatchDisable();
|
||||
}
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_NO_CACHE`.
|
||||
*/
|
||||
static setCacheDisable() {
|
||||
Afl.jsApiSetCacheDisable();
|
||||
}
|
||||
/**
|
||||
* See `AFL_FRIDA_DEBUG_MAPS`.
|
||||
*/
|
||||
@ -91,6 +97,13 @@ class Afl {
|
||||
static setInMemoryFuzzing() {
|
||||
Afl.jsApiAflSharedMemFuzzing.writeInt(1);
|
||||
}
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_CACHE_SIZE`. This function takes a single `number`
|
||||
* as an argument.
|
||||
*/
|
||||
static setInstrumentCacheSize(size) {
|
||||
Afl.jsApiSetInstrumentCacheSize(size);
|
||||
}
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
|
||||
* as an argument.
|
||||
@ -299,8 +312,10 @@ Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing");
|
||||
Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []);
|
||||
Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]);
|
||||
Afl.jsApiSetBackpatchDisable = Afl.jsApiGetFunction("js_api_set_backpatch_disable", "void", []);
|
||||
Afl.jsApiSetCacheDisable = Afl.jsApiGetFunction("js_api_set_cache_disable", "void", []);
|
||||
Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
|
||||
Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
|
||||
Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]);
|
||||
Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]);
|
||||
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
|
||||
Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []);
|
||||
|
@ -262,6 +262,19 @@ __attribute__((visibility("default"))) void js_api_set_stalker_adjacent_blocks(
|
||||
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) void js_api_set_cache_disable(void) {
|
||||
|
||||
instrument_cache_enabled = FALSE;
|
||||
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) void js_api_set_instrument_cache_size(
|
||||
gsize size) {
|
||||
|
||||
instrument_cache_size = size;
|
||||
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) void js_api_set_js_main_hook(
|
||||
const js_main_hook_t hook) {
|
||||
|
||||
|
97
frida_mode/test/cache/GNUmakefile
vendored
Normal file
97
frida_mode/test/cache/GNUmakefile
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
PWD:=$(shell pwd)/
|
||||
ROOT:=$(PWD)../../../
|
||||
BUILD_DIR:=$(PWD)build/
|
||||
|
||||
TEST_CACHE_SRC:=$(PWD)cache.c
|
||||
TEST_CACHE_OBJ:=$(BUILD_DIR)cache
|
||||
|
||||
TEST_DATA_DIR:=$(BUILD_DIR)in/
|
||||
CACHE_INPUT:=$(TEST_DATA_DIR)in
|
||||
QEMU_OUT:=$(BUILD_DIR)qemu-out
|
||||
FRIDA_OUT:=$(BUILD_DIR)frida-out
|
||||
|
||||
ADDR_BIN:=$(ROOT)frida_mode/build/addr
|
||||
GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
|
||||
|
||||
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
|
||||
|
||||
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
|
||||
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_CACHE_OBJ) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
|
||||
|
||||
DUMMY_DATA_FILE:=$(BUILD_DIR)dummy.dat
|
||||
|
||||
.PHONY: all 32 clean frida frida_noinst debug format
|
||||
|
||||
all: $(TEST_CACHE_OBJ)
|
||||
make -C $(ROOT)frida_mode/
|
||||
|
||||
32:
|
||||
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(TEST_DATA_DIR): | $(BUILD_DIR)
|
||||
mkdir -p $@
|
||||
|
||||
$(CACHE_INPUT): | $(TEST_DATA_DIR)
|
||||
echo -n "ABC" > $@
|
||||
|
||||
$(TEST_CACHE_OBJ): $(TEST_CACHE_SRC) | $(BUILD_DIR)
|
||||
$(CC) -g $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
########## DUMMY #######
|
||||
|
||||
$(DUMMY_DATA_FILE): | $(BUILD_DIR)
|
||||
dd if=/dev/zero bs=1048576 count=1 of=$@
|
||||
|
||||
frida: $(TEST_CACHE_OBJ) $(CACHE_INPUT) $(DUMMY_DATA_FILE)
|
||||
AFL_FRIDA_INST_INSN=1 \
|
||||
AFL_FRIDA_PERSISTENT_CNT=1000000 \
|
||||
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
|
||||
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||
AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||
$(ROOT)afl-fuzz \
|
||||
-O \
|
||||
-i $(TEST_DATA_DIR) \
|
||||
-o $(FRIDA_OUT) \
|
||||
-Z \
|
||||
-t 10000+ \
|
||||
-- \
|
||||
$(TEST_CACHE_OBJ) $(DUMMY_DATA_FILE)
|
||||
|
||||
frida_nocache: $(TEST_CACHE_OBJ) $(CACHE_INPUT) $(DUMMY_DATA_FILE)
|
||||
AFL_FRIDA_INST_NO_CACHE=1 \
|
||||
AFL_FRIDA_PERSISTENT_CNT=1000000 \
|
||||
AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \
|
||||
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||
AFL_ENTRYPOINT=$(AFL_FRIDA_PERSISTENT_ADDR) \
|
||||
$(ROOT)afl-fuzz \
|
||||
-O \
|
||||
-i $(TEST_DATA_DIR) \
|
||||
-o $(FRIDA_OUT) \
|
||||
-Z \
|
||||
-- \
|
||||
$(TEST_CACHE_OBJ) $(DUMMY_DATA_FILE)
|
||||
|
||||
debug: $(TEST_CACHE_OBJ) $(CACHE_INPUT)
|
||||
gdb \
|
||||
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
|
||||
--ex 'set disassembly-flavor intel' \
|
||||
--ex 'r $(CACHE_INPUT)' \
|
||||
--args $(TEST_CACHE_OBJ) $(CACHE_INPUT)
|
||||
|
||||
show: $(TEST_CACHE_OBJ) $(CACHE_INPUT)
|
||||
gdb \
|
||||
--ex "set disassembly-flavor intel" \
|
||||
--ex "set confirm off" \
|
||||
--ex "symbol-file $(TEST_CACHE_OBJ)" \
|
||||
--ex "x/50i LLVMFuzzerTestOneInput" \
|
||||
--ex "r" \
|
||||
--args $(TEST_CACHE_OBJ) $(CACHE_INPUT)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
format:
|
||||
cd $(ROOT) && echo $(TEST_CACHE_SRC) | xargs -L1 ./.custom-format.py -i
|
22
frida_mode/test/cache/Makefile
vendored
Normal file
22
frida_mode/test/cache/Makefile
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
all:
|
||||
@echo trying to use GNU make...
|
||||
@gmake all || echo please install GNUmake
|
||||
|
||||
32:
|
||||
@echo trying to use GNU make...
|
||||
@gmake 32 || echo please install GNUmake
|
||||
|
||||
frida:
|
||||
@gmake frida
|
||||
|
||||
frida_nocache:
|
||||
@gmake frida_nocache
|
||||
|
||||
debug:
|
||||
@gmake debug
|
||||
|
||||
clean:
|
||||
@gmake clean
|
||||
|
||||
format:
|
||||
@gmake format
|
115
frida_mode/test/cache/cache.c
vendored
Normal file
115
frida_mode/test/cache/cache.c
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void LLVMFuzzerTestOneInput(char *buf, int len);
|
||||
|
||||
__asm__ (
|
||||
"LLVMFuzzerTestOneInput:\n"
|
||||
".func LLVMFuzzerTestOneInput\n"
|
||||
".global LLVMFuzzerTestOneInput\n"
|
||||
" jmpq *jmp_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"call_target:\n"
|
||||
" ret\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
"jmp_target:\n"
|
||||
" callq *call_offset(%rip)\n"
|
||||
" nop\n"
|
||||
" nop\n"
|
||||
" leaq rax_offset(%rip), %rax\n"
|
||||
" jmp (%rax)\n"
|
||||
" nop\n"
|
||||
" ud2\n"
|
||||
" nop\n"
|
||||
"rax_target:\n"
|
||||
" ret\n"
|
||||
"\n"
|
||||
"\n"
|
||||
".global jmp_offset\n"
|
||||
".p2align 3\n"
|
||||
"jmp_offset:\n"
|
||||
" .quad jmp_target\n"
|
||||
"call_offset:\n"
|
||||
" .quad call_target\n"
|
||||
"rax_offset:\n"
|
||||
" .quad rax_target\n"
|
||||
);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
char * file;
|
||||
int fd = -1;
|
||||
off_t len;
|
||||
char * buf = NULL;
|
||||
size_t n_read;
|
||||
int result = -1;
|
||||
|
||||
if (argc != 2) { return 1; }
|
||||
|
||||
do {
|
||||
|
||||
file = argv[1];
|
||||
|
||||
dprintf(STDERR_FILENO, "Running: %s\n", file);
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
||||
perror("open");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
len = lseek(fd, 0, SEEK_END);
|
||||
if (len < 0) {
|
||||
|
||||
perror("lseek (SEEK_END)");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) != 0) {
|
||||
|
||||
perror("lseek (SEEK_SET)");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL) {
|
||||
|
||||
perror("malloc");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
n_read = read(fd, buf, len);
|
||||
if (n_read != len) {
|
||||
|
||||
perror("read");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read);
|
||||
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read);
|
||||
|
||||
result = 0;
|
||||
|
||||
} while (false);
|
||||
|
||||
if (buf != NULL) { free(buf); }
|
||||
|
||||
if (fd != -1) { close(fd); }
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ vorbis: $(VORBIS_LIB)
|
||||
########## HARNESS #######
|
||||
|
||||
$(DECODE_SRC):
|
||||
wget -O $@ $(DECODE_URL)
|
||||
wget -O $@ $(DECODE_URL) || curl -L -o $@ $(DECODE_URL)
|
||||
|
||||
$(DECODE_OBJ): $(DECODE_SRC)
|
||||
$(CXX) -o $@ -c $< -I$(VORBIS_DIR)include/ -I$(OGG_DIR)include/
|
||||
@ -135,7 +135,7 @@ decode: $(DECODE_OBJ)
|
||||
########## HARNESS #######
|
||||
|
||||
$(HARNESS_SRC):
|
||||
wget -O $@ $(HARNESS_URL)
|
||||
wget -O $@ $(HARNESS_URL) || curl -L -o $@ $(HARNESS_URL)
|
||||
|
||||
$(HARNESS_OBJ): $(HARNESS_SRC)
|
||||
$(CC) -o $@ -c $<
|
||||
@ -165,8 +165,8 @@ $(AFLPP_DRIVER_DUMMY_INPUT): | $(BUILD_DIR)
|
||||
|
||||
###### TEST DATA #######
|
||||
|
||||
$(TEST_DATA_FILE): $(TEST_DATA_DIR)
|
||||
wget -O $@ $(TEST_DATA_SRC)
|
||||
$(TEST_DATA_FILE): | $(TEST_DATA_DIR)
|
||||
wget -O $@ $(TEST_DATA_SRC) || curl -L -o $@ $(TEST_DATA_SRC)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
@ -84,6 +84,13 @@ class Afl {
|
||||
Afl.jsApiSetBackpatchDisable();
|
||||
}
|
||||
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_NO_CACHE`.
|
||||
*/
|
||||
public static setCacheDisable(): void {
|
||||
Afl.jsApiSetCacheDisable();
|
||||
}
|
||||
|
||||
/**
|
||||
* See `AFL_FRIDA_DEBUG_MAPS`.
|
||||
*/
|
||||
@ -110,6 +117,14 @@ class Afl {
|
||||
Afl.jsApiAflSharedMemFuzzing.writeInt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_CACHE_SIZE`. This function takes a single `number`
|
||||
* as an argument.
|
||||
*/
|
||||
public static setInstrumentCacheSize(size: number): void {
|
||||
Afl.jsApiSetInstrumentCacheSize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
|
||||
* as an argument.
|
||||
@ -354,6 +369,11 @@ class Afl {
|
||||
"void",
|
||||
[]);
|
||||
|
||||
private static readonly jsApiSetCacheDisable = Afl.jsApiGetFunction(
|
||||
"js_api_set_cache_disable",
|
||||
"void",
|
||||
[]);
|
||||
|
||||
private static readonly jsApiSetDebugMaps = Afl.jsApiGetFunction(
|
||||
"js_api_set_debug_maps",
|
||||
"void",
|
||||
@ -364,6 +384,11 @@ class Afl {
|
||||
"void",
|
||||
["pointer"]);
|
||||
|
||||
private static readonly jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction(
|
||||
"js_api_set_instrument_cache_size",
|
||||
"void",
|
||||
["size_t"]);
|
||||
|
||||
private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction(
|
||||
"js_api_set_instrument_coverage_file",
|
||||
"void",
|
||||
|
@ -57,10 +57,12 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_FRIDA_DEBUG_MAPS",
|
||||
"AFL_FRIDA_DRIVER_NO_HOOK",
|
||||
"AFL_FRIDA_EXCLUDE_RANGES",
|
||||
"AFL_FRIDA_INST_CACHE_SIZE",
|
||||
"AFL_FRIDA_INST_COVERAGE_FILE",
|
||||
"AFL_FRIDA_INST_DEBUG_FILE",
|
||||
"AFL_FRIDA_INST_INSN",
|
||||
"AFL_FRIDA_INST_JIT",
|
||||
"AFL_FRIDA_INST_NO_CACHE",
|
||||
"AFL_FRIDA_INST_NO_OPTIMIZE",
|
||||
"AFL_FRIDA_INST_NO_PREFETCH",
|
||||
"AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
|
||||
|
@ -70,6 +70,8 @@ typedef struct {
|
||||
enum NyxReturnValue (*nyx_exec)(void *qemu_process);
|
||||
uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process);
|
||||
size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process);
|
||||
uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer,
|
||||
uint32_t size);
|
||||
|
||||
} nyx_plugin_handler_t;
|
||||
|
||||
@ -173,6 +175,7 @@ typedef struct afl_forkserver {
|
||||
void * nyx_runner; /* nyx runner object */
|
||||
u32 nyx_id; /* nyx runner id (0 -> master) */
|
||||
u32 nyx_bind_cpu_id; /* nyx runner cpu id */
|
||||
char * nyx_aux_string;
|
||||
#endif
|
||||
|
||||
} afl_forkserver_t;
|
||||
|
@ -46,21 +46,12 @@ typedef long double max_align_t;
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/Pass.h"
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
#include "llvm/Passes/PassPlugin.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#endif
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */
|
||||
#include "llvm/Passes/OptimizationLevel.h"
|
||||
#endif
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 4 || \
|
||||
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
|
||||
@ -78,30 +69,17 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
class AFLCoverage : public PassInfoMixin<AFLCoverage> {
|
||||
|
||||
public:
|
||||
AFLCoverage() {
|
||||
|
||||
#else
|
||||
class AFLCoverage : public ModulePass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
AFLCoverage() : ModulePass(ID) {
|
||||
|
||||
#endif
|
||||
|
||||
initInstrumentList();
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
#else
|
||||
bool runOnModule(Module &M) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
uint32_t ngram_size = 0;
|
||||
@ -115,55 +93,7 @@ class AFLCoverage : public ModulePass {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
||||
llvmGetPassPluginInfo() {
|
||||
|
||||
return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1",
|
||||
/* lambda to insert our pass into the pass pipeline. */
|
||||
[](PassBuilder &PB) {
|
||||
|
||||
#if 1
|
||||
#if LLVM_VERSION_MAJOR <= 13
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
|
||||
MPM.addPass(AFLCoverage());
|
||||
|
||||
});
|
||||
|
||||
/* TODO LTO registration */
|
||||
#else
|
||||
using PipelineElement = typename PassBuilder::PipelineElement;
|
||||
PB.registerPipelineParsingCallback([](StringRef Name,
|
||||
ModulePassManager &MPM,
|
||||
ArrayRef<PipelineElement>) {
|
||||
|
||||
if (Name == "AFLCoverage") {
|
||||
|
||||
MPM.addPass(AFLCoverage());
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
}};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char AFLCoverage::ID = 0;
|
||||
#endif
|
||||
|
||||
/* needed up to 3.9.0 */
|
||||
#if LLVM_VERSION_MAJOR == 3 && \
|
||||
@ -189,15 +119,8 @@ uint64_t PowerOf2Ceil(unsigned in) {
|
||||
(LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1)
|
||||
#define AFL_HAVE_VECTOR_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
#endif
|
||||
|
||||
LLVMContext &C = M.getContext();
|
||||
|
||||
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
||||
@ -211,10 +134,6 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
u32 rand_seed;
|
||||
unsigned int cur_loc = 0;
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
auto PA = PreservedAnalyses::all();
|
||||
#endif
|
||||
|
||||
/* Setup random() so we get Actually Random(TM) outputs from AFL_R() */
|
||||
gettimeofday(&tv, &tz);
|
||||
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
||||
@ -1079,15 +998,10 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
return PA;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */
|
||||
static void registerAFLPass(const PassManagerBuilder &,
|
||||
legacy::PassManagerBase &PM) {
|
||||
|
||||
@ -1100,5 +1014,4 @@ static RegisterStandardPasses RegisterAFLPass(
|
||||
|
||||
static RegisterStandardPasses RegisterAFLPass0(
|
||||
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);
|
||||
#endif
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -37,6 +38,7 @@
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#endif
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Pass.h"
|
||||
@ -136,7 +138,7 @@ llvmGetPassPluginInfo() {
|
||||
#else
|
||||
char CmpLogInstructions::ID = 0;
|
||||
#endif
|
||||
|
||||
|
||||
template <class Iterator>
|
||||
Iterator Unique(Iterator first, Iterator last) {
|
||||
|
||||
@ -684,10 +686,10 @@ bool CmpLogInstructions::runOnModule(Module &M) {
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR < 11 /* use old pass manager */
|
||||
#if LLVM_MAJOR < 11 /* use old pass manager */
|
||||
static void registerCmpLogInstructionsPass(const PassManagerBuilder &,
|
||||
legacy::PassManagerBase &PM) {
|
||||
|
||||
@ -708,4 +710,3 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO(
|
||||
registerCmpLogInstructionsPass);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -26,23 +26,14 @@
|
||||
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
#include "llvm/Passes/PassPlugin.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#endif
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */
|
||||
#include "llvm/Passes/OptimizationLevel.h"
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 4 || \
|
||||
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
|
||||
@ -61,21 +52,12 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
class CompareTransform : public PassInfoMixin<CompareTransform> {
|
||||
|
||||
public:
|
||||
CompareTransform() {
|
||||
|
||||
#else
|
||||
class CompareTransform : public ModulePass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
CompareTransform() : ModulePass(ID) {
|
||||
|
||||
#endif
|
||||
|
||||
initInstrumentList();
|
||||
|
||||
}
|
||||
@ -88,18 +70,17 @@ class CompareTransform : public ModulePass {
|
||||
const char *getPassName() const override {
|
||||
|
||||
#endif
|
||||
|
||||
return "cmplog transform";
|
||||
return "transforms compare functions";
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
#else
|
||||
//#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
// PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
//#else
|
||||
bool runOnModule(Module &M) override;
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
private:
|
||||
bool transformCmps(Module &M, const bool processStrcmp,
|
||||
@ -111,54 +92,7 @@ class CompareTransform : public ModulePass {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
||||
llvmGetPassPluginInfo() {
|
||||
|
||||
return {LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1",
|
||||
/* lambda to insert our pass into the pass pipeline. */
|
||||
[](PassBuilder &PB) {
|
||||
|
||||
#if 1
|
||||
#if LLVM_VERSION_MAJOR <= 13
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
|
||||
MPM.addPass(CompareTransform());
|
||||
|
||||
});
|
||||
|
||||
/* TODO LTO registration */
|
||||
#else
|
||||
using PipelineElement = typename PassBuilder::PipelineElement;
|
||||
PB.registerPipelineParsingCallback([](StringRef Name,
|
||||
ModulePassManager &MPM,
|
||||
ArrayRef<PipelineElement>) {
|
||||
|
||||
if (Name == "comparetransform") {
|
||||
|
||||
MPM.addPass(CompareTransform());
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
}};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
char CompareTransform::ID = 0;
|
||||
#endif
|
||||
|
||||
bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
const bool processMemcmp,
|
||||
@ -458,7 +392,6 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
bool isCaseInsensitive = false;
|
||||
bool needs_null = false;
|
||||
Function * Callee = callInst->getCalledFunction();
|
||||
|
||||
if (Callee) {
|
||||
|
||||
if (!Callee->getName().compare("memcmp") ||
|
||||
@ -716,14 +649,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
bool CompareTransform::runOnModule(Module &M) {
|
||||
|
||||
#endif
|
||||
|
||||
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
|
||||
printf(
|
||||
"Running compare-transform-pass by laf.intel@gmail.com, extended by "
|
||||
@ -731,28 +658,13 @@ bool CompareTransform::runOnModule(Module &M) {
|
||||
else
|
||||
be_quiet = 1;
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
auto PA = PreservedAnalyses::all();
|
||||
#endif
|
||||
|
||||
transformCmps(M, true, true, true, true, true);
|
||||
verifyModule(M);
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
/* if (modified) {
|
||||
|
||||
PA.abandon<XX_Manager>();
|
||||
|
||||
}*/
|
||||
|
||||
return PA;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR < 11 /* use old pass manager */
|
||||
static void registerCompTransPass(const PassManagerBuilder &,
|
||||
legacy::PassManagerBase &PM) {
|
||||
|
||||
@ -767,9 +679,8 @@ static RegisterStandardPasses RegisterCompTransPass(
|
||||
static RegisterStandardPasses RegisterCompTransPass0(
|
||||
PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
static RegisterStandardPasses RegisterCompTransPassLTO(
|
||||
PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* Copyright 2016 laf-intel
|
||||
* extended for floating point by Heiko Eißfeldt
|
||||
* adapted to new pass manager by Heiko Eißfeldt
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -29,20 +28,10 @@
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
#include "llvm/Passes/PassPlugin.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#endif
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */
|
||||
#include "llvm/Passes/OptimizationLevel.h"
|
||||
#endif
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#if LLVM_VERSION_MAJOR >= 4 || \
|
||||
@ -64,31 +53,27 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
class SplitComparesTransform : public PassInfoMixin<SplitComparesTransform> {
|
||||
|
||||
public:
|
||||
// static char ID;
|
||||
SplitComparesTransform() : enableFPSplit(0) {
|
||||
|
||||
#else
|
||||
class SplitComparesTransform : public ModulePass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
|
||||
|
||||
#endif
|
||||
|
||||
initInstrumentList();
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
#else
|
||||
bool runOnModule(Module &M) override;
|
||||
#if LLVM_VERSION_MAJOR >= 4
|
||||
StringRef getPassName() const override {
|
||||
|
||||
#else
|
||||
const char *getPassName() const override {
|
||||
|
||||
#endif
|
||||
return "AFL_SplitComparesTransform";
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
int enableFPSplit;
|
||||
@ -177,54 +162,7 @@ class SplitComparesTransform : public ModulePass {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
||||
llvmGetPassPluginInfo() {
|
||||
|
||||
return {LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1",
|
||||
/* lambda to insert our pass into the pass pipeline. */
|
||||
[](PassBuilder &PB) {
|
||||
|
||||
#if 1
|
||||
#if LLVM_VERSION_MAJOR <= 13
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
|
||||
MPM.addPass(SplitComparesTransform());
|
||||
|
||||
});
|
||||
|
||||
/* TODO LTO registration */
|
||||
#else
|
||||
using PipelineElement = typename PassBuilder::PipelineElement;
|
||||
PB.registerPipelineParsingCallback([](StringRef Name,
|
||||
ModulePassManager &MPM,
|
||||
ArrayRef<PipelineElement>) {
|
||||
|
||||
if (Name == "splitcompares") {
|
||||
|
||||
MPM.addPass(SplitComparesTransform());
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
}};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
char SplitComparesTransform::ID = 0;
|
||||
#endif
|
||||
|
||||
/// This function splits FCMP instructions with xGE or xLE predicates into two
|
||||
/// FCMP instructions with predicate xGT or xLT and EQ
|
||||
@ -1483,15 +1421,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
PreservedAnalyses SplitComparesTransform::run(Module & M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
|
||||
#endif
|
||||
|
||||
char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW");
|
||||
if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW");
|
||||
if (bitw_env) { target_bitwidth = atoi(bitw_env); }
|
||||
@ -1501,7 +1432,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
|
||||
getenv("AFL_DEBUG") != NULL) {
|
||||
|
||||
errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by "
|
||||
errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
|
||||
"heiko@hexco.de (splitting icmp to "
|
||||
<< target_bitwidth << " bit)\n";
|
||||
|
||||
@ -1513,10 +1444,6 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
auto PA = PreservedAnalyses::all();
|
||||
#endif
|
||||
|
||||
if (enableFPSplit) {
|
||||
|
||||
simplifyFPCompares(M);
|
||||
@ -1546,16 +1473,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
|
||||
auto op0 = CI->getOperand(0);
|
||||
auto op1 = CI->getOperand(1);
|
||||
if (!op0 || !op1) {
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
return PA;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (!op0 || !op1) { return false; }
|
||||
auto iTy1 = dyn_cast<IntegerType>(op0->getType());
|
||||
if (iTy1 && isa<IntegerType>(op1->getType())) {
|
||||
|
||||
@ -1604,29 +1522,10 @@ bool SplitComparesTransform::runOnModule(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
|
||||
getenv("AFL_DEBUG") != NULL) {
|
||||
|
||||
errs() << count << " comparisons found\n";
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
/* if (modified) {
|
||||
|
||||
PA.abandon<XX_Manager>();
|
||||
|
||||
}*/
|
||||
|
||||
return PA;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR < 11 /* use old pass manager */
|
||||
|
||||
static void registerSplitComparesPass(const PassManagerBuilder &,
|
||||
legacy::PassManagerBase &PM) {
|
||||
|
||||
@ -1640,15 +1539,14 @@ static RegisterStandardPasses RegisterSplitComparesPass(
|
||||
static RegisterStandardPasses RegisterSplitComparesTransPass0(
|
||||
PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
static RegisterStandardPasses RegisterSplitComparesTransPassLTO(
|
||||
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
|
||||
registerSplitComparesPass);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static RegisterPass<SplitComparesTransform> X("splitcompares",
|
||||
"AFL++ split compares",
|
||||
true /* Only looks at CFG */,
|
||||
true /* Analysis Pass */);
|
||||
#endif
|
||||
|
||||
|
@ -27,23 +27,14 @@
|
||||
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
#include "llvm/Passes/PassPlugin.h"
|
||||
#include "llvm/Passes/PassBuilder.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#endif
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */
|
||||
#include "llvm/Passes/OptimizationLevel.h"
|
||||
#endif
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#if LLVM_VERSION_MAJOR >= 4 || \
|
||||
@ -63,42 +54,29 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
class SplitSwitchesTransform : public PassInfoMixin<SplitSwitchesTransform> {
|
||||
|
||||
public:
|
||||
SplitSwitchesTransform() {
|
||||
|
||||
#else
|
||||
class SplitSwitchesTransform : public ModulePass {
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
SplitSwitchesTransform() : ModulePass(ID) {
|
||||
|
||||
#endif
|
||||
initInstrumentList();
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
|
||||
#else
|
||||
bool runOnModule(Module &M) override;
|
||||
bool runOnModule(Module &M) override;
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 4
|
||||
#if LLVM_VERSION_MAJOR >= 4
|
||||
StringRef getPassName() const override {
|
||||
|
||||
#else
|
||||
#else
|
||||
const char *getPassName() const override {
|
||||
|
||||
#endif
|
||||
#endif
|
||||
return "splits switch constructs";
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct CaseExpr {
|
||||
|
||||
ConstantInt *Val;
|
||||
@ -125,54 +103,7 @@ class SplitSwitchesTransform : public ModulePass {
|
||||
|
||||
} // namespace
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
|
||||
llvmGetPassPluginInfo() {
|
||||
|
||||
return {LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1",
|
||||
/* lambda to insert our pass into the pass pipeline. */
|
||||
[](PassBuilder &PB) {
|
||||
|
||||
#if 1
|
||||
#if LLVM_VERSION_MAJOR <= 13
|
||||
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
|
||||
#endif
|
||||
PB.registerOptimizerLastEPCallback(
|
||||
[](ModulePassManager &MPM, OptimizationLevel OL) {
|
||||
|
||||
MPM.addPass(SplitSwitchesTransform());
|
||||
|
||||
});
|
||||
|
||||
/* TODO LTO registration */
|
||||
#else
|
||||
using PipelineElement = typename PassBuilder::PipelineElement;
|
||||
PB.registerPipelineParsingCallback([](StringRef Name,
|
||||
ModulePassManager &MPM,
|
||||
ArrayRef<PipelineElement>) {
|
||||
|
||||
if (Name == "splitswitches") {
|
||||
|
||||
MPM.addPass(SplitSwitchesTransform());
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
}};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
char SplitSwitchesTransform::ID = 0;
|
||||
#endif
|
||||
|
||||
/* switchConvert - Transform simple list of Cases into list of CaseRange's */
|
||||
BasicBlock *SplitSwitchesTransform::switchConvert(
|
||||
@ -482,42 +413,19 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses SplitSwitchesTransform::run(Module & M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
bool SplitSwitchesTransform::runOnModule(Module &M) {
|
||||
|
||||
#endif
|
||||
|
||||
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
|
||||
printf("Running split-switches-pass by laf.intel@gmail.com\n");
|
||||
else
|
||||
be_quiet = 1;
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
auto PA = PreservedAnalyses::all();
|
||||
#endif
|
||||
|
||||
splitSwitches(M);
|
||||
verifyModule(M);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
/* if (modified) {
|
||||
|
||||
PA.abandon<XX_Manager>();
|
||||
|
||||
}*/
|
||||
|
||||
return PA;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */
|
||||
static void registerSplitSwitchesTransPass(const PassManagerBuilder &,
|
||||
legacy::PassManagerBase &PM) {
|
||||
|
||||
@ -532,10 +440,9 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPass(
|
||||
static RegisterStandardPasses RegisterSplitSwitchesTransPass0(
|
||||
PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO(
|
||||
PassManagerBuilder::EP_FullLinkTimeOptimizationLast,
|
||||
registerSplitSwitchesTransPass);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1 +1 @@
|
||||
2e45754
|
||||
8a77c71
|
||||
|
@ -1 +1 @@
|
||||
76100c5
|
||||
5d143ee
|
||||
|
Submodule nyx_mode/QEMU-Nyx updated: c2c69cfc52...c08e4ac942
@ -1 +1 @@
|
||||
c2c69cfc52
|
||||
c08e4ac942
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define TRACE_BUFFER_SIZE (64)
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE-1)) + PAGE_SIZE)
|
||||
#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE - 1)) + PAGE_SIZE)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
@ -30,8 +30,9 @@ int main(int argc, char **argv) {
|
||||
/* this is our "bitmap" that is later shared with the fuzzer (you can also
|
||||
* pass the pointer of the bitmap used by compile-time instrumentations in
|
||||
* your target) */
|
||||
uint8_t *trace_buffer = mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ |
|
||||
PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
uint8_t *trace_buffer =
|
||||
mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
||||
memset(trace_buffer, 0,
|
||||
TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already
|
||||
// mapped into the guest's memory (alternatively
|
||||
|
Submodule nyx_mode/libnyx updated: 2e45754e27...8a77c71dc8
Submodule nyx_mode/packer updated: 76100c52db...5d143eee4e
36
src/afl-cc.c
36
src/afl-cc.c
@ -473,7 +473,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/split-switches-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -499,7 +499,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/compare-transform-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -514,16 +514,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
} else {
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path);
|
||||
#else
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = "-load";
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/split-compares-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -553,17 +548,11 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
alloc_printf("%s/cmplog-switches-pass.so", obj_path);
|
||||
|
||||
// reuse split switches from laf
|
||||
#if LLVM_MAJOR >= 11
|
||||
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path);
|
||||
#else
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = "-load";
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/split-switches-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -571,10 +560,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR == 13 // TODO: set to 14 when done FIXME
|
||||
// Use the old pass manager in LLVM 13 which the afl++ passes still use.
|
||||
cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
|
||||
#endif
|
||||
//#if LLVM_MAJOR >= 13
|
||||
// // Use the old pass manager in LLVM 14 which the afl++ passes still use.
|
||||
// cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
|
||||
//#endif
|
||||
|
||||
if (lto_mode && !have_c) {
|
||||
|
||||
@ -665,16 +654,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
} else {
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path);
|
||||
#else
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = "-load";
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@ -695,20 +678,23 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
|
||||
cc_params[cc_par_cnt++] = alloc_printf(
|
||||
"-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path);
|
||||
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
|
||||
cc_params[cc_par_cnt++] = alloc_printf(
|
||||
"-fpass-plugin=%s/cmplog-routines-pass.so", obj_path);
|
||||
#else
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = "-load";
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/cmplog-instructions-pass.so", obj_path);
|
||||
#endif
|
||||
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] = "-load";
|
||||
cc_params[cc_par_cnt++] = "-Xclang";
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/cmplog-routines-pass.so", obj_path);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -450,6 +450,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
|
||||
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
|
||||
|
||||
fsrv->nyx_aux_string = malloc(0x1000);
|
||||
memset(fsrv->nyx_aux_string, 0, 0x1000);
|
||||
|
||||
/* dry run */
|
||||
fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4);
|
||||
switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) {
|
||||
@ -1253,7 +1256,13 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
||||
fsrv->child_pid = -1;
|
||||
|
||||
#ifdef __linux__
|
||||
if (fsrv->nyx_mode) { fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); }
|
||||
if (fsrv->nyx_mode) {
|
||||
|
||||
free(fsrv->nyx_aux_string);
|
||||
fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -423,10 +423,10 @@ void write_crash_readme(afl_state_t *afl) {
|
||||
"them to a vendor? Check out the afl-tmin that comes with the fuzzer!\n\n"
|
||||
|
||||
"Found any cool bugs in open-source tools using afl-fuzz? If yes, please "
|
||||
"drop\n"
|
||||
"an mail at <afl-users@googlegroups.com> once the issues are fixed\n\n"
|
||||
|
||||
" https://github.com/AFLplusplus/AFLplusplus\n\n",
|
||||
"post\n"
|
||||
"to https://github.com/AFLplusplus/AFLplusplus/issues/286 once the "
|
||||
"issues\n"
|
||||
" are fixed :)\n\n",
|
||||
|
||||
afl->orig_cmdline,
|
||||
stringify_mem_size(val_buf, sizeof(val_buf),
|
||||
@ -771,6 +771,25 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||
ck_write(fd, mem, len, fn);
|
||||
close(fd);
|
||||
|
||||
#ifdef __linux__
|
||||
if (afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) {
|
||||
|
||||
u8 fn_log[PATH_MAX];
|
||||
|
||||
snprintf(fn_log, PATH_MAX, "%s.log", fn);
|
||||
fd = open(fn_log, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn_log); }
|
||||
|
||||
u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string(
|
||||
afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string, 0x1000);
|
||||
|
||||
ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, fn_log);
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return keeping;
|
||||
|
||||
}
|
||||
|
@ -2136,7 +2136,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
|
||||
|
||||
if ((i % 2)) {
|
||||
|
||||
if (len > idx + i && is_hex(orig_buf + idx + i)) {
|
||||
if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) {
|
||||
|
||||
fromhex += 2;
|
||||
|
||||
@ -2323,7 +2323,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
|
||||
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||
// fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex,
|
||||
// *status);
|
||||
memcpy(buf + idx + i, save + i, i + 1 + off);
|
||||
memcpy(buf + idx, save, i + 1 + off);
|
||||
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
|
||||
|
||||
memcpy(afl->fsrv.shmem_fuzz, mem, skip_at);
|
||||
|
||||
memcpy(afl->fsrv.shmem_fuzz, mem + skip_at + skip_len, tail_len);
|
||||
memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len, tail_len);
|
||||
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,9 @@ static void usage(u8 *argv0, int more_help) {
|
||||
" See docs/README.MOpt.md\n"
|
||||
" -c program - enable CmpLog by specifying a binary compiled for "
|
||||
"it.\n"
|
||||
" if using QEMU, just use -c 0.\n"
|
||||
" if using QEMU/FRIDA or if you the fuzzing target is "
|
||||
"compiled"
|
||||
" for CmpLog then just use -c 0.\n"
|
||||
" -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n"
|
||||
" 1=small files, 2=larger files (default), 3=all "
|
||||
"files,\n"
|
||||
@ -466,6 +468,9 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
|
||||
dlsym(handle, "nyx_get_bitmap_buffer_size");
|
||||
if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; }
|
||||
|
||||
plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string");
|
||||
if (plugin->nyx_get_aux_string == NULL) { goto fail; }
|
||||
|
||||
OKF("libnyx plugin is ready!");
|
||||
return plugin;
|
||||
|
||||
@ -1458,6 +1463,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
|
||||
|
||||
if (afl->shm.cmplog_mode &&
|
||||
(!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
|
||||
|
||||
afl->cmplog_binary = argv[optind];
|
||||
|
||||
}
|
||||
|
||||
if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) {
|
||||
|
||||
WARNF(cLRD
|
||||
@ -1675,7 +1687,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (getenv("LD_PRELOAD")) {
|
||||
|
||||
WARNF(
|
||||
"LD_PRELOAD is set, are you sure that is what to you want to do "
|
||||
"LD_PRELOAD is set, are you sure that is what you want to do "
|
||||
"instead of using AFL_PRELOAD?");
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user