mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-16 11:58:08 +00:00
AFL_ENTRYPOINT instruction granularity
This commit is contained in:
@ -56,6 +56,7 @@
|
||||
|
||||
* qbdi_mode: fuzz android native libraries via QBDI framework
|
||||
|
||||
* The new CmpLog instrumentation for LLVM and QEMU inspired by [Redqueen](https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2018/12/17/NDSS19-Redqueen.pdf)
|
||||
|
||||
A more thorough list is available in the PATCHES file.
|
||||
|
||||
|
@ -34,6 +34,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- AFL_PERSISTENT_HOOK callback module for persistent QEMU
|
||||
(see examples/qemu_persistent_hook)
|
||||
- added qemu_mode/README.persistent.md documentation
|
||||
- AFL_ENTRYPOINT noew has instruction granularity
|
||||
- afl-cmin is now a sh script (invoking awk) instead of bash for portability
|
||||
the original script is still present as afl-cmin.bash
|
||||
- afl-showmap: -i dir option now allows processing multiple inputs using the
|
||||
|
@ -66,8 +66,7 @@ the deferred initialization.
|
||||
This can be enabled setting the environment variable AFL_ENTRYPOINT which allows
|
||||
to move the forkserver to a different part, e.g. just before the file is
|
||||
opened (e.g. way after command line parsing and config file loading, etc.)
|
||||
which can be a huge speed improvement. Note that the specified address
|
||||
must be an address of a basic block.
|
||||
which can be a huge speed improvement.
|
||||
|
||||
## 4) Bonus feature #2: persistent mode
|
||||
|
||||
|
@ -158,6 +158,9 @@ patch -p1 <../patches/i386-ops_sse.diff || exit 1
|
||||
patch -p1 <../patches/i386-fpu_helper.diff || exit 1
|
||||
patch -p1 <../patches/softfloat.diff || exit 1
|
||||
patch -p1 <../patches/configure.diff || exit 1
|
||||
patch -p1 <../patches/tcg-runtime.diff || exit 1
|
||||
patch -p1 <../patches/tcg-runtime-head.diff || exit 1
|
||||
patch -p1 <../patches/translator.diff || exit 1
|
||||
|
||||
echo "[+] Patching done."
|
||||
|
||||
|
@ -69,7 +69,7 @@ typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base);
|
||||
|
||||
extern unsigned char *afl_area_ptr;
|
||||
extern unsigned int afl_inst_rms;
|
||||
extern abi_ulong afl_start_code, afl_end_code;
|
||||
extern abi_ulong afl_entry_point, afl_start_code, afl_end_code;
|
||||
extern abi_ulong afl_persistent_addr;
|
||||
extern abi_ulong afl_persistent_ret_addr;
|
||||
extern u8 afl_compcov_level;
|
||||
@ -88,6 +88,9 @@ extern __thread abi_ulong afl_prev_loc;
|
||||
extern struct cmp_map *__afl_cmp_map;
|
||||
extern __thread u32 __afl_cmp_counter;
|
||||
|
||||
void afl_setup(void);
|
||||
void afl_forkserver(CPUState *cpu);
|
||||
|
||||
void afl_debug_dump_saved_regs();
|
||||
|
||||
void afl_persistent_loop();
|
||||
|
@ -42,22 +42,6 @@
|
||||
* VARIOUS AUXILIARY STUFF *
|
||||
***************************/
|
||||
|
||||
/* This snippet kicks in when the instruction pointer is positioned at
|
||||
_start and does the usual forkserver stuff, not very different from
|
||||
regular instrumentation injected via afl-as.h. */
|
||||
|
||||
#define AFL_QEMU_CPU_SNIPPET2 \
|
||||
do { \
|
||||
\
|
||||
if (itb->pc == afl_entry_point) { \
|
||||
\
|
||||
afl_setup(); \
|
||||
afl_forkserver(cpu); \
|
||||
\
|
||||
} \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/* We use one additional file descriptor to relay "needs translation"
|
||||
messages between the child and the fork server. */
|
||||
|
||||
@ -107,9 +91,6 @@ unsigned int afl_inst_rms = MAP_SIZE; /* Exported for afl_gen_trace */
|
||||
|
||||
/* Function declarations. */
|
||||
|
||||
static void afl_setup(void);
|
||||
static void afl_forkserver(CPUState *);
|
||||
|
||||
static void afl_wait_tsl(CPUState *, int);
|
||||
static void afl_request_tsl(target_ulong, target_ulong, uint32_t, uint32_t,
|
||||
TranslationBlock *, int);
|
||||
@ -155,7 +136,7 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
|
||||
|
||||
/* Set up SHM region and initialize other stuff. */
|
||||
|
||||
static void afl_setup(void) {
|
||||
void afl_setup(void) {
|
||||
|
||||
char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO");
|
||||
|
||||
@ -310,7 +291,7 @@ static void print_mappings(void) {
|
||||
|
||||
/* Fork server logic, invoked once we hit _start. */
|
||||
|
||||
static void afl_forkserver(CPUState *cpu) {
|
||||
void afl_forkserver(CPUState *cpu) {
|
||||
|
||||
static unsigned char tmp[4];
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
|
||||
index 870027d4..841ba557 100644
|
||||
index 870027d4..0bc87dfc 100644
|
||||
--- a/accel/tcg/cpu-exec.c
|
||||
+++ b/accel/tcg/cpu-exec.c
|
||||
@@ -36,6 +36,8 @@
|
||||
@ -11,16 +11,7 @@ index 870027d4..841ba557 100644
|
||||
/* -icount align implementation. */
|
||||
|
||||
typedef struct SyncClocks {
|
||||
@@ -144,6 +146,8 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
|
||||
int tb_exit;
|
||||
uint8_t *tb_ptr = itb->tc.ptr;
|
||||
|
||||
+ AFL_QEMU_CPU_SNIPPET2;
|
||||
+
|
||||
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
|
||||
"Trace %d: %p ["
|
||||
TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n",
|
||||
@@ -397,11 +401,13 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
@@ -397,11 +399,13 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
TranslationBlock *tb;
|
||||
target_ulong cs_base, pc;
|
||||
uint32_t flags;
|
||||
@ -34,7 +25,7 @@ index 870027d4..841ba557 100644
|
||||
mmap_unlock();
|
||||
/* We add the TB in the virtual pc hash table for the fast lookup */
|
||||
atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
|
||||
@@ -418,6 +424,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
@@ -418,6 +422,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
/* See if we can patch the calling TB. */
|
||||
if (last_tb) {
|
||||
tb_add_jump(last_tb, tb_exit, tb);
|
||||
|
10
qemu_mode/patches/tcg-runtime-head.diff
Normal file
10
qemu_mode/patches/tcg-runtime-head.diff
Normal file
@ -0,0 +1,10 @@
|
||||
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
|
||||
index 1bd39d13..944997ee 100644
|
||||
--- a/accel/tcg/tcg-runtime.h
|
||||
+++ b/accel/tcg/tcg-runtime.h
|
||||
@@ -260,3 +260,5 @@ DEF_HELPER_FLAGS_4(gvec_leu8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
+
|
||||
+DEF_HELPER_FLAGS_1(afl_entry_routine, TCG_CALL_NO_RWG, void, env)
|
24
qemu_mode/patches/tcg-runtime.diff
Normal file
24
qemu_mode/patches/tcg-runtime.diff
Normal file
@ -0,0 +1,24 @@
|
||||
diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
|
||||
index d0d44844..46154af1 100644
|
||||
--- a/accel/tcg/tcg-runtime.c
|
||||
+++ b/accel/tcg/tcg-runtime.c
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "disas/disas.h"
|
||||
#include "exec/log.h"
|
||||
|
||||
+#include "../../../patches/afl-qemu-common.h"
|
||||
+
|
||||
/* 32-bit helpers */
|
||||
|
||||
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)
|
||||
@@ -167,3 +169,10 @@ void HELPER(exit_atomic)(CPUArchState *env)
|
||||
{
|
||||
cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC());
|
||||
}
|
||||
+
|
||||
+
|
||||
+void HELPER(afl_entry_routine)(CPUArchState *env) {
|
||||
+
|
||||
+ afl_forkserver(ENV_GET_CPU(env));
|
||||
+
|
||||
+}
|
25
qemu_mode/patches/translator.diff
Normal file
25
qemu_mode/patches/translator.diff
Normal file
@ -0,0 +1,25 @@
|
||||
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
|
||||
index afd0a49e..773ea712 100644
|
||||
--- a/accel/tcg/translator.c
|
||||
+++ b/accel/tcg/translator.c
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "exec/log.h"
|
||||
#include "exec/translator.h"
|
||||
|
||||
+#include "../../../patches/afl-qemu-common.h"
|
||||
+
|
||||
/* Pairs with tcg_clear_temp_count.
|
||||
To be called by #TranslatorOps.{translate_insn,tb_stop} if
|
||||
(1) the target is sufficiently clean to support reporting,
|
||||
@@ -92,6 +94,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||
break;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (db->pc_next == afl_entry_point) {
|
||||
+ afl_setup();
|
||||
+ gen_helper_afl_entry_routine(cpu_env);
|
||||
+ }
|
||||
|
||||
/* Disassemble one instruction. The translate_insn hook should
|
||||
update db->pc_next and db->is_jmp to indicate what should be
|
Reference in New Issue
Block a user