persistent qemu should now works as expected

This commit is contained in:
Andrea Fioraldi
2019-10-08 12:39:11 +02:00
parent 78d9fa280c
commit eae4a9e1f8
5 changed files with 92 additions and 37 deletions

View File

@ -71,7 +71,8 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/file.h> #include <sys/file.h>
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__NetBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */ #endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */

View File

@ -510,8 +510,10 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
? 24 ? 24
: sizeInBits == 64 : sizeInBits == 64
? 53 ? 53
: sizeInBits == 128 ? 113 : sizeInBits == 16 ? 11 : sizeInBits == 128 ? 113
/* sizeInBits == 80 */ : 65; : sizeInBits == 16 ? 11
/* sizeInBits == 80 */
: 65;
const unsigned shiftR_exponent = precision - 1; const unsigned shiftR_exponent = precision - 1;
const unsigned long long mask_fraction = const unsigned long long mask_fraction =
@ -522,17 +524,17 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
// round up sizes to the next power of two // round up sizes to the next power of two
// this should help with integer compare splitting // this should help with integer compare splitting
size_t exTySizeBytes = ((sizeInBits - precision + 7) >> 3); size_t exTySizeBytes = ((sizeInBits - precision + 7) >> 3);
size_t frTySizeBytes = ((precision - 1ULL + 7) >> 3); size_t frTySizeBytes = ((precision - 1ULL + 7) >> 3);
IntegerType *IntExponentTy = IntegerType *IntExponentTy =
IntegerType::get(C, nextPowerOfTwo(exTySizeBytes) << 3); IntegerType::get(C, nextPowerOfTwo(exTySizeBytes) << 3);
IntegerType *IntFractionTy = IntegerType *IntFractionTy =
IntegerType::get(C, nextPowerOfTwo(frTySizeBytes) << 3); IntegerType::get(C, nextPowerOfTwo(frTySizeBytes) << 3);
// errs() << "Fractions: IntFractionTy size " << // errs() << "Fractions: IntFractionTy size " <<
// IntFractionTy->getPrimitiveSizeInBits() << ", op_size " << op_size << // IntFractionTy->getPrimitiveSizeInBits() << ", op_size " << op_size <<
// ", mask " << mask_fraction << // ", mask " << mask_fraction <<
// ", precision " << precision << "\n"; // ", precision " << precision << "\n";
BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst)); BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(FcmpInst));
@ -552,16 +554,16 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
* the original operands so only the first bit remains.*/ * the original operands so only the first bit remains.*/
Instruction *s_s0, *t_s0, *s_s1, *t_s1, *icmp_sign_bit; Instruction *s_s0, *t_s0, *s_s1, *t_s1, *icmp_sign_bit;
s_s0 = BinaryOperator::Create( s_s0 =
Instruction::LShr, b_op0, BinaryOperator::Create(Instruction::LShr, b_op0,
ConstantInt::get(b_op0->getType(), op_size - 1)); ConstantInt::get(b_op0->getType(), op_size - 1));
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s0); bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s0);
t_s0 = new TruncInst(s_s0, Int1Ty); t_s0 = new TruncInst(s_s0, Int1Ty);
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s0); bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s0);
s_s1 = BinaryOperator::Create( s_s1 =
Instruction::LShr, b_op1, BinaryOperator::Create(Instruction::LShr, b_op1,
ConstantInt::get(b_op1->getType(), op_size - 1)); ConstantInt::get(b_op1->getType(), op_size - 1));
bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s1); bb->getInstList().insert(bb->getTerminator()->getIterator(), s_s1);
t_s1 = new TruncInst(s_s1, Int1Ty); t_s1 = new TruncInst(s_s1, Int1Ty);
bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s1); bb->getInstList().insert(bb->getTerminator()->getIterator(), t_s1);

View File

@ -88,7 +88,7 @@ unsigned char afl_fork_child;
unsigned int afl_forksrv_pid; unsigned int afl_forksrv_pid;
unsigned char is_persistent; unsigned char is_persistent;
target_long persistent_stack_offset; target_long persistent_stack_offset;
unsigned char persistent_first_pass; unsigned char persistent_first_pass = 1;
unsigned char persistent_save_gpr; unsigned char persistent_save_gpr;
target_ulong persistent_saved_gpr[AFL_REGS_NUM]; target_ulong persistent_saved_gpr[AFL_REGS_NUM];
int persisent_retaddr_offset; int persisent_retaddr_offset;
@ -210,10 +210,10 @@ static void afl_setup(void) {
if (is_persistent) { if (is_persistent) {
afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 16); afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 0);
if (getenv("AFL_QEMU_PERSISTENT_RET")) if (getenv("AFL_QEMU_PERSISTENT_RET"))
afl_persistent_ret_addr = afl_persistent_ret_addr =
strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 16); strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 0);
/* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */ /* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */
} }
@ -222,20 +222,19 @@ static void afl_setup(void) {
if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET")) if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"))
persisent_retaddr_offset = persisent_retaddr_offset =
strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 16); strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0);
if (getenv("AFL_QEMU_PERSISTENT_CNT")) if (getenv("AFL_QEMU_PERSISTENT_CNT"))
afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 16); afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 0);
else else
afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT; afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT;
} }
static void print_mappings(void) { static void print_mappings(void) {
u8 buf[MAX_LINE]; u8 buf[MAX_LINE];
FILE* f = fopen("/proc/self/maps", "r"); FILE *f = fopen("/proc/self/maps", "r");
if (!f) return; if (!f) return;
@ -254,9 +253,8 @@ static void afl_forkserver(CPUState *cpu) {
if (forkserver_installed == 1) return; if (forkserver_installed == 1) return;
forkserver_installed = 1; forkserver_installed = 1;
if (getenv("AFL_QEMU_DEBUG_MAPS")) if (getenv("AFL_QEMU_DEBUG_MAPS")) print_mappings();
print_mappings();
// if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer // if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer
@ -394,6 +392,7 @@ void afl_persistent_loop() {
sizeof(struct afl_tsl)) { sizeof(struct afl_tsl)) {
/* Exit the persistent loop on pipe error */ /* Exit the persistent loop on pipe error */
afl_area_ptr = dummy;
exit(0); exit(0);
} }
@ -405,6 +404,7 @@ void afl_persistent_loop() {
} else { } else {
afl_area_ptr = dummy;
exit(0); exit(0);
} }

View File

@ -51,7 +51,7 @@ static void afl_compcov_log_32(target_ulong cur_loc, target_ulong arg1,
if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
INC_AFL_AREA(idx +2); INC_AFL_AREA(idx + 2);
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
INC_AFL_AREA(idx + 1); INC_AFL_AREA(idx + 1);
@ -70,7 +70,7 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1,
if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) {
INC_AFL_AREA(idx +6); INC_AFL_AREA(idx + 6);
if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) {
INC_AFL_AREA(idx + 5); INC_AFL_AREA(idx + 5);
@ -86,11 +86,7 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1,
if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
INC_AFL_AREA(idx + 1); INC_AFL_AREA(idx + 1);
if ((arg1 & 0xff00) == (arg2 & 0xff00)) { if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); }
INC_AFL_AREA(idx);
}
} }
@ -134,6 +130,58 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
} }
/* Routines for debug */
/*
static void log_x86_saved_gpr(void) {
static const char reg_names[CPU_NB_REGS][4] = {
#ifdef TARGET_X86_64
[R_EAX] = "rax",
[R_EBX] = "rbx",
[R_ECX] = "rcx",
[R_EDX] = "rdx",
[R_ESI] = "rsi",
[R_EDI] = "rdi",
[R_EBP] = "rbp",
[R_ESP] = "rsp",
[8] = "r8",
[9] = "r9",
[10] = "r10",
[11] = "r11",
[12] = "r12",
[13] = "r13",
[14] = "r14",
[15] = "r15",
#else
[R_EAX] = "eax",
[R_EBX] = "ebx",
[R_ECX] = "ecx",
[R_EDX] = "edx",
[R_ESI] = "esi",
[R_EDI] = "edi",
[R_EBP] = "ebp",
[R_ESP] = "esp",
#endif
};
int i;
for (i = 0; i < CPU_NB_REGS; ++i) {
fprintf(stderr, "%s = %lx\n", reg_names[i], persistent_saved_gpr[i]);
}
}
static void log_x86_sp_content(void) {
fprintf(stderr, ">> SP = %lx -> %lx\n", persistent_saved_gpr[R_ESP],
*(unsigned long*)persistent_saved_gpr[R_ESP]);
}*/
#define I386_RESTORE_STATE_FOR_PERSISTENT \ #define I386_RESTORE_STATE_FOR_PERSISTENT \
do { \ do { \
\ \
@ -154,7 +202,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
for (i = 0; i < CPU_NB_REGS; ++i) { \ for (i = 0; i < CPU_NB_REGS; ++i) { \
\ \
gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \ gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \
tcg_gen_ld_tl(gpr_sv, cpu_regs[i], 0); \ tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); \
\ \
} \ } \
\ \
@ -172,8 +220,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
gen_set_label(lbl_finish_restore_gpr); \ gen_set_label(lbl_finish_restore_gpr); \
tcg_temp_free(first_pass); \ tcg_temp_free(first_pass); \
\ \
} \ } else if (afl_persistent_ret_addr == 0) { \
if (afl_persistent_ret_addr == 0) { \
\ \
TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); \ TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); \
TCGv stack_off = tcg_temp_new(); \ TCGv stack_off = tcg_temp_new(); \
@ -191,6 +238,8 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
if (s->pc == afl_persistent_addr) { \ if (s->pc == afl_persistent_addr) { \
\ \
I386_RESTORE_STATE_FOR_PERSISTENT; \ I386_RESTORE_STATE_FOR_PERSISTENT; \
/*tcg_gen_afl_call0(log_x86_saved_gpr); \
tcg_gen_afl_call0(log_x86_sp_content);*/ \
\ \
if (afl_persistent_ret_addr == 0) { \ if (afl_persistent_ret_addr == 0) { \
\ \
@ -199,6 +248,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
\ \
} \ } \
tcg_gen_afl_call0(&afl_persistent_loop); \ tcg_gen_afl_call0(&afl_persistent_loop); \
/*tcg_gen_afl_call0(log_x86_sp_content);*/ \
\ \
} else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \
\ \

View File

@ -35,7 +35,7 @@ void bind_to_free_cpu(void) {
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)
cpu_set_t c; cpu_set_t c;
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
cpuset_t *c; cpuset_t* c;
#endif #endif
u8 cpu_used[4096] = {0}; u8 cpu_used[4096] = {0};
@ -147,8 +147,10 @@ void bind_to_free_cpu(void) {
struct kinfo_proc2* procs; struct kinfo_proc2* procs;
size_t nprocs; size_t nprocs;
size_t proccount; size_t proccount;
int s_name[] = {CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0}; int s_name[] = {
size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]);
CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), 0};
size_t s_name_l = sizeof(s_name) / sizeof(s_name[0]);
if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return; if (sysctl(s_name, s_name_l, NULL, &nprocs, NULL, 0) != 0) return;
proccount = nprocs / sizeof(struct kinfo_proc2); proccount = nprocs / sizeof(struct kinfo_proc2);