mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-10 01:01:33 +00:00
removed unused diffs
This commit is contained in:
parent
f772d49faf
commit
e19e06aba7
@ -1,48 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop++ - unicorn instrumentation
|
||||
----------------------------------------------
|
||||
|
||||
Originally written by Andrew Griffiths <agriffiths@google.com> and
|
||||
Michal Zalewski
|
||||
|
||||
Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
|
||||
|
||||
CompareCoverage and NeverZero counters by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>
|
||||
|
||||
Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is a shim patched into the separately-distributed source
|
||||
code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
|
||||
to implement AFL-style instrumentation and to take care of the remaining
|
||||
parts of the AFL fork server logic.
|
||||
|
||||
The resulting libunicorn binary is essentially a standalone instrumentation
|
||||
tool; for an example of how to leverage it for other purposes, you can
|
||||
have a look at afl-showmap.c.
|
||||
|
||||
*/
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
/* NeverZero */
|
||||
|
||||
#if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO)
|
||||
#define INC_AFL_AREA(loc) \
|
||||
asm volatile( \
|
||||
"incb (%0, %1, 1)\n" \
|
||||
"adcb $0, (%0, %1, 1)\n" \
|
||||
: /* no out */ \
|
||||
: "r"(afl_area_ptr), "r"(loc) \
|
||||
: "memory", "eax")
|
||||
#else
|
||||
#define INC_AFL_AREA(loc) afl_area_ptr[loc]++
|
||||
#endif
|
||||
|
@ -1,293 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop++ - unicorn instrumentation
|
||||
----------------------------------------------
|
||||
|
||||
Originally written by Andrew Griffiths <agriffiths@google.com> and
|
||||
Michal Zalewski
|
||||
|
||||
Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
|
||||
|
||||
CompareCoverage and NeverZero counters by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>
|
||||
|
||||
Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is a shim patched into the separately-distributed source
|
||||
code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
|
||||
to implement AFL-style instrumentation and to take care of the remaining
|
||||
parts of the AFL fork server logic.
|
||||
|
||||
The resulting libunicorn binary is essentially a standalone instrumentation
|
||||
tool; for an example of how to leverage it for other purposes, you can
|
||||
have a look at afl-showmap.c.
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include "afl-unicorn-common.h"
|
||||
|
||||
/***************************
|
||||
* VARIOUS AUXILIARY STUFF *
|
||||
***************************/
|
||||
|
||||
/* A snippet patched into tb_find_slow to inform the parent process that
|
||||
we have hit a new block that hasn't been translated yet, and to tell
|
||||
it to translate within its own context, too (this avoids translation
|
||||
overhead in the next forked-off copy). */
|
||||
|
||||
#define AFL_UNICORN_CPU_SNIPPET1 \
|
||||
do { \
|
||||
\
|
||||
afl_request_tsl(pc, cs_base, flags); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/* 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_UNICORN_CPU_SNIPPET2 \
|
||||
do { \
|
||||
\
|
||||
if (unlikely(afl_first_instr == 0)) { \
|
||||
\
|
||||
afl_setup(env->uc); \
|
||||
afl_forkserver(env); \
|
||||
afl_first_instr = 1; \
|
||||
\
|
||||
} \
|
||||
afl_maybe_log(env->uc, tb->pc); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/* We use one additional file descriptor to relay "needs translation"
|
||||
messages between the child and the fork server. */
|
||||
|
||||
#define TSL_FD (FORKSRV_FD - 1)
|
||||
|
||||
/* Set in the child process in forkserver mode: */
|
||||
|
||||
static unsigned char afl_fork_child;
|
||||
static unsigned int afl_forksrv_pid;
|
||||
|
||||
/* Function declarations. */
|
||||
|
||||
static void afl_setup(struct uc_struct* uc);
|
||||
static void afl_forkserver(CPUArchState*);
|
||||
static inline void afl_maybe_log(struct uc_struct* uc, unsigned long);
|
||||
|
||||
static void afl_wait_tsl(CPUArchState*, int);
|
||||
static void afl_request_tsl(target_ulong, target_ulong, uint64_t);
|
||||
|
||||
static TranslationBlock* tb_find_slow(CPUArchState*, target_ulong, target_ulong,
|
||||
uint64_t);
|
||||
|
||||
/* Data structure passed around by the translate handlers: */
|
||||
|
||||
struct afl_tsl {
|
||||
|
||||
target_ulong pc;
|
||||
target_ulong cs_base;
|
||||
uint64_t flags;
|
||||
|
||||
};
|
||||
|
||||
/*************************
|
||||
* ACTUAL IMPLEMENTATION *
|
||||
*************************/
|
||||
|
||||
/* Set up SHM region and initialize other stuff. */
|
||||
|
||||
static void afl_setup(struct uc_struct* uc) {
|
||||
|
||||
char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO");
|
||||
|
||||
int shm_id;
|
||||
|
||||
if (inst_r) {
|
||||
|
||||
unsigned int r;
|
||||
|
||||
r = atoi(inst_r);
|
||||
|
||||
if (r > 100) r = 100;
|
||||
if (!r) r = 1;
|
||||
|
||||
uc->afl_inst_rms = MAP_SIZE * r / 100;
|
||||
|
||||
} else {
|
||||
|
||||
uc->afl_inst_rms = MAP_SIZE;
|
||||
|
||||
}
|
||||
|
||||
if (id_str) {
|
||||
|
||||
shm_id = atoi(id_str);
|
||||
uc->afl_area_ptr = shmat(shm_id, NULL, 0);
|
||||
|
||||
if (uc->afl_area_ptr == (void*)-1) exit(1);
|
||||
|
||||
/* With AFL_INST_RATIO set to a low value, we want to touch the bitmap
|
||||
so that the parent doesn't give up on us. */
|
||||
|
||||
if (inst_r) uc->afl_area_ptr[0] = 1;
|
||||
|
||||
}
|
||||
|
||||
/* Maintain for compatibility */
|
||||
if (getenv("AFL_QEMU_COMPCOV")) { uc->afl_compcov_level = 1; }
|
||||
if (getenv("AFL_COMPCOV_LEVEL")) {
|
||||
|
||||
uc->afl_compcov_level = atoi(getenv("AFL_COMPCOV_LEVEL"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Fork server logic, invoked once we hit first emulated instruction. */
|
||||
|
||||
static void afl_forkserver(CPUArchState* env) {
|
||||
|
||||
static unsigned char tmp[4];
|
||||
|
||||
if (!env->uc->afl_area_ptr) return;
|
||||
|
||||
/* Tell the parent that we're alive. If the parent doesn't want
|
||||
to talk, assume that we're not running in forkserver mode. */
|
||||
|
||||
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
|
||||
|
||||
afl_forksrv_pid = getpid();
|
||||
|
||||
/* All right, let's await orders... */
|
||||
|
||||
while (1) {
|
||||
|
||||
pid_t child_pid;
|
||||
int status, t_fd[2];
|
||||
|
||||
/* Whoops, parent dead? */
|
||||
|
||||
if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);
|
||||
|
||||
/* Establish a channel with child to grab translation commands. We'll
|
||||
read from t_fd[0], child will write to TSL_FD. */
|
||||
|
||||
if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);
|
||||
close(t_fd[1]);
|
||||
|
||||
child_pid = fork();
|
||||
if (child_pid < 0) exit(4);
|
||||
|
||||
if (!child_pid) {
|
||||
|
||||
/* Child process. Close descriptors and run free. */
|
||||
|
||||
afl_fork_child = 1;
|
||||
close(FORKSRV_FD);
|
||||
close(FORKSRV_FD + 1);
|
||||
close(t_fd[0]);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Parent. */
|
||||
|
||||
close(TSL_FD);
|
||||
|
||||
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);
|
||||
|
||||
/* Collect translation requests until child dies and closes the pipe. */
|
||||
|
||||
afl_wait_tsl(env, t_fd[0]);
|
||||
|
||||
/* Get and relay exit status to parent. */
|
||||
|
||||
if (waitpid(child_pid, &status, 0) < 0) exit(6);
|
||||
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The equivalent of the tuple logging routine from afl-as.h. */
|
||||
|
||||
static inline void afl_maybe_log(struct uc_struct* uc, unsigned long cur_loc) {
|
||||
|
||||
static __thread unsigned long prev_loc;
|
||||
|
||||
u8* afl_area_ptr = uc->afl_area_ptr;
|
||||
|
||||
if (!afl_area_ptr) return;
|
||||
|
||||
/* Looks like QEMU always maps to fixed locations, so ASAN is not a
|
||||
concern. Phew. But instruction addresses may be aligned. Let's mangle
|
||||
the value to get something quasi-uniform. */
|
||||
|
||||
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
|
||||
cur_loc &= MAP_SIZE - 1;
|
||||
|
||||
/* Implement probabilistic instrumentation by looking at scrambled block
|
||||
address. This keeps the instrumented locations stable across runs. */
|
||||
|
||||
if (cur_loc >= uc->afl_inst_rms) return;
|
||||
|
||||
register uintptr_t afl_idx = cur_loc ^ prev_loc;
|
||||
|
||||
INC_AFL_AREA(afl_idx);
|
||||
|
||||
prev_loc = cur_loc >> 1;
|
||||
|
||||
}
|
||||
|
||||
/* This code is invoked whenever QEMU decides that it doesn't have a
|
||||
translation of a particular block and needs to compute it. When this happens,
|
||||
we tell the parent to mirror the operation, so that the next fork() has a
|
||||
cached copy. */
|
||||
|
||||
static void afl_request_tsl(target_ulong pc, target_ulong cb, uint64_t flags) {
|
||||
|
||||
struct afl_tsl t;
|
||||
|
||||
if (!afl_fork_child) return;
|
||||
|
||||
t.pc = pc;
|
||||
t.cs_base = cb;
|
||||
t.flags = flags;
|
||||
|
||||
if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* This is the other side of the same channel. Since timeouts are handled by
|
||||
afl-fuzz simply killing the child, we can just wait until the pipe breaks. */
|
||||
|
||||
static void afl_wait_tsl(CPUArchState* env, int fd) {
|
||||
|
||||
struct afl_tsl t;
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Broken pipe means it's time to return to the fork server routine. */
|
||||
|
||||
if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break;
|
||||
|
||||
tb_find_slow(env, t.pc, t.cs_base, t.flags);
|
||||
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop++ - unicorn instrumentation
|
||||
----------------------------------------------
|
||||
|
||||
Originally written by Andrew Griffiths <agriffiths@google.com> and
|
||||
Michal Zalewski
|
||||
|
||||
Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
|
||||
|
||||
CompareCoverage and NeverZero counters by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>
|
||||
|
||||
Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is a shim patched into the separately-distributed source
|
||||
code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
|
||||
to implement AFL-style instrumentation and to take care of the remaining
|
||||
parts of the AFL fork server logic.
|
||||
|
||||
The resulting libunicorn binary is essentially a standalone instrumentation
|
||||
tool; for an example of how to leverage it for other purposes, you can
|
||||
have a look at afl-showmap.c.
|
||||
|
||||
*/
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
static void afl_gen_compcov(TCGContext *s, uint64_t cur_loc, TCGv_i64 arg1,
|
||||
TCGv_i64 arg2, TCGMemOp ot, int is_imm) {
|
||||
|
||||
if (!s->uc->afl_compcov_level || !s->uc->afl_area_ptr) return;
|
||||
|
||||
if (!is_imm && s->uc->afl_compcov_level < 2) return;
|
||||
|
||||
cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
|
||||
cur_loc &= MAP_SIZE - 7;
|
||||
|
||||
if (cur_loc >= s->uc->afl_inst_rms) return;
|
||||
|
||||
switch (ot) {
|
||||
|
||||
case MO_64: gen_afl_compcov_log_64(s, cur_loc, arg1, arg2); break;
|
||||
case MO_32: gen_afl_compcov_log_32(s, cur_loc, arg1, arg2); break;
|
||||
case MO_16: gen_afl_compcov_log_16(s, cur_loc, arg1, arg2); break;
|
||||
default: return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop++ - unicorn instrumentation
|
||||
----------------------------------------------
|
||||
|
||||
Originally written by Andrew Griffiths <agriffiths@google.com> and
|
||||
Michal Zalewski
|
||||
|
||||
Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
|
||||
|
||||
CompareCoverage and NeverZero counters by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>
|
||||
|
||||
Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is a shim patched into the separately-distributed source
|
||||
code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
|
||||
to implement AFL-style instrumentation and to take care of the remaining
|
||||
parts of the AFL fork server logic.
|
||||
|
||||
The resulting libunicorn binary is essentially a standalone instrumentation
|
||||
tool; for an example of how to leverage it for other purposes, you can
|
||||
have a look at afl-showmap.c.
|
||||
|
||||
*/
|
||||
|
||||
static inline void gen_afl_compcov_log_16(TCGContext *tcg_ctx, uint64_t cur_loc,
|
||||
TCGv_i64 arg1, TCGv_i64 arg2) {
|
||||
|
||||
TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
|
||||
TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
|
||||
gen_helper_afl_compcov_log_16(tcg_ctx, tuc, tcur_loc, arg1, arg2);
|
||||
|
||||
}
|
||||
|
||||
static inline void gen_afl_compcov_log_32(TCGContext *tcg_ctx, uint64_t cur_loc,
|
||||
TCGv_i64 arg1, TCGv_i64 arg2) {
|
||||
|
||||
TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
|
||||
TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
|
||||
gen_helper_afl_compcov_log_32(tcg_ctx, tuc, tcur_loc, arg1, arg2);
|
||||
|
||||
}
|
||||
|
||||
static inline void gen_afl_compcov_log_64(TCGContext *tcg_ctx, uint64_t cur_loc,
|
||||
TCGv_i64 arg1, TCGv_i64 arg2) {
|
||||
|
||||
TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
|
||||
TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
|
||||
gen_helper_afl_compcov_log_64(tcg_ctx, tuc, tcur_loc, arg1, arg2);
|
||||
|
||||
}
|
||||
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
american fuzzy lop++ - unicorn instrumentation
|
||||
----------------------------------------------
|
||||
|
||||
Originally written by Andrew Griffiths <agriffiths@google.com> and
|
||||
Michal Zalewski
|
||||
|
||||
Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
|
||||
|
||||
CompareCoverage and NeverZero counters by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>
|
||||
|
||||
Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at:
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
This code is a shim patched into the separately-distributed source
|
||||
code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
|
||||
to implement AFL-style instrumentation and to take care of the remaining
|
||||
parts of the AFL fork server logic.
|
||||
|
||||
The resulting libunicorn binary is essentially a standalone instrumentation
|
||||
tool; for an example of how to leverage it for other purposes, you can
|
||||
have a look at afl-showmap.c.
|
||||
|
||||
*/
|
||||
|
||||
#include "uc_priv.h"
|
||||
#include "afl-unicorn-common.h"
|
||||
|
||||
void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff) == (arg2 & 0xff)) { INC_AFL_AREA(cur_loc); }
|
||||
|
||||
}
|
||||
|
||||
void HELPER(afl_compcov_log_32)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff) == (arg2 & 0xff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc);
|
||||
if ((arg1 & 0xffff) == (arg2 & 0xffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 1);
|
||||
if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { INC_AFL_AREA(cur_loc + 2); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff) == (arg2 & 0xff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc);
|
||||
if ((arg1 & 0xffff) == (arg2 & 0xffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 1);
|
||||
if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 2);
|
||||
if ((arg1 & 0xffffffff) == (arg2 & 0xffffffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 3);
|
||||
if ((arg1 & 0xffffffffff) == (arg2 & 0xffffffffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 4);
|
||||
if ((arg1 & 0xffffffffffff) == (arg2 & 0xffffffffffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 5);
|
||||
if ((arg1 & 0xffffffffffffff) == (arg2 & 0xffffffffffffff)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 6);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* // Little endian CompCov
|
||||
void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
|
||||
|
||||
}
|
||||
|
||||
void HELPER(afl_compcov_log_32)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 2);
|
||||
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 1);
|
||||
if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
|
||||
u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
|
||||
|
||||
if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 6);
|
||||
if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 5);
|
||||
if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 4);
|
||||
if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 3);
|
||||
if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 2);
|
||||
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
|
||||
|
||||
INC_AFL_AREA(cur_loc + 1);
|
||||
if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
@ -1,251 +0,0 @@
|
||||
diff --git a/include/uc_priv.h b/include/uc_priv.h
|
||||
index 22f494e..1aa7b3a 100644
|
||||
--- a/include/uc_priv.h
|
||||
+++ b/include/uc_priv.h
|
||||
@@ -245,6 +245,12 @@ struct uc_struct {
|
||||
uint32_t target_page_align;
|
||||
uint64_t next_pc; // save next PC for some special cases
|
||||
bool hook_insert; // insert new hook at begin of the hook list (append by default)
|
||||
+
|
||||
+#ifdef UNICORN_AFL
|
||||
+ unsigned char *afl_area_ptr;
|
||||
+ int afl_compcov_level;
|
||||
+ unsigned int afl_inst_rms;
|
||||
+#endif
|
||||
};
|
||||
|
||||
// Metadata stub for the variable-size cpu context used with uc_context_*()
|
||||
diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c
|
||||
index 4995eda..06c7e63 100644
|
||||
--- a/qemu/target-arm/translate.c
|
||||
+++ b/qemu/target-arm/translate.c
|
||||
@@ -63,6 +63,12 @@ static TCGv_i64 cpu_exclusive_test;
|
||||
static TCGv_i32 cpu_exclusive_info;
|
||||
#endif
|
||||
|
||||
+#if defined(UNICORN_AFL)
|
||||
+#include "../../afl-unicorn-cpu-translate-inl.h"
|
||||
+#else
|
||||
+#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0)
|
||||
+#endif
|
||||
+
|
||||
|
||||
static const char *regnames[] =
|
||||
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
@@ -8214,6 +8220,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
||||
} else {
|
||||
if (set_cc) {
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
|
||||
} else {
|
||||
tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
|
||||
}
|
||||
@@ -8223,6 +8230,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
||||
case 0x03:
|
||||
if (set_cc) {
|
||||
gen_sub_CC(s, tmp, tmp2, tmp);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
|
||||
} else {
|
||||
tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
|
||||
}
|
||||
@@ -8277,6 +8285,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
||||
case 0x0a:
|
||||
if (set_cc) {
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
|
||||
}
|
||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||
break;
|
||||
@@ -9148,7 +9157,7 @@ thumb2_logic_op(int op)
|
||||
|
||||
static int
|
||||
gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
|
||||
- TCGv_i32 t0, TCGv_i32 t1)
|
||||
+ TCGv_i32 t0, TCGv_i32 t1, int has_imm)
|
||||
{
|
||||
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||
int logic_cc;
|
||||
@@ -9195,15 +9204,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
|
||||
}
|
||||
break;
|
||||
case 13: /* sub */
|
||||
- if (conds)
|
||||
+ if (conds) {
|
||||
gen_sub_CC(s, t0, t0, t1);
|
||||
- else
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm);
|
||||
+ } else
|
||||
tcg_gen_sub_i32(tcg_ctx, t0, t0, t1);
|
||||
break;
|
||||
case 14: /* rsb */
|
||||
- if (conds)
|
||||
+ if (conds) {
|
||||
gen_sub_CC(s, t0, t1, t0);
|
||||
- else
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm);
|
||||
+ } else
|
||||
tcg_gen_sub_i32(tcg_ctx, t0, t1, t0);
|
||||
break;
|
||||
default: /* 5, 6, 7, 9, 12, 15. */
|
||||
@@ -9572,7 +9583,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
conds = (insn & (1 << 20)) != 0;
|
||||
logic_cc = (conds && thumb2_logic_op(op));
|
||||
gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
|
||||
- if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
|
||||
+ if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10)))
|
||||
goto illegal_op;
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
if (rd != 15) {
|
||||
@@ -10215,7 +10226,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||
}
|
||||
op = (insn >> 21) & 0xf;
|
||||
if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
|
||||
- shifter_out, tmp, tmp2))
|
||||
+ shifter_out, tmp, tmp2, insn & (1 << 10)))
|
||||
goto illegal_op;
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
rd = (insn >> 8) & 0xf;
|
||||
@@ -10471,8 +10482,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||
if (insn & (1 << 9)) {
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
|
||||
- else
|
||||
+ else {
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 10));
|
||||
+ }
|
||||
} else {
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
|
||||
@@ -10509,6 +10522,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||
switch (op) {
|
||||
case 1: /* cmp */
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
break;
|
||||
@@ -10523,8 +10537,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||
case 3: /* sub */
|
||||
if (s->condexec_mask)
|
||||
tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
|
||||
- else
|
||||
+ else {
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1);
|
||||
+ }
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
@@ -10562,6 +10578,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||
tmp = load_reg(s, rd);
|
||||
tmp2 = load_reg(s, rm);
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||
break;
|
||||
@@ -10680,6 +10697,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||
break;
|
||||
case 0xa: /* cmp */
|
||||
gen_sub_CC(s, tmp, tmp, tmp2);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0);
|
||||
rd = 16;
|
||||
break;
|
||||
case 0xb: /* cmn */
|
||||
diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c
|
||||
index 36fae09..196d346 100644
|
||||
--- a/qemu/target-i386/translate.c
|
||||
+++ b/qemu/target-i386/translate.c
|
||||
@@ -33,6 +33,12 @@
|
||||
|
||||
#include "uc_priv.h"
|
||||
|
||||
+#if defined(UNICORN_AFL)
|
||||
+#include "../../afl-unicorn-cpu-translate-inl.h"
|
||||
+#else
|
||||
+#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0)
|
||||
+#endif
|
||||
+
|
||||
#define PREFIX_REPZ 0x01
|
||||
#define PREFIX_REPNZ 0x02
|
||||
#define PREFIX_LOCK 0x04
|
||||
@@ -1555,6 +1561,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d)
|
||||
case OP_SUBL:
|
||||
tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]);
|
||||
tcg_gen_sub_tl(tcg_ctx, *cpu_T[0], *cpu_T[0], *cpu_T[1]);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX);
|
||||
gen_op_st_rm_T0_A0(s, ot, d);
|
||||
gen_op_update2_cc(tcg_ctx);
|
||||
set_cc_op(s, CC_OP_SUBB + ot);
|
||||
@@ -1582,6 +1589,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d)
|
||||
tcg_gen_mov_tl(tcg_ctx, cpu_cc_src, *cpu_T[1]);
|
||||
tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]);
|
||||
tcg_gen_sub_tl(tcg_ctx, cpu_cc_dst, *cpu_T[0], *cpu_T[1]);
|
||||
+ afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX);
|
||||
set_cc_op(s, CC_OP_SUBB + ot);
|
||||
break;
|
||||
}
|
||||
diff --git a/qemu/tcg-runtime.c b/qemu/tcg-runtime.c
|
||||
index 21b022a..14d7891 100644
|
||||
--- a/qemu/tcg-runtime.c
|
||||
+++ b/qemu/tcg-runtime.c
|
||||
@@ -31,9 +31,14 @@
|
||||
|
||||
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
|
||||
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
|
||||
+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
|
||||
+ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4));
|
||||
|
||||
#include "tcg-runtime.h"
|
||||
|
||||
+#ifdef UNICORN_AFL
|
||||
+#include "../afl-unicorn-tcg-runtime-inl.h"
|
||||
+#endif
|
||||
|
||||
/* 32-bit helpers */
|
||||
|
||||
diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h
|
||||
index 38b7dd9..c5a9af9 100644
|
||||
--- a/qemu/tcg/tcg-op.h
|
||||
+++ b/qemu/tcg/tcg-op.h
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
int gen_new_label(TCGContext *);
|
||||
|
||||
+#ifdef UNICORN_AFL
|
||||
+#include "../../afl-unicorn-tcg-op-inl.h"
|
||||
+#endif
|
||||
+
|
||||
static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, int32_t type, void *uc, uint64_t pc)
|
||||
{
|
||||
TCGv_i32 tsize = tcg_const_i32(tcg_ctx, size);
|
||||
diff --git a/qemu/tcg/tcg-runtime.h b/qemu/tcg/tcg-runtime.h
|
||||
index 23a0c37..90b993c 100644
|
||||
--- a/qemu/tcg/tcg-runtime.h
|
||||
+++ b/qemu/tcg/tcg-runtime.h
|
||||
@@ -14,3 +14,9 @@ DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
|
||||
|
||||
DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
|
||||
DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||
+
|
||||
+#ifdef UNICORN_AFL
|
||||
+DEF_HELPER_FLAGS_4(afl_compcov_log_16, 0, void, ptr, i64, i64, i64)
|
||||
+DEF_HELPER_FLAGS_4(afl_compcov_log_32, 0, void, ptr, i64, i64, i64)
|
||||
+DEF_HELPER_FLAGS_4(afl_compcov_log_64, 0, void, ptr, i64, i64, i64)
|
||||
+#endif
|
||||
diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h
|
||||
index 8dcbb3e..11e18b4 100644
|
||||
--- a/qemu/unicorn_common.h
|
||||
+++ b/qemu/unicorn_common.h
|
||||
@@ -84,6 +84,10 @@ static inline void uc_common_init(struct uc_struct* uc)
|
||||
|
||||
if (!uc->release)
|
||||
uc->release = release_common;
|
||||
+
|
||||
+#ifdef UNICORN_AFL
|
||||
+ uc->afl_area_ptr = 0;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,107 +0,0 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 7d73782..fb3ccfd 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -88,6 +88,10 @@ AR = llvm-ar
|
||||
LDFLAGS := -fsanitize=address ${LDFLAGS}
|
||||
endif
|
||||
|
||||
+ifeq ($(UNICORN_AFL),yes)
|
||||
+UNICORN_CFLAGS += -DUNICORN_AFL
|
||||
+endif
|
||||
+
|
||||
ifeq ($(CROSS),)
|
||||
CC ?= cc
|
||||
AR ?= ar
|
||||
diff --git a/config.mk b/config.mk
|
||||
index c3621fb..c7b4f7e 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -8,7 +8,7 @@
|
||||
# Compile with debug info when you want to debug code.
|
||||
# Change this to 'no' for release edition.
|
||||
|
||||
-UNICORN_DEBUG ?= yes
|
||||
+UNICORN_DEBUG ?= no
|
||||
|
||||
################################################################################
|
||||
# Specify which archs you want to compile in. By default, we build all archs.
|
||||
@@ -28,3 +28,9 @@ UNICORN_STATIC ?= yes
|
||||
# a shared library.
|
||||
|
||||
UNICORN_SHARED ?= yes
|
||||
+
|
||||
+
|
||||
+################################################################################
|
||||
+# Changing 'UNICORN_AFLL = yes' to 'UNICORN_AFL = no' disables AFL instrumentation
|
||||
+
|
||||
+UNICORN_AFL ?= yes
|
||||
diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c
|
||||
index 7755adf..8114b70 100644
|
||||
--- a/qemu/cpu-exec.c
|
||||
+++ b/qemu/cpu-exec.c
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
#include "uc_priv.h"
|
||||
|
||||
+#if defined(UNICORN_AFL)
|
||||
+#include "../afl-unicorn-cpu-inl.h"
|
||||
+static int afl_first_instr = 0;
|
||||
+#endif
|
||||
+
|
||||
static tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr);
|
||||
static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
|
||||
target_ulong cs_base, uint64_t flags);
|
||||
@@ -231,6 +236,10 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||
next_tb & TB_EXIT_MASK, tb);
|
||||
}
|
||||
|
||||
+#if defined(UNICORN_AFL)
|
||||
+ AFL_UNICORN_CPU_SNIPPET2;
|
||||
+#endif
|
||||
+
|
||||
/* cpu_interrupt might be called while translating the
|
||||
TB, but before it is linked into a potentially
|
||||
infinite loop and becomes env->current_tb. Avoid
|
||||
@@ -369,6 +378,11 @@ static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
|
||||
not_found:
|
||||
/* if no translated code available, then translate it now */
|
||||
tb = tb_gen_code(cpu, pc, cs_base, (int)flags, 0); // qq
|
||||
+
|
||||
+#if defined(UNICORN_AFL)
|
||||
+ /* There seems to be no chaining in unicorn ever? :( */
|
||||
+ AFL_UNICORN_CPU_SNIPPET1;
|
||||
+#endif
|
||||
|
||||
found:
|
||||
/* Move the last found TB to the head of the list */
|
||||
diff --git a/qemu/translate-all.c b/qemu/translate-all.c
|
||||
index 1a96c34..7ef4878 100644
|
||||
--- a/qemu/translate-all.c
|
||||
+++ b/qemu/translate-all.c
|
||||
@@ -403,11 +403,25 @@ static PageDesc *page_find_alloc(struct uc_struct *uc, tb_page_addr_t index, int
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
/* We can't use g_malloc because it may recurse into a locked mutex. */
|
||||
+#if defined(UNICORN_AFL)
|
||||
+ /* This was added by unicorn-afl to bail out semi-gracefully if out of memory. */
|
||||
+# define ALLOC(P, SIZE) \
|
||||
+ do { \
|
||||
+ void* _tmp = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
|
||||
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
|
||||
+ if (_tmp == (void*)-1) { \
|
||||
+ qemu_log(">>> Out of memory for stack, bailing out. <<<\n"); \
|
||||
+ exit(1); \
|
||||
+ } \
|
||||
+ (P) = _tmp; \
|
||||
+ } while (0)
|
||||
+#else /* !UNICORN_AFL */
|
||||
# define ALLOC(P, SIZE) \
|
||||
do { \
|
||||
P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
|
||||
} while (0)
|
||||
+#endif /* UNICORN_AFL */
|
||||
#else
|
||||
# define ALLOC(P, SIZE) \
|
||||
do { P = g_malloc0(SIZE); } while (0)
|
Loading…
x
Reference in New Issue
Block a user