/* Copyright (C) 2017 Sergej Schumilo This file is part of QEMU-PT (kAFL). QEMU-PT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. QEMU-PT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QEMU-PT. If not, see . */ #pragma once #include "qemu/osdep.h" #include "nyx/khash.h" #include "nyx/page_cache.h" #include "nyx/redqueen_trace.h" #include #include #include #include #include #include #include #include // #define RQ_DEBUG #define REDQUEEN_MAX_STRCMP_LEN 64 #define REDQUEEN_TRAP_LIMIT 16 #define REG64_NUM 16 #define REG32_NUM 16 // seems we don't want to include rip, since this index is used to acces the qemu cpu structure or something? #define REG16_NUM 16 #define REG8L_NUM 16 #define REG8H_NUM 8 #define EXTRA_REG_RIP 16 #define EXTRA_REG_NOP 17 #define REDQUEEN_NO_INSTRUMENTATION 0 #define REDQUEEN_LIGHT_INSTRUMENTATION 1 #define REDQUEEN_SE_INSTRUMENTATION 2 #define REDQUEEN_WHITELIST_INSTRUMENTATION 3 enum reg_types { RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15 }; #define CMP_BITMAP_NOP 0x0000000UL #define CMP_BITMAP_RQ_INSTRUCTION 0x1000000UL #define CMP_BITMAP_SE_INSTRUCTION 0x2000000UL #define CMP_BITMAP_BLACKLISTED 0x4000000UL #define CMP_BITMAP_TRACE_ENABLED 0x8000000UL #define CMP_BITMAP_SHOULD_HOOK_SE \ (CMP_BITMAP_SE_INSTRUCTION | CMP_BITMAP_TRACE_ENABLED) #define CMP_BITMAP_SHOULD_HOOK_RQ (CMP_BITMAP_RQ_INSTRUCTION) KHASH_MAP_INIT_INT64(RQ, uint32_t) typedef struct redqueen_s { khash_t(RQ) * lookup; bool intercept_mode; bool singlestep_enabled; int hooks_applied; CPUState *cpu; uint64_t last_rip; uint64_t next_rip; uint64_t *breakpoint_whitelist; uint64_t num_breakpoint_whitelist; redqueen_trace_t *trace_state; page_cache_t *page_cache; } redqueen_t; typedef struct redqueen_workdir_s { char *redqueen_results; char *symbolic_results; char *pt_trace_results; char *redqueen_patches; char *breakpoint_white; char *breakpoint_black; char *target_code_dump; } redqueen_workdir_t; extern redqueen_workdir_t redqueen_workdir; void setup_redqueen_workdir(char *workdir); redqueen_t *new_rq_state(CPUState *cpu, page_cache_t *page_cache); void destroy_rq_state(redqueen_t *self); void set_rq_instruction(redqueen_t *self, uint64_t addr); void set_rq_blacklist(redqueen_t *self, uint64_t addr); void handle_hook(redqueen_t *self); void handel_se_hook(redqueen_t *self); void enable_rq_intercept_mode(redqueen_t *self); void disable_rq_intercept_mode(redqueen_t *self); void set_se_instruction(redqueen_t *self, uint64_t addr); void dump_se_registers(redqueen_t *self); void dump_se_memory_access(redqueen_t *self, cs_insn *insn); void dump_se_return_access(redqueen_t *self, cs_insn *insn); void dump_se_memory_access_at(redqueen_t *self, uint64_t instr_addr, uint64_t mem_addr); void redqueen_insert_hooks(redqueen_t *self); void redqueen_remove_hooks(redqueen_t *self); void redqueen_callback(void *opaque, disassembler_mode_t mode, uint64_t start_addr, uint64_t end_addr);