diff --git a/Makefile.objs b/Makefile.objs index 865ae96..d8a6254 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -431,9 +431,11 @@ QEMU_CFLAGS+=$(GLIB_CFLAGS) QEMU_CPPFLAGS+=$(QEMU_CFLAGS) #LOK: moved the callback interface into the shared directory libdecaf-y=DECAF_callback.o DECAF_main.o DECAF_cmds.o -libdecaf-y+=procmod.o read_linux.o hookapi.o windows_vmi.o vmi.o linux_vmi.o +libdecaf-y+=procmod.o hookapi.o windows_vmi.o vmi.o +#Kevin: read_linux.o is removed, also add some read ELF stuff heres -- 10/23/2013 +libdecaf-y+=linux_procinfo.o linux_readelf.o linux_vmi.o libdecaf-y+=function_map.o -libdecaf-y+=tainting/reduce_taint.o tainting/taintcheck_opt.o tainting/tainting.o +libdecaf-y+=tainting/reduce_taint.o tainting/taintcheck_opt.o tainting/tainting.o libdecaf-y+=tainting/taint_memory.o tainting/tcg_taint.o tainting/analysis_log.o #libdecaf-y+=sqlite3/sqlite3.o libdecaf-y+=DECAF_vm_compress.o diff --git a/Makefile.target b/Makefile.target index f499c8c..dfa63fd 100644 --- a/Makefile.target +++ b/Makefile.target @@ -213,7 +213,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-y += memory.o -LIBS+=-lz +LIBS+=-lz -lrt QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) diff --git a/configure b/configure index a8f4e78..fc2bfec 100755 --- a/configure +++ b/configure @@ -112,6 +112,8 @@ target_list="" enable_vmi="yes" #AWH - TCG tainting off by default tcg_taint="no" +#AWH - TCG IR logging off by default +tcg_ir_log="no" bluez="" brlapi="" curl="" @@ -482,8 +484,7 @@ Haiku) linux="yes" linux_user="yes" usb="linux" - # AWH - No KVM support - #kvm="yes" + kvm="yes" vhost_net="yes" if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then audio_possible_drivers="$audio_possible_drivers fmod" @@ -673,7 +674,7 @@ for opt do ;; --disable-kvm) kvm="no" ;; - --enable-kvm) kvm="no" # AWH - No KVM support + --enable-kvm) kvm="yes" ;; --disable-tcg-interpreter) tcg_interpreter="no" ;; @@ -805,6 +806,11 @@ for opt do ;; --disable-tcg-taint) tcg_taint="no" ;; + # AWH - TCG IR logging + --enable-tcg-ir-log) tcg_ir_log="yes" + ;; + --disable-tcg-ir-log) tcg_ir_log="no" + ;; # AWH - VMI support --enable-vmi) enable_vmi="yes" ;; @@ -898,6 +904,7 @@ default_target_list="" if [ "$softmmu" = "yes" ] ; then default_target_list="\ i386-softmmu \ +arm-softmmu \ " fi #x86_64-softmmu \ @@ -1105,6 +1112,9 @@ echo " --enable-guest-agent enable building of the QEMU Guest Agent" # AWH - TCG tainting echo " --disable-tcg-taint disable taint IR generation via TCG (default)" echo " --enable-tcg-taint enable taint IR generation via TCG" +# AWH - TCG IR logging +echo " --disable-tcg-ir-log disable TCG IR logging buffers (default)" +echo " --enable-tcg-ir-log enable TCG IR logging buffers" # AWH - VMI enable echo " --disable-vmi disable VMI support" echo " --enable-vmi enable VMI support (default)" @@ -2907,6 +2917,8 @@ echo "libiscsi support $libiscsi" echo "build guest agent $guest_agent" # AWH - TCG tainting echo "enable TCG taint $tcg_taint" +# AWH - TCG IR logging +echo "enable IR logging $tcg_ir_log" # AWH - VMI echo "enable VMI $enable_vmi" @@ -2960,7 +2972,10 @@ fi if test "$tcg_taint" = "yes" ; then echo "CONFIG_TCG_TAINT=y" >> $config_host_mak fi - +#AWH - TCG IR logging +if test "$tcg_ir_log" = "yes" ; then + echo "CONFIG_TCG_IR_LOG=y" >> $config_host_mak +fi echo "ARCH=$ARCH" >> $config_host_mak if test "$debug_tcg" = "yes" ; then echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak @@ -3606,24 +3621,23 @@ case "$target_arch2" in *) echo "CONFIG_NO_XEN=y" >> $config_target_mak esac -#AWH - Disable KVM support -#case "$target_arch2" in -# i386|x86_64|ppcemb|ppc|ppc64|s390x) -# # Make sure the target and host cpus are compatible -# if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \ -# \( "$target_arch2" = "$cpu" -o \ -# \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc" \) -o \ -# \( "$target_arch2" = "ppc64" -a "$cpu" = "ppc" \) -o \ -# \( "$target_arch2" = "ppc" -a "$cpu" = "ppc64" \) -o \ -# \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc64" \) -o \ -# \( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \ -# \( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then -# echo "CONFIG_KVM=y" >> $config_target_mak -# if test "$vhost_net" = "yes" ; then -# echo "CONFIG_VHOST_NET=y" >> $config_target_mak -# fi -# fi -#esac +case "$target_arch2" in + i386|x86_64|ppcemb|ppc|ppc64|s390x) + # Make sure the target and host cpus are compatible + if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \ + \( "$target_arch2" = "$cpu" -o \ + \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc" \) -o \ + \( "$target_arch2" = "ppc64" -a "$cpu" = "ppc" \) -o \ + \( "$target_arch2" = "ppc" -a "$cpu" = "ppc64" \) -o \ + \( "$target_arch2" = "ppcemb" -a "$cpu" = "ppc64" \) -o \ + \( "$target_arch2" = "x86_64" -a "$cpu" = "i386" \) -o \ + \( "$target_arch2" = "i386" -a "$cpu" = "x86_64" \) \) ; then + echo "CONFIG_KVM=y" >> $config_target_mak + if test "$vhost_net" = "yes" ; then + echo "CONFIG_VHOST_NET=y" >> $config_target_mak + fi + fi +esac if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then echo "CONFIG_PSERIES=y" >> $config_target_mak fi diff --git a/cpu-defs.h b/cpu-defs.h index 9c53830..9469c3e 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -154,7 +154,8 @@ typedef struct CPUWatchpoint { } CPUWatchpoint; #ifdef CONFIG_TCG_TAINT -#define CPU_TEMP_BUF_NLONGS 256 +#define CPU_TEMP_BUF_NLONGS 1024 +// AWH - Was 256 #else #define CPU_TEMP_BUF_NLONGS 128 #endif /* CONFIG_TCG_TAINT */ diff --git a/cpus.c b/cpus.c index 82530c4..caa2ee0 100644 --- a/cpus.c +++ b/cpus.c @@ -932,6 +932,8 @@ static void qemu_kvm_start_vcpu(CPUState *env) } } +extern int DECAF_kvm_enabled; + void qemu_init_vcpu(void *_env) { CPUState *env = _env; @@ -939,7 +941,7 @@ void qemu_init_vcpu(void *_env) env->nr_cores = smp_cores; env->nr_threads = smp_threads; env->stopped = 1; - if (kvm_enabled()) { + if (kvm_enabled() && DECAF_kvm_enabled) { // Added by Heng Yin qemu_kvm_start_vcpu(env); } else { qemu_tcg_init_vcpu(env); diff --git a/exec-all.h b/exec-all.h index c03212b..7e0cf76 100644 --- a/exec-all.h +++ b/exec-all.h @@ -21,6 +21,9 @@ #define _EXEC_ALL_H_ #include "qemu-common.h" +#ifdef CONFIG_TCG_IR_LOG +#include "tcg-target.h" /* AWH - For TCG_TARGET_REG_BITS */ +#endif /* CONFIG_TCG_IR_LOG */ /* allow to see translation results - the slowdown should be negligible, so we leave it */ #define DEBUG_DISAS @@ -48,7 +51,7 @@ typedef struct TranslationBlock TranslationBlock; #else #define MAX_OPC_PARAM_PER_ARG 1 #endif -#ifdef CONFIG_TCG_TAINT +#if 0 //def CONFIG_TCG_TAINT /* AWH - We can have a whole bunch of input args to a CALL that logs taint information (reg numbers and concrete values). */ #define MAX_OPC_PARAM_IARGS 10 @@ -62,6 +65,7 @@ typedef struct TranslationBlock TranslationBlock; * and up to 4 + N parameters on 64-bit archs * (N = number of input arguments + output arguments). */ #define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS)) + #ifdef CONFIG_TCG_TAINT /* AWH - We need to increase the size of the opcode buffer to be big enough to hold all of our added taint IR and logging CALL ops. But, @@ -96,14 +100,19 @@ typedef struct TranslationBlock TranslationBlock; <- OPC_MAX_SIZE: 432 -><- MAX_OP_PER_INSTR: 5968 -> */ #define OPC_BUF_SIZE 6400 -#define MAX_OP_PER_INSTR (OPC_BUF_SIZE - 640 + 208) #else /* XXX: make safe guess about sizes */ -#define MAX_OP_PER_INSTR 208 #define OPC_BUF_SIZE 640 #endif /* CONFIG_TCG_TAINT */ +#define MAX_OP_PER_INSTR (OPC_BUF_SIZE - 208) +/* AWH - We want to reduce the number of IR ops that are generated in + a single TB to reduce the number of IRs that we have to store if we + are storing the IRs for a plugin to examine later. */ +#ifdef CONFIG_TCG_IR_LOG +#define OPC_MAX_SIZE 200 +#else #define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) - +#endif /* CONFIG_TCG_IR_LOG */ /* Maximum size a TCG op can expand to. This is complicated because a single op may require several host instructions and register reloads. For now take a wild guess at 192 bytes, which should allow at least @@ -201,6 +210,18 @@ struct TranslationBlock { struct TranslationBlock *jmp_next[2]; struct TranslationBlock *jmp_first; uint32_t icount; +#ifdef CONFIG_TCG_IR_LOG + uint8_t DECAF_logged; /* AWH - Has this been logged to disk? */ + uint16_t *DECAF_gen_opc_buf; /* AWH - IR ops in this TB */ +#if TCG_TARGET_REG_BITS == 32 + uint32_t *DECAF_gen_opparam_buf; /* AWH - IR parms in this TB */ +#else + uint64_t *DECAF_gen_opparam_buf; /* AWH - IR parms in this TB */ +#endif /* TCG_TARGET_REG_BITS */ + uint32_t DECAF_num_opc; + uint32_t DECAF_num_opparam; + unsigned long DECAF_tb_id; /* AWH - offset of this in "tbs" (exec.c) */ +#endif /* CONFIG_TCG_IR_LOG */ }; static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) diff --git a/exec.c b/exec.c index 038c8cd..ace8423 100644 --- a/exec.c +++ b/exec.c @@ -24,12 +24,6 @@ #include #endif -//#include "test_tlb_cb.h" - -#ifdef CONFIG_VMI_ENABLE -#include "shared/DECAF_callback_to_QEMU.h" -#endif - #include "qemu-common.h" #include "cpu.h" #include "tcg.h" @@ -64,6 +58,7 @@ #endif #include "DECAF_main.h" +#include "shared/DECAF_callback_to_QEMU.h" //#define DEBUG_TB_INVALIDATE //#define DEBUG_FLUSH @@ -84,6 +79,14 @@ #define SMC_BITMAP_USE_THRESHOLD 10 +#ifdef CONFIG_TCG_IR_LOG +static uint16_t *gDECAF_gen_opc_buf; +#if TCG_TARGET_REG_BITS == 32 +uint32_t *gDECAF_gen_opparam_buf; +#else +uint64_t *gDECAF_gen_opparam_buf; +#endif /* TCG_TARGET_REG_BITS */ +#endif /* CONFIG_TCG_IR_LOG */ static TranslationBlock *tbs; static int code_gen_max_blocks; TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; @@ -475,6 +478,9 @@ static void code_gen_alloc(unsigned long tb_size) map_exec(code_gen_buffer, code_gen_buffer_size); #else code_gen_buffer_size = tb_size; +#ifdef CONFIG_TCG_IR_LOG + unsigned long i; +#endif /* CONFIG_TCG_IR_LOG */ if (code_gen_buffer_size == 0) { #if defined(CONFIG_USER_ONLY) code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE; @@ -565,8 +571,32 @@ static void code_gen_alloc(unsigned long tb_size) map_exec(code_gen_prologue, sizeof(code_gen_prologue)); code_gen_buffer_max_size = code_gen_buffer_size - (TCG_MAX_OP_SIZE * OPC_BUF_SIZE); +#if (defined(CONFIG_TCG_IR_LOG) && (TCG_TARGET_REG_BITS == 32)) +/* AWH - For people running DECAF on a 32-bit machine, the IR storage + will require too much RAM. So, for 32-bit systems, we make the number + of code blocks much smaller. */ + code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE / 16; +#else code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE; +#endif /* CONFIG_TCG_IR_LOG && (TCG_TARGET_REG_BITS == 32) */ tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock)); +#ifdef CONFIG_TCG_IR_LOG +fprintf(stderr, "AWH: code_gen_alloc(): code_gen_max_blocks: %d\n", code_gen_max_blocks); +fprintf(stderr, "AWH: code_gen_alloc(): gDECAF_gen_opc_buf: %d\n", OPC_MAX_SIZE * sizeof(uint16_t) * code_gen_max_blocks); + gDECAF_gen_opc_buf = g_malloc(OPC_MAX_SIZE * sizeof(uint16_t) * code_gen_max_blocks); +fprintf(stderr, "AWH: code_gen_alloc(): gDECAF_gen_opparam_buf: %d\n", OPC_MAX_SIZE * sizeof(uint16_t) * 6 * code_gen_max_blocks); + gDECAF_gen_opparam_buf = g_malloc(OPC_MAX_SIZE * sizeof(TCGArg) * 6 * code_gen_max_blocks); + + for (i = 0; i < code_gen_max_blocks; i++) { + tbs[i].DECAF_tb_id = i; + tbs[i].DECAF_gen_opc_buf = + gDECAF_gen_opc_buf + (OPC_MAX_SIZE * i); + /* Allocate 6 arguments per IR opcode */ + tbs[i].DECAF_gen_opparam_buf = + gDECAF_gen_opparam_buf + (OPC_MAX_SIZE * 6 * i); + //printf("Allocating block %d of %d\n", i+1, code_gen_max_blocks); + } +#endif /* CONFIG_TCG_IR_LOG */ } /* Must be called before using the QEMU cpus. 'tb_size' is the size @@ -684,6 +714,11 @@ static TranslationBlock *tb_alloc(target_ulong pc) tb = &tbs[nb_tbs++]; tb->pc = pc; tb->cflags = 0; +#ifdef CONFIG_TCG_IR_LOG + tb->DECAF_logged = 0; /* AWH - Has this been logged to disk? */ + tb->DECAF_num_opc = 0; + tb->DECAF_num_opparam = 0; +#endif /* CONFIG_TCG_IR_LOG */ return tb; } @@ -695,6 +730,9 @@ void tb_free(TranslationBlock *tb) if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) { code_gen_ptr = tb->tc_ptr; nb_tbs--; +#ifdef CONFIG_TCG_IR_LOG + tb->DECAF_logged = 0; +#endif /* CONFIG_TCG_TAINT */ } } @@ -2336,8 +2374,7 @@ void tlb_set_page(CPUState *env, target_ulong vaddr, #ifdef CONFIG_VMI_ENABLE if (DECAF_is_callback_needed(DECAF_TLB_EXEC_CB)) DECAF_invoke_tlb_exec_callback(env, vaddr); -#endif - +#endif /* CONFIG_VMI_ENABLE */ } else { te->addr_code = -1; } diff --git a/kvm-all.c b/kvm-all.c index 4c466d6..b2f0010 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -35,7 +35,6 @@ /* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */ #define PAGE_SIZE TARGET_PAGE_SIZE - //#define DEBUG_KVM #ifdef DEBUG_KVM diff --git a/qemu-options.hx b/qemu-options.hx index 3137632..51519f1 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2297,6 +2297,16 @@ STEXI Start right away with a saved state (@code{loadvm} in monitor) ETEXI +DEF("toggle-kvm", HAS_ARG, QEMU_OPTION_toggle_kvm, \ + "-toggle-kvm [0|1]\n" \ + " toggle KVM on or off at runtime\n", \ + QEMU_ARCH_ALL) +STEXI +@item -toggle-kvm @var{file} +@findex -toggle-kvm +Toggle KVM on or off at runtime. +ETEXI + DEF("after_loadvm", HAS_ARG, QEMU_OPTION_after_loadvm, \ "-after_loadvm [???]\n" \ " NO DESCRIPTION\n", \ @@ -2307,13 +2317,13 @@ STEXI NO DESCRIPTION ETEXI -DEF("load_plugin", HAS_ARG, QEMU_OPTION_load_plugin, \ - "-after_loadvm [path to plugin]\n" \ +DEF("load-plugin", HAS_ARG, QEMU_OPTION_load_plugin, \ + "-load-plugin [path to plugin]\n" \ " load the specified plugin at startup\n", \ QEMU_ARCH_ALL) STEXI -@item -load_plugin @var{file} -@findex -load_plugin +@item -load-plugin @var{file} +@findex -load-plugin Load the specified plugin immediately upon startup of QEMU. ETEXI diff --git a/shared/DECAF_callback.c b/shared/DECAF_callback.c index 57eb517..725b890 100644 --- a/shared/DECAF_callback.c +++ b/shared/DECAF_callback.c @@ -244,7 +244,6 @@ int DECAF_is_BlockEndCallback_needed(gva_t from, gva_t to) return (CountingHashmap_exist(pOBEPageMap, from, to)); } - DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( DECAF_callback_func_t cb_func, int *cb_cond, @@ -332,6 +331,93 @@ DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( return ((DECAF_Handle)cb_struct); } +//Aravind - Serialized callbacks. 000 to 1ff, 1xx == 0fxx (for two byte opcodes) +static callback_struct_t* instructionCallbacks[0x200] = {0}; + +//Aravind - Function to register cb handlers for instruction ranges +DECAF_Handle DECAF_registerOpcodeRangeCallbacks ( + DECAF_callback_func_t handler, + OpcodeRangeCallbackConditions *condition, + uint16_t start_opcode, + uint16_t end_opcode) +{ + int i; + + if(end_opcode < start_opcode) { + fprintf(stderr, "end_opcode can't be less than start_opcode.\n"); + return DECAF_NULL_HANDLE; + } + + callback_struct_t * cb_struct = (callback_struct_t *)malloc(sizeof(callback_struct_t)); + if (cb_struct == NULL) + { + return (DECAF_NULL_HANDLE); + } + + if(start_opcode >= 0x0f00) { + start_opcode = 0x100 | (start_opcode & 0xff); + } + + if(end_opcode >= 0x0f00) { + end_opcode = 0x100 | (end_opcode & 0xff); + } + + cb_struct->callback = handler; + cb_struct->from = start_opcode; + cb_struct->to = end_opcode; + cb_struct->enabled = condition; + + for(i = start_opcode; i <= end_opcode; i++) { + instructionCallbacks[i] = cb_struct; + } + + LIST_INSERT_HEAD(&callback_list_heads[DECAF_OPCODE_RANGE_CB], cb_struct, link); + + //Flush the tb + tb_flush(cpu_single_env); + + return (DECAF_Handle)cb_struct; +} + +//Function to unregister opcode range callbacks +DECAF_errno_t DECAF_unregisterOpcodeRangeCallbacks(DECAF_Handle handle) +{ + callback_struct_t *cb_struct; + + int i; + + LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_OPCODE_RANGE_CB], link) { + + if((DECAF_Handle)cb_struct != handle) + continue; + + //Sanity check + if(cb_struct->from > 0x1ff || + cb_struct->to > 0x1ff || + cb_struct->from > cb_struct->to) + goto invalid_handle; + + for(i = cb_struct->from; i <= cb_struct->to; i++) { + instructionCallbacks[i] = NULL; + } + + LIST_REMOVE(cb_struct, link); + + free(cb_struct); + + tb_flush(cpu_single_env); + + return 0; + } + +invalid_handle: + return -1; +} + +//end - Aravind + + + DECAF_Handle DECAF_registerOptimizedBlockEndCallback( DECAF_callback_func_t cb_func, int *cb_cond, @@ -629,7 +715,6 @@ int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle return -1; } -#ifdef CONFIG_VMI_ENABLE void DECAF_invoke_tlb_exec_callback(CPUState *env, gva_t vaddr) { callback_struct_t *cb_struct; @@ -646,7 +731,62 @@ void DECAF_invoke_tlb_exec_callback(CPUState *env, gva_t vaddr) } } } -#endif + +void helper_DECAF_invoke_opcode_range_callback( + CPUState *env, + target_ulong eip, + target_ulong next_eip, + uint32_t op) +{ + callback_struct_t *cb_struct = instructionCallbacks[op]; + if(cb_struct == NULL || env == NULL) + return; + + //OpcodeRangeCallbackConditions *cond = (OpcodeRangeCallbackConditions *)(cb_struct->enabled); + OpcodeRangeCallbackConditions temp; + + //FIXME: Being naive and assuming that kernel starts from 0x80000000. + //Correct way to do this would be to expose an interface from vmi to indicate the kernel base. + uint32_t kernel_base = 0x80000000; + int from_user, from_kernel, to_user, to_kernel; + from_user = from_kernel = to_user = to_kernel = 0; + + if(*(cb_struct->enabled) != DECAF_ALL) { + if(eip > kernel_base) { + from_kernel = 1; + } else { + from_user = 1; + } + + if(next_eip > kernel_base) { + to_kernel = 1; + } else { + to_user = 1; + } + + if(from_user & to_user) { + temp = DECAF_USER_TO_USER_ONLY; + } else if(from_user & to_kernel) { + temp = DECAF_USER_TO_KERNEL_ONLY; + } else if(from_kernel & to_user) { + temp = DECAF_KERNEL_TO_USER_ONLY; + } else { + temp = DECAF_KERNEL_TO_KERNEL_ONLY; + } + + //Condition violated + if(temp & *(cb_struct->enabled) == 0) + return; + } + + DECAF_Callback_Params params; + params.op.env = env; + params.op.eip = eip; + params.op.next_eip = next_eip; + params.op.op = op; + + cb_struct->callback(¶ms); +} void helper_DECAF_invoke_block_begin_callback(CPUState* env, TranslationBlock* tb) { @@ -717,6 +857,8 @@ PUSH_ALL() params.be.next_pc = env->eip + env->segs[R_CS].base; #elif defined(TARGET_ARM) params.be.next_pc = env->regs[15]; +#elif defined(TARGET_MIPS) + params.be.next_pc = env->active_tc.PC; #else fix this error #endif @@ -814,13 +956,17 @@ void helper_DECAF_invoke_mem_read_callback(gva_t virt_addr,gpa_t phy_addr,DATA_T } } } -void helper_DECAF_invoke_eip_check_callback(gva_t eip) +void helper_DECAF_invoke_eip_check_callback(uint32_t eip, uint32_t eip_taint) { callback_struct_t *cb_struct; DECAF_Callback_Params params; + PUSH_ALL() //AWH params.ec.eip = eip; + params.ec.eip_taint = eip_taint; //if (cpu_single_env == 0) return; + if(!DECAF_is_callback_needed(DECAF_EIP_CHECK_CB)) + goto out; //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_EIP_CHECK_CB], link) { @@ -831,7 +977,8 @@ void helper_DECAF_invoke_eip_check_callback(gva_t eip) cb_struct->callback(¶ms); } } - +out: + POP_ALL() // AWH } void helper_DECAF_invoke_keystroke_callback(int keycode,uint32_t *taint_mark) @@ -905,7 +1052,7 @@ void helper_DECAF_invoke_nic_send_callback(uint32_t addr,int size,uint8_t *buf) params.ns.addr=addr; params.ns.size=size; params.ns.buf=buf; - +PUSH_ALL() // AWH //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_NIC_SEND_CB], link) { @@ -915,6 +1062,7 @@ void helper_DECAF_invoke_nic_send_callback(uint32_t addr,int size,uint8_t *buf) if (!cb_struct->enabled || *cb_struct->enabled) cb_struct->callback(¶ms); } +POP_ALL() // AWH } void helper_DECAF_invoke_read_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,uint8_t *taint_info) diff --git a/shared/DECAF_callback.h b/shared/DECAF_callback.h index 2d9a471..13111b1 100644 --- a/shared/DECAF_callback.h +++ b/shared/DECAF_callback.h @@ -49,6 +49,12 @@ extern DECAF_Handle DECAF_register_callback( extern int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle); +DECAF_Handle DECAF_registerOpcodeRangeCallbacks ( + DECAF_callback_func_t handler, + OpcodeRangeCallbackConditions *condition, + uint16_t start_opcode, + uint16_t end_opcode); + DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( DECAF_callback_func_t cb_func, int *cb_cond, diff --git a/shared/DECAF_callback_common.h b/shared/DECAF_callback_common.h index 31cb783..54e60fd 100644 --- a/shared/DECAF_callback_common.h +++ b/shared/DECAF_callback_common.h @@ -29,7 +29,17 @@ extern "C" #include "cpu.h" #include "shared/DECAF_types.h" -//#include "test_tlb_cb.h" +/* + * Condition flags for range callbacks. Transitions are only valid for instructions that branch. + * For all other instructions only 0x00, 0x01, 0x08 are valid. + */ +typedef enum { + DECAF_ALL = 0x00, + DECAF_USER_TO_USER_ONLY = 0x01, + DECAF_USER_TO_KERNEL_ONLY = 0x02, + DECAF_KERNEL_TO_USER_ONLY = 0x04, + DECAF_KERNEL_TO_KERNEL_ONLY = 0x08, +} OpcodeRangeCallbackConditions; typedef enum { DECAF_BLOCK_BEGIN_CB = 0, @@ -42,9 +52,8 @@ typedef enum { DECAF_KEYSTROKE_CB,//keystroke event DECAF_NIC_REC_CB, DECAF_NIC_SEND_CB, -#ifdef CONFIG_VMI_ENABLE + DECAF_OPCODE_RANGE_CB, DECAF_TLB_EXEC_CB, -#endif DECAF_READ_TAINTMEM_CB, DECAF_WRITE_TAINTMEM_CB, DECAF_LAST_CB, //place holder for the last position, no other uses. @@ -89,13 +98,19 @@ typedef struct _DECAF_Block_Begin_Params TranslationBlock* tb; }DECAF_Block_Begin_Params; -#ifdef CONFIG_VMI_ENABLE typedef struct _DECAF_Tlb_Exec_Params { CPUState *env; gva_t vaddr; //Address loaded to tlb exec cache } DECAF_Tlb_Exec_Params; -#endif + +typedef struct _DECAF_Opcode_Range_Params +{ + CPUState *env; + gva_t eip; + gva_t next_eip; + uint16_t op; +} DECAF_Opcode_Range_Params; typedef struct _DECAF_Block_End_Params { @@ -130,7 +145,8 @@ typedef struct _DECAF_Mem_Write_Params }DECAF_Mem_Write_Params; typedef struct _DECAF_EIP_Check_Params { - gva_t eip; + uint32_t eip; + uint32_t eip_taint; }DECAF_EIP_Check_Params; typedef struct _DECAF_Keystroke_Params { @@ -187,9 +203,8 @@ typedef struct _DECAF_Callback_Params DECAF_Keystroke_Params ks; DECAF_Nic_Rec_Params nr; DECAF_Nic_Send_Params ns; -#ifdef CONFIG_VMI_ENABLE + DECAF_Opcode_Range_Params op; DECAF_Tlb_Exec_Params tx; -#endif DECAF_Read_Taint_Mem rt; DECAF_Write_Taint_Mem wt; }; diff --git a/shared/DECAF_cmds.c b/shared/DECAF_cmds.c index a292937..b6f809a 100644 --- a/shared/DECAF_cmds.c +++ b/shared/DECAF_cmds.c @@ -16,6 +16,7 @@ If you have any questions about DECAF,please post it on #include "DECAF_cmds.h" #include "procmod.h" +#if 0 void do_linux_ps(Monitor *mon, const QDict* qdict) { if (qdict_haskey(qdict, "mmap_flag")) @@ -23,6 +24,7 @@ void do_linux_ps(Monitor *mon, const QDict* qdict) else linux_ps(mon, 1); } +#endif void do_guest_ps(Monitor *mon) { @@ -46,3 +48,21 @@ void do_guest_modules(Monitor *mon, const QDict *qdict) } list_guest_modules(mon, pid); } + +extern int DECAF_kvm_enabled; + +void do_toggle_kvm(Monitor *mon, const QDict *qdict) +{ + int status = qdict_get_bool(qdict, "status"); + if(DECAF_kvm_enabled == status) { + monitor_printf(default_mon, "KVM has already been turned %s!\n", status? "on": "off"); + return; + } + + DECAF_stop_vm(); + DECAF_kvm_enabled = status; + DECAF_start_vm(); + monitor_printf(default_mon, "KVM is now turned %s!\n", status? "on": "off"); + +} + diff --git a/shared/DECAF_cmds.h b/shared/DECAF_cmds.h index c73b18e..e20dd72 100644 --- a/shared/DECAF_cmds.h +++ b/shared/DECAF_cmds.h @@ -31,9 +31,11 @@ extern "C" { #endif -void do_linux_ps(Monitor *mon, const QDict* qdict); +//void do_linux_ps(Monitor *mon, const QDict* qdict); void do_guest_ps(Monitor *mon); void do_guest_modules(Monitor *mon, const QDict *qdict); +void do_toggle_kvm(Monitor *mon, const QDict *qdict); + #ifdef __cplusplus } diff --git a/shared/DECAF_main.c b/shared/DECAF_main.c index 5a2ae9a..a4f9221 100644 --- a/shared/DECAF_main.c +++ b/shared/DECAF_main.c @@ -41,6 +41,8 @@ #include "shared/vmi_include.h" #endif +int DECAF_kvm_enabled = 0; + plugin_interface_t *decaf_plugin = NULL; static void *plugin_handle = NULL; static char decaf_plugin_path[PATH_MAX] = ""; @@ -335,7 +337,7 @@ int do_unload_plugin(Monitor *mon, const QDict *qdict, QObject **ret_data) { hookapi_flush_hooks(decaf_plugin_path); #ifdef TARGET_I386 //Currently opcode-based callback mechanism is only available in x86. - DECAF_cleanup_insn_cbs(); + //DECAF_cleanup_insn_cbs(); #endif //LOK: Created a new callback interface for procmod // loadmainmodule_notify = createproc_notify = removeproc_notify = loadmodule_notify = NULL; @@ -392,7 +394,7 @@ void DECAF_loadvm(void *opaque) { } } -static FILE *guestlog = NULL; +FILE *guestlog = NULL; static void DECAF_save(QEMUFile * f, void *opaque) { uint32_t len = strlen(decaf_plugin_path) + 1; @@ -484,7 +486,6 @@ static int DECAF_load(QEMUFile * f, void *opaque, int version_id) { extern void tainting_init(void); extern void function_map_init(void); extern void DECAF_callback_init(void); -extern void vmi_init(void); void DECAF_init(void) { DECAF_callback_init(); diff --git a/shared/DECAF_main.h b/shared/DECAF_main.h index 62dca4b..5f84300 100644 --- a/shared/DECAF_main.h +++ b/shared/DECAF_main.h @@ -36,6 +36,7 @@ extern "C" { #endif +extern int DECAF_kvm_enabled; /************************************************************************* * The Plugin interface comes first diff --git a/shared/DECAF_mon_cmds.h b/shared/DECAF_mon_cmds.h index a1c041b..36bf89f 100644 --- a/shared/DECAF_mon_cmds.h +++ b/shared/DECAF_mon_cmds.h @@ -46,6 +46,16 @@ If you have any questions about DECAF,please post it on .params = "pid", .help = "list the modules of the process with " }, + +{ + .name = "toggle_kvm", + .args_type = "status:b", + .mhandler.cmd = do_toggle_kvm, + .params = "on|off", + .help = "turn kvm on or off at runtime" +}, + +#if 0 //To be removed { .name = "linux_ps", .args_type = "mmap_flag:i?", @@ -53,6 +63,8 @@ If you have any questions about DECAF,please post it on .params = "[mmap_flag]", .help = "list the processes on linux guest system (default: mmap_flag = 1)" }, +#endif + #ifdef CONFIG_TCG_TAINT /* TCG tainting commands */ { diff --git a/shared/linux_vmi.cpp b/shared/linux_vmi.cpp index 7ea8ad4..3d52dbb 100644 --- a/shared/linux_vmi.cpp +++ b/shared/linux_vmi.cpp @@ -18,6 +18,8 @@ * * Created on: June 7, 2013 * Author: Heng Yin + * Updated on: August 29, 2013 + * by: Kevin Wang */ #include @@ -37,45 +39,39 @@ #include #include #include -#include "sqlite3/sqlite3.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "cpu.h" #include "config.h" #include "hw/hw.h" // AWH -#include "DECAF_main.h" -#include "DECAF_target.h" + #ifdef __cplusplus }; #endif /* __cplusplus */ #include "linux_vmi.h" +#include "linux_procinfo.h" #include "hookapi.h" -#include "read_linux.h" #include "function_map.h" #include "shared/procmod.h" #include "shared/vmi.h" #include "DECAF_main.h" +#include "DECAF_target.h" #include "shared/utils/SimpleCallback.h" +using namespace std; +using namespace std::tr1; + #ifdef CONFIG_VMI_ENABLE -#if 0 -GHashTable *cr3_hashtable = NULL; -GHashTable *eproc_ht = NULL; -process *system_proc = NULL; -process *new_proc = NULL; - -uint32_t gkpcr; -uint32_t GuestOS_index = 11; -uintptr_t block_handle = 0; -uint32_t system_cr3 = 0; -uint32_t file_sz; -uint32_t MAX = 500; +// current linux profile +static ProcInfo OFFSET_PROFILE = {"VMI"}; + +//static process *kernel_proc = NULL; + /* Timer to check for proc exits */ static QEMUTimer *recon_timer = NULL; -#endif static inline int is_page_resolved(process *proc, uint32_t page_num) { @@ -85,14 +81,19 @@ static inline int is_page_resolved(process *proc, uint32_t page_num) static void message_p(process* proc, int operation) { char proc_mod_msg[512] = { '\0' }; - if (operation) { - //monitor_printf(default_mon,"P + %d %d %08x %s\n", proc->pid, proc->parent_pid, proc->cr3, proc->name); + + switch (operation) { + case '+': snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P + %d %d %08x %s\n", - proc->pid, proc->parent_pid, proc->cr3, proc->name); - } else { - //monitor_printf(default_mon,"P - %d %d %08x %s\n", proc->pid, proc->parent_pid, proc->cr3, proc->name); + proc->pid, proc->parent_pid, proc->cr3, proc->name); + break; + case '-': snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P - %d %d %08x %s\n", - proc->pid, proc->parent_pid, proc->cr3, proc->name); + proc->pid, proc->parent_pid, proc->cr3, proc->name); + break; + case '^': + snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P ^ %d %d %08x %s\n", + proc->pid, proc->parent_pid, proc->cr3, proc->name); } handle_guest_message(proc_mod_msg); } @@ -113,83 +114,403 @@ static void message_m(uint32_t pid, uint32_t cr3, uint32_t base, module *pe) { //monitor_printf(default_mon,"%s\n", name); //monitor_printf(default_mon,"M %d %08x \"%s\" %08x %08x \"%s\"\n", pid, cr3, name, base, pe->size,pe->fullname); snprintf(proc_mod_msg, sizeof(proc_mod_msg), - "M %d %08x \"%s\" %08x %08x \"%s\"\n", pid, cr3, name, base, - pe->size, pe->fullname); + "M %d %08x \"%s\" %08x %08x \"%s\"\n", pid, cr3, name, base, + pe->size, pe->fullname); handle_guest_message(proc_mod_msg); } + static void message_p_d(dprocess* proc, int operation) { char proc_mod_msg[1024] = { '\0' }; - if (operation) { - //monitor_printf(default_mon,"P + %d %d %08x %s\n", proc->pid, proc->parent_pid, proc->cr3, proc->name); - sprintf(proc_mod_msg, "P + %d %d %08x %s\n", proc->pid, - proc->parent_pid, proc->cr3, proc->name); - } else { - //monitor_printf(default_mon,"P - %d %d %08x %s\n", proc->pid, proc->parent_pid, proc->cr3, proc->name); - sprintf(proc_mod_msg, "P - %d %d %08x %s\n", proc->pid, - proc->parent_pid, proc->cr3, proc->name); + + switch (operation) { + case '+': + snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P + %d %d %08x %s\n", + proc->pid, proc->parent_pid, proc->cr3, proc->name); + break; + case '-': + snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P - %d %d %08x %s\n", + proc->pid, proc->parent_pid, proc->cr3, proc->name); + break; + case '^': + snprintf(proc_mod_msg, sizeof(proc_mod_msg), "P ^ %d %d %08x %s\n", + proc->pid, proc->parent_pid, proc->cr3, proc->name); } handle_guest_message(proc_mod_msg); } +static int dump_modules(CPUState *env, uint32_t cr3, module * mod, target_ulong start_addr) { + char magicBytes[4]; + char filepath[64]; + + if (DECAF_read_mem_with_pgd(env, cr3, start_addr, sizeof(magicBytes), magicBytes) < 0) { + // memory is not ready yet + return 0; + } + // read first 4 bytes, verify the magic bytes of ELF header first + else if (!(magicBytes[0] == 0x7f && magicBytes[1] == 'E' && magicBytes[2] == 'L' && magicBytes[3] == 'F')) { + // not valid an ELF + return 0; + } + + sprintf(filepath, "/tmp/%s", mod->name); + FILE *fp = fopen(filepath, "w"); + if (fp == NULL) { + monitor_printf(default_mon, "File cannot be opened for writing \n"); + return 0; + } + + //DECAF_stop_vm(); // stop VM before dumping memory + const target_ulong READ_PAGE_SIZE = 4096; // how much to read every time? + for (target_ulong i=0, readSize=0; i < mod->size; i += READ_PAGE_SIZE) { + char mem_page[READ_PAGE_SIZE]; + readSize = mod->size - i; + if (readSize > READ_PAGE_SIZE) + readSize = READ_PAGE_SIZE; + if (DECAF_read_mem_with_pgd(env, cr3, start_addr+i, readSize, mem_page) < 0) { + fclose(fp); + //DECAF_start_vm(); + //monitor_printf(default_mon, "READ FAILED \n"); + return 0; + } + fwrite(mem_page, 1, readSize, fp); + } + fclose(fp); + //DECAF_start_vm(); + mod->symbols_extracted = true; // mark as extracted + monitor_printf(default_mon, "mod %s (start_addr = 0x%08x, end_addr = 0x%08x) is dumped \n", filepath, start_addr, (start_addr + mod->size)); + return 1; +} + +void extract_symbols_info(CPUState *env, uint32_t cr3, target_ulong start_addr, module * mod) { +} + +// get new module, basically reading from mm_struct +static void get_new_modules(CPUState* env, process * proc) +{ + + target_ulong ts_mm, mm_mmap, vma_file, vma_next, f_dentry; + const int MAX_LOOP_COUNT = 300; // prevent infinite loop + target_ulong vma_vm_start = 0, vma_vm_end = 0; + static target_ulong last_vm_start = 0, last_vm_end = 0; + char name[32], key[128]; // module file path + static std::string last_mod_name; + module* mod = NULL; + std::string _name; + + if (DECAF_read_mem(env, proc->EPROC_base_addr + OFFSET_PROFILE.ts_mm, sizeof(target_ptr), &ts_mm) < 0) + return; + + // read vma from mm first, then traverse mmap + if (DECAF_read_mem(env, ts_mm + OFFSET_PROFILE.mm_mmap, sizeof(target_ptr), &mm_mmap) < 0) + return; + + // starting from the first vm_area, read vm_file. NOTICE vm_area_struct can be null + if ((vma_next = mm_mmap) == 0) + return; + + // see if vm_area is populated already + if (populate_vm_area_struct_offsets(env, vma_next, &OFFSET_PROFILE) < 0) + return; + + for (size_t count = MAX_LOOP_COUNT; count--; ) { + + // read current vma's size + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_start, sizeof(target_ptr), &vma_vm_start) < 0) + goto next; + + if (is_page_resolved(proc, vma_vm_start)) + goto next; + + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_end, sizeof(target_ptr), &vma_vm_end) < 0) + goto next; + + + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_file, sizeof(target_ptr), &vma_file) < 0 || !vma_file) + goto next; + + if (getDentryFromFile(env, vma_file, &OFFSET_PROFILE)) // populate dentry offset + goto next; + + if (DECAF_read_mem(env, vma_file + OFFSET_PROFILE.file_dentry, sizeof(target_ptr), &f_dentry) < 0 || !f_dentry) + goto next; + + if (populate_dentry_struct_offsets(env, f_dentry, &OFFSET_PROFILE)) + goto next; + + // read small names + if (DECAF_read_mem(env, f_dentry + OFFSET_PROFILE.dentry_d_iname, 32, name) < 0) + goto next; + + name[31] = '\0'; // truncate long string +#if 1 + _name = name; + if (!_name.length() || !(_name.find("lib")==0 && ( _name.find(".so.")!=std::string::npos || _name.find_last_of(".so")==_name.length()-3 ))) + goto next; + + // use module name for key + //monitor_printf(default_mon, "\nlast lib = %s, vm_start = 0x%08x, vm_end = 0x%08x \n", last_mod_name.c_str(), last_vm_start, last_vm_end); + //monitor_printf(default_mon, "new lib = %s, vm_start = 0x%08x, vm_end = 0x%08x \n", name, vma_vm_start, vma_vm_end); + + if (last_mod_name.length() == 0) { // for the first detected module + last_vm_start = vma_vm_start; + last_vm_end = vma_vm_end; + last_mod_name = _name; + } + else if (last_mod_name.compare(_name) != 0 || vma_vm_start != last_vm_end) { // different modules, or when the module is loaded again + // NOTICE the vm_next is sorted by address, according to Linux source code comment, + // so the vma_vm_start should be equal to last_vm_end if they belong to the same module + //sprintf(key, "%s_%x", last_mod_name.c_str(), last_vm_end - last_vm_start); + strcpy(key, last_mod_name.c_str()); + //monitor_printf(default_mon, "mod_name %s \n", key); + + mod = findModule(key); + if (!mod) { + mod = new module(); + strcpy(mod->name, last_mod_name.c_str()); + mod->size = 0; // we update mod size later + addModule(mod, key); + } + procmod_insert_modinfoV(proc->pid, last_vm_start, mod); + message_m(proc->pid, proc->cr3, last_vm_start, mod); + + if (mod->size < last_vm_end - last_vm_start) { // the size may expand or shink at a later time + mod->size = last_vm_end - last_vm_start; + //monitor_printf(default_mon, "shared lib (%s, 0x%08x->0x%08x) is loaded to proc %s (pid = %d) \n", last_mod_name.c_str(), last_vm_start, last_vm_end, proc->name, proc->pid); + } + + // try to dump modules here + dump_modules(env, proc->cr3, mod, last_vm_start); + + last_vm_start = vma_vm_start; + last_vm_end = vma_vm_end; + last_mod_name = _name; + } + else if (last_mod_name.compare(_name) == 0) { + if (last_vm_end == vma_vm_start) // continous sections + last_vm_end = vma_vm_end; // extend vm area + else if (last_vm_start == vma_vm_end) + last_vm_start = vma_vm_start; + } +#endif + +next: + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_next, sizeof(target_ptr), &vma_next) < 0) + break; + if (!vma_next || vma_next == mm_mmap) + break; + } +} + +static process * find_new_process(CPUState *env, uint32_t cr3) { + uint32_t task_pid = 0, ts_parent_pid = 0; + const int MAX_LOOP_COUNT = 300; + // how are we going to traverse the task list? set this to zero we are traverse forward, set to sizeof(target_ptr) we will traverse backward + // (according the list_head) + const target_ulong TASKS_DIRECTION = sizeof(target_ptr); + int count = MAX_LOOP_COUNT; // avoid infinite loop + process *right_proc = NULL, *proc = NULL; + + for (target_ulong next_task = OFFSET_PROFILE.init_task_addr, ts_real_parent, mm, task_pgd, proc_cr3; + count-- ; + ) { + + // NOTICE by reading next_task at the beginning, we are skipping the "init" task + // highly likely linux add the latest process to the tail of the linked list, so we go backward + if (DECAF_read_mem(env, next_task + (OFFSET_PROFILE.ts_tasks + TASKS_DIRECTION), sizeof(target_ptr), &next_task) < 0) + break; + + // NOTE - tasks is a list_head, so we need to minus offset to get the base address + next_task -= OFFSET_PROFILE.ts_tasks; + if (next_task == OFFSET_PROFILE.init_task_addr) // loop back, we have traversed the whole link list + break; + + // read task pid + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_tgid, sizeof(target_ulong), &task_pid) < 0) + continue; + + if ( (proc = findProcessByPid(task_pid)) != NULL) + continue; + + + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_mm, sizeof(target_ptr), &mm) < 0) + continue; + + if (mm == 0) { + // NOTICE kernel thread does not own a process address space, thus its mm is NULL. It uses active_mm instead + continue; + } + else if (populate_mm_struct_offsets(env, mm, &OFFSET_PROFILE) != 0) // see if mm_struct offsets are populated. If not, do it now + continue; // try until we get it. + + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_mm + sizeof(target_ptr), sizeof(target_ptr), &mm) < 0 || DECAF_read_mem(env, mm + OFFSET_PROFILE.mm_pgd, sizeof(target_ulong), &task_pgd) < 0) + continue; + + proc_cr3 = DECAF_get_phys_addr(env, task_pgd); + if (findProcessByCR3(proc_cr3)) + continue; + + // get parent task's base address + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_real_parent, sizeof(target_ptr), &ts_real_parent) < 0) + continue; + + if (DECAF_read_mem(env, ts_real_parent + OFFSET_PROFILE.ts_tgid, sizeof(target_ulong), &ts_parent_pid) < 0) + continue; + + //monitor_printf(default_mon, "pgd =%08x CR3=%08x, pgd_val=%08x\n", task_pgd, cr3, proc_cr3); + + process* pe = new process(); + pe->pid = task_pid; + pe->parent_pid = ts_parent_pid; + pe->cr3 = proc_cr3; + pe->EPROC_base_addr = next_task; // store current task_struct's base address + DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_comm, SIZEOF_COMM, pe->name); + addProcV(pe); + message_p(pe, '+'); + //monitor_printf(default_mon, "new proc = %s, pid = %d, parent_pid = %d \n", pe->name, pe->pid, pe->parent_pid); + if (cr3 == proc_cr3) { + right_proc = pe; + break; // once we find a new process, there is no point traverse the entire of linked list + } + } + + return right_proc; +} + +// retrive symbols from specific process +static void retrive_symbols(CPUState *env, process * proc) { + if (!proc) + return; + for (unordered_map < uint32_t,module * >::iterator it = proc->module_list.begin(); + it != proc->module_list.end(); it++) { + module *cur_mod = it->second; + if (!cur_mod->symbols_extracted) + extract_symbols_info(env, proc->cr3, it->first, cur_mod); + } +} static void Linux_tlb_call_back(DECAF_Callback_Params *temp) { -#if 0 CPUState *env = temp->tx.env; target_ulong vaddr = temp->tx.vaddr; - //struct cr3_info* cr3i = NULL; - int newflag = 0; - - //target_ulong modules; - uint32_t exit_page = 0; - uint32_t cr3 = env->cr[3]; - - process *proc = findProcessByCR3(cr3); - if (proc == NULL) { - //We see a new cr3 - //If this execution is in user land, then this is a new process. - //Otherwise, it is just within the kernel execution, so we don't care. - if (!DECAF_is_in_kernel()) { - newflag = 1; - - //If we haven't found system process, do it now. - if (system_proc == NULL) { - system_proc = find_new_process(env, cr3); - if(system_proc == NULL || strcasecmp(system_proc->name, "System")) { - monitor_printf(default_mon, - "System proc not found!!!\n"); - abort(); - } + uint32_t cr3 = DECAF_getPGD(env); + process *proc = NULL; + int found_new = 0; + + //TODO: kernel modules are not retrieved in the current implementation. + if (DECAF_is_in_kernel()) { + //proc = kernel_proc; + } else { + proc = findProcessByCR3(cr3); + if (proc == NULL) { + proc = find_new_process(env, cr3); + if (proc) { + found_new = 1; + } + } + } - //update_kernel_modules(env, vaddr); + if (proc) { + if(!is_page_resolved(proc, vaddr)) { + char task_comm[SIZEOF_COMM]; + if (!found_new) { + DECAF_read_mem(env, proc->EPROC_base_addr + OFFSET_PROFILE.ts_comm, + SIZEOF_COMM, task_comm); + if(strncmp(proc->name, task_comm, SIZEOF_COMM)) { + //monitor_printf(default_mon, "update proc (%s -> %s), pid = %d \n", proc->name, task_comm, proc->pid); + strcpy(proc->name, task_comm); + message_p(proc, '^'); + } + } + get_new_modules(env, proc); - proc = system_proc; - } else { - proc = find_new_process(env, cr3); + if (!is_page_resolved(proc, vaddr)) { + if (proc->pending_pages.find(vaddr>>12) == proc->pending_pages.end()) + proc->pending_pages.insert(vaddr>>12); + else { + proc->pending_pages.erase(vaddr>>12); + proc->resolved_pages.insert(vaddr>>12); + } } + } + // retrive symbol information here + retrive_symbols(env, proc); } +} - //getting_new_mods++; - //monitor_printf(default_mon,"%d\n", getting_new_mods++); - if (proc) - get_new_modules(env, proc, vaddr); -#endif +static void check_procexit(void *) { + CPUState *env = cpu_single_env ? cpu_single_env : first_cpu; + qemu_mod_timer(recon_timer, + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * 30); + size_t numofProc, task_pid = 0; + dprocess *processes; + target_ulong next_task = OFFSET_PROFILE.init_task_addr; + processes = find_all_processes_infoV(&numofProc); + dprocess *proc; + unordered_set taskPID_set; + // store all tasks first + taskPID_set.insert(0); // init_task shall never be removed + for (int i = 0; i < 512; i++) { // limit loop round, avoid infinite loop + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_tasks, sizeof(target_ptr), &next_task) < 0) + break; + next_task -= OFFSET_PROFILE.ts_tasks; + if (next_task == OFFSET_PROFILE.init_task_addr) + break; + if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_pid, sizeof(target_ulong), &task_pid) < 0) + break; + taskPID_set.insert(task_pid); // push pid into a set + } + if (processes != NULL) { + // what we do here is to traverse the running task list, + // remove non-exist tasks + for (size_t i = numofProc; i--; ) { + proc = &processes[i]; + if (taskPID_set.find(proc->pid) == taskPID_set.end()) { // remove when not found + removeProcV(proc->pid); + message_p_d(proc, '-'); + //monitor_printf(default_mon, "proc %s (pid = %d) is removed \n", proc->name, proc->pid); + } + } + } + delete[] processes; } +// to see whether this is a Linux or not, +// the trick is to check the init_thread_info, init_task +int find_linux(CPUState *env, uintptr_t insn_handle) { + target_ulong _thread_info = DECAF_getESP(env) & ~ (guestOS_THREAD_SIZE - 1); + static target_ulong _last_thread_info = 0; + + // if current address is tested before, save time and do not try it again + if (_thread_info == _last_thread_info || _thread_info <= 0x80000000) + return 0; + // first time run + if (_last_thread_info == 0) + memset(&OFFSET_PROFILE.init_task_addr, -1, sizeof(ProcInfo) - sizeof(OFFSET_PROFILE.strName)); + + _last_thread_info = _thread_info; -void Linux_vmi_init() + // try populate kernel offset, NOTICE we cannot get mm_struct offset yet + if (populate_kernel_offsets(env, _thread_info, &OFFSET_PROFILE) != 0) + return (0); + + monitor_printf(default_mon, "init_task @ [%08x] \n", OFFSET_PROFILE.init_task_addr); + // it is firm that this is linux. we can start extract process information here, but mm offsets may not be ready yet + + //printProcInfo(&OFFSET_PROFILE); + + return (1); +} + +void linux_vmi_init() { DECAF_register_callback(DECAF_TLB_EXEC_CB, Linux_tlb_call_back, NULL); -#if 0 recon_timer = qemu_new_timer_ns(vm_clock, check_procexit, 0); qemu_mod_timer(recon_timer, - qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * 30); -#endif - + qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * 30); } #endif /* CONFIG_VMI_ENABLE*/ diff --git a/shared/linux_vmi.h b/shared/linux_vmi.h index 9e5502d..8c7ff30 100644 --- a/shared/linux_vmi.h +++ b/shared/linux_vmi.h @@ -19,6 +19,8 @@ If you have any questions about DECAF,please post it on * * Created on: June 7, 2013 * Author: Heng Yin + * Updated on: Sept 11, 2013 + * by: Kevin Wang */ @@ -30,8 +32,12 @@ If you have any questions about DECAF,please post it on extern "C" { #endif -void Linux_vmi_init(); -//void tlb_call_back(DECAF_Callback_Params *temp); +#define guestOS_THREAD_SIZE 8192 + +#define SIZEOF_COMM 16 + +int find_linux(CPUState *env, uintptr_t insn_handle); +void linux_vmi_init(); #ifdef __cplusplus }; diff --git a/shared/procmod.cpp b/shared/procmod.cpp index f0b5bdc..22a8e30 100644 --- a/shared/procmod.cpp +++ b/shared/procmod.cpp @@ -83,8 +83,11 @@ static unordered_map < uint32_t, process_info_t * >process_map; //map pid to process_info_t static unordered_map < uint32_t, process_info_t * >process_pid_map; +extern FILE *guestlog; + void handle_guest_message(const char *message) { + //fprintf(guestlog, "%s\n", message); switch (message[0]) { case 'P': parse_process(message); @@ -254,33 +257,43 @@ int procmod_createproc(uint32_t pid, uint32_t parent_pid, int procmod_removeproc(uint32_t pid) { - procmod_Callback_Params params; + procmod_Callback_Params params; - params.rp.pid = pid; + params.rp.pid = pid; - SimpleCallback_dispatch(&procmod_callbacks[PROCMOD_REMOVEPROC_CB], ¶ms); + SimpleCallback_dispatch(&procmod_callbacks[PROCMOD_REMOVEPROC_CB], ¶ms); - // if (removeproc_notify) -// removeproc_notify(pid); + unordered_map < uint32_t, process_info_t * >::iterator iter = + process_pid_map.find(pid); + if (iter == process_pid_map.end()) //pid not found + return -1; - unordered_map < uint32_t, process_info_t * >::iterator iter = - process_pid_map.find(pid); - if (iter == process_pid_map.end()) //pid not found - return -1; + process_info_t *proc = iter->second; + module_info_t *mod; - process_info_t *proc = iter->second; - module_info_t *mod; + while (!proc->module_list.empty()) { + mod = proc->module_list.front(); + proc->module_list.pop_front(); + delete mod; + } - while (!proc->module_list.empty()) { - mod = proc->module_list.front(); - proc->module_list.pop_front(); - delete mod; - } + process_pid_map.erase(iter); + process_map.erase(proc->cr3); + delete proc; + return 0; +} - process_pid_map.erase(iter); - process_map.erase(proc->cr3); - delete proc; - return 0; +int procmod_update_name(uint32_t pid, char *name) +{ + unordered_map < uint32_t, process_info_t * >::iterator iter = + process_pid_map.find(pid); + if (iter == process_pid_map.end()) //pid not found + return -1; + + process_info_t *proc = iter->second; + proc->name = name; + + return 0; } @@ -307,7 +320,7 @@ static int procmod_remove_all() return 0; } - +#if 0 void update_proc(void *opaque) { // long taskaddr = 0xC033C300; @@ -365,7 +378,7 @@ void update_proc(void *opaque) } while (nextaddr != taskaddr); } - +#endif void procmod_cleanup() { @@ -559,7 +572,7 @@ void list_procs(Monitor *mon) // AWH void) } } - +#if 0 void linux_ps(Monitor *mon, int mmap_flag) { int pid; @@ -600,7 +613,7 @@ monitor_printf(mon, "linux_ps() -> After update_proc(0)\n"); // AWH } while (nextaddr != taskaddr); } - +#endif uint32_t find_cr3(uint32_t pid) { @@ -821,10 +834,12 @@ int procmod_init() fclose(guestlog); } +#if 0 //TODO: save and load thread information if (init_kernel_offsets() >= 0) hookapi_hook_function(1, hookingpoint, 0, update_proc, NULL, 0); +#endif // AWH - Added NULL parm for DeviceState* (change in API) register_savevm(NULL, "procmod", 0, 1, procmod_save, procmod_load, NULL); @@ -858,8 +873,13 @@ void parse_process(const char *log) procmod_createproc(pid, parent_pid, cr3, name); else procmod_createproc(pid, parent_pid, -1, ""); - break; + case '^': + procmod_update_name(pid, name); + break; + default: + + abort(); } } diff --git a/shared/procmod.h b/shared/procmod.h index 6936589..34b85b8 100644 --- a/shared/procmod.h +++ b/shared/procmod.h @@ -158,7 +158,7 @@ extern uint32_t find_pid_by_name(const char* proc_name); extern void list_procs(Monitor *mon); // AWH void); //extern void do_linux_ps(Monitor *mon); // AWH void); -extern void linux_ps(Monitor *mon, int mmap_flag); +//extern void linux_ps(Monitor *mon, int mmap_flag); extern void list_guest_modules(Monitor *mon, uint32_t pid); void parse_process(const char *log); diff --git a/shared/tainting/DECAF_taint_helper.h b/shared/tainting/DECAF_taint_helper.h index 075acad..c371bf7 100644 --- a/shared/tainting/DECAF_taint_helper.h +++ b/shared/tainting/DECAF_taint_helper.h @@ -42,15 +42,15 @@ DEF_HELPER_6(taint_event5_64, void, i32, i64, i64, i64, i64, i64) Since values are the first arguments, the (VC, VC) form of the opcode results in a helper function call of (V, V, C, C). */ - -/* 5 parms: (VC, VC, VC, V, V) */ -DEF_HELPER_8(taint_log_deposit_i32, void, i32, i32, i32, i32, i32, i32, i32, i32) -/* 6 parms: (VC, VC, VC, VC, VC, V) */ -DEF_HELPER_11(taint_log_setcond2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -/* 1 parm: (VC) */ -DEF_HELPER_2(taint_log_movi_i32, void, i32, i32) -/* 2 parms: (VC, VC) */ -DEF_HELPER_4(taint_log_mov_i32, void, i32, i32, i32, i32) +DEF_HELPER_2(taint_log_pointer, void, i32, i32) +/* 5 parms: (V, VC, VC, V, V) */ +DEF_HELPER_7(taint_log_deposit_i32, void, i32, i32, i32, i32, i32, i32, i32) +/* 6 parms: (V, VC, VC, VC, VC, V) */ +DEF_HELPER_10(taint_log_setcond2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) +/* 1 parm: (V) */ +DEF_HELPER_1(taint_log_movi_i32, void, i32) +/* 2 parms: (V, VC) */ +DEF_HELPER_3(taint_log_mov_i32, void, i32, i32, i32) /* 4 parms: (VC, VC, V, ID) - Sixth parm is the opcode ID (follows concrete) */ DEF_HELPER_6(taint_log_qemu_ld, void, i32, i32, i32, i32, i32, i32) DEF_HELPER_6(taint_log_qemu_st, void, i32, i32, i32, i32, i32, i32) @@ -58,61 +58,61 @@ DEF_HELPER_6(taint_log_qemu_st, void, i32, i32, i32, i32, i32, i32) DEF_HELPER_?(taint_log_qemu_ld64, void, ?) DEF_HELPER_?(taint_log_qemu_st64, void, ?) #endif // AWH -/* 4 parms: (VC, VC, VC, V) */ -DEF_HELPER_7(taint_log_setcond_i32, void, i32, i32, i32, i32, i32, i32, i32) -/* 3 parms: (VC, VC, VC) */ -DEF_HELPER_6(taint_log_shl_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_shr_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_sar_i32, void, i32, i32, i32, i32, i32, i32) +/* 4 parms: (V, VC, VC, V) */ +DEF_HELPER_6(taint_log_setcond_i32, void, i32, i32, i32, i32, i32, i32) +/* 3 parms: (V, VC, VC) */ +DEF_HELPER_5(taint_log_shl_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_shr_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_sar_i32, void, i32, i32, i32, i32, i32) #if TCG_TARGET_HAS_rot_i32 -DEF_HELPER_6(taint_log_rotl_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_rotr_i32, void, i32, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_rotl_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_rotr_i32, void, i32, i32, i32, i32, i32) #endif /* TCG_TARGET_HAS_rot_i32 */ -DEF_HELPER_6(taint_log_add_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_sub_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_mul_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_and_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_or_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_xor_i32, void, i32, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_add_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_sub_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_mul_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_and_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_or_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_xor_i32, void, i32, i32, i32, i32, i32) #if TCG_TARGET_HAS_div_i32 -DEF_HELPER_6(taint_log_div_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_divu_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_rem_i32, void, i32, i32, i32, i32, i32, i32) -DEF_HELPER_6(taint_log_remu_i32, void, i32, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_div_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_divu_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_rem_i32, void, i32, i32, i32, i32, i32) +DEF_HELPER_5(taint_log_remu_i32, void, i32, i32, i32, i32, i32) #elif TCG_TARGET_HAS_div2_i32 -/* 5 parms: (VC, VC, VC, VC, VC) */ -DEF_HELPER_10(taint_log_div2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -DEF_HELPER_10(taint_log_divu2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) +/* 5 parms: (V, V, VC, VC, VC) */ +DEF_HELPER_8(taint_log_div2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32) +DEF_HELPER_8(taint_log_divu2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32) #endif /* TCG_TARGET_HAS_div_i32 */ -/* 4 parms: (VC, VC, VC, VC) */ -DEF_HELPER_8(taint_log_mulu2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32) -/* 6 parms: (VC, VC, VC, VC, VC, VC) */ -DEF_HELPER_12(taint_log_add2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -DEF_HELPER_12(taint_log_sub2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -/* 2 parms: (VC, VC) */ +/* 4 parms: (V, V, VC, VC) */ +DEF_HELPER_6(taint_log_mulu2_i32, void, i32, i32, i32, i32, i32, i32) +/* 6 parms: (V, V, VC, VC, VC, VC) */ +DEF_HELPER_10(taint_log_add2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) +DEF_HELPER_10(taint_log_sub2_i32, void, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) +/* 2 parms: (V, VC) */ #if TCG_TARGET_HAS_ext8s_i32 -DEF_HELPER_4(taint_log_ext8s_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_ext8s_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_ext8s_i32 */ #if TCG_TARGET_HAS_ext16s_i32 -DEF_HELPER_4(taint_log_ext16s_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_ext16s_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_ext16s_i32 */ #if TCG_TARGET_HAS_ext8u_i32 -DEF_HELPER_4(taint_log_ext8u_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_ext8u_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_ext8u_i32 */ #if TCG_TARGET_HAS_ext16u_i32 -DEF_HELPER_4(taint_log_ext16u_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_ext16u_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_ext16u_i32 */ #if TCG_TARGET_HAS_bswap16_i32 -DEF_HELPER_4(taint_log_bswap16_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_bswap16_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_bswap16_i32 */ #if TCG_TARGET_HAS_bswap32_i32 -DEF_HELPER_4(taint_log_bswap32_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_bswap32_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_bswap32_i32 */ #if TCG_TARGET_HAS_not_i32 -DEF_HELPER_4(taint_log_not_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_not_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_not_i32 */ #if TCG_TARGET_HAS_neg_i32 -DEF_HELPER_4(taint_log_neg_i32, void, i32, i32, i32, i32) +DEF_HELPER_3(taint_log_neg_i32, void, i32, i32, i32) #endif /* TCG_TARGET_HAS_neg_i32 */ /* TODO: All of the 64-bit opcodes */ diff --git a/shared/tainting/analysis_log.c b/shared/tainting/analysis_log.c index 5c95706..883c632 100644 --- a/shared/tainting/analysis_log.c +++ b/shared/tainting/analysis_log.c @@ -1,3 +1,9 @@ +#if defined(__SSE__) +#include +#define SPIN_DELAY _mm_pause(); +#else +#define SPIN_DELAY __asm__ __volatile__ ("pause"); +#endif #include #include #include @@ -8,10 +14,16 @@ #include "helper.h" // AWH /* The buffered internal analysis log */ -#define MAX_LOG_ENTRIES 512 static uint8_t temp_liveness[TCG_MAX_TEMPS]; -static analysis_log_entry_t analysisLog[MAX_LOG_ENTRIES]; -static uint32_t logSize = 0; +analysis_log_entry_t *analysis_log = NULL; +static uint32_t writer_current_block = 0; +static uint32_t writer_current_index = 0; +static uint16_t current_reader_writer_offset = 0; +static uint32_t reader_current_block = 0; +static uint16_t reader_current_index = 0; +static uint32_t log_initialized = 0; +static volatile int block_lock[MAX_LOG_BLOCKS]; +static int i = 0; /* These are our concrete global registers */ #if defined(TARGET_X86_64) @@ -20,10 +32,61 @@ static uint64_t cpu_regs[16]; static uint32_t cpu_regs[8]; #elif defined(TARGET_ARM) static uint32_t cpu_regs[16]; +#elif defined(TARGET_MIPS) +static uint32_t cpu_regs[32]; #else #error Unknown target #endif +static inline void log_spin_lock(int lock) { + if (lock >= MAX_LOG_BLOCKS) lock = 0; + while (!__sync_bool_compare_and_swap((block_lock + lock), 0, 1)) + while(block_lock[lock]) SPIN_DELAY +} + +static inline void log_spin_unlock(int lock) { + asm volatile (""); + block_lock[lock] = 0; +} + +void initialize_taint_log(void) { + if (!log_initialized) { + log_initialized = 1; + if (analysis_log) free(analysis_log); + analysis_log = (analysis_log_entry_t *)calloc(sizeof(analysis_log_entry_t), MAX_LOG_ENTRIES_PER_BLOCK * MAX_LOG_BLOCKS); + writer_current_block = writer_current_index = 0; + reader_current_block = reader_current_index = 0; + + for (i = 0; i < MAX_LOG_BLOCKS; i++) + block_lock[i] = 0; + + /* Start with the writer locking block 0 */ + log_spin_lock(0); + + /* TODO: Start reader thread */ + } +} + +static inline change_lock(uint32_t volatile current_block) { + /* Release the lock on this block */ + log_spin_unlock(writer_current_block >> 16); + + /* Change to the next block */ + writer_current_block += MAX_LOG_ENTRIES_PER_BLOCK; + if (writer_current_block > (MAX_LOG_ENTRIES_PER_BLOCK * MAX_LOG_BLOCKS)) + writer_current_block = 0; + + /* Lock the current block */ + log_spin_lock(writer_current_block >> 16); +} + +static inline insert_record0(uint32_t op) { + analysis_log[writer_current_block + writer_current_index++].op = op; + + /* Have we reached the end of the current block (integer wrap)? */ + if (!writer_current_index) change_lock(writer_current_index); +} + void helper_taint_event1_32(uint32_t op, uint32_t arg0) {} void helper_taint_event1_64(uint32_t op, uint64_t arg0) {} @@ -57,6 +120,7 @@ void helper_taint_event4_64(uint32_t op, uint64_t arg0, uint64_t arg1, uint64_t void helper_taint_event5_32(uint32_t op, uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4) { +#if 0 assert(logSize < MAX_LOG_ENTRIES); analysisLog[logSize].op = op; analysisLog[logSize].arg[0] = arg0; @@ -64,10 +128,12 @@ void helper_taint_event5_32(uint32_t op, uint32_t arg0, uint32_t arg1, analysisLog[logSize].arg[2] = arg2; analysisLog[logSize].arg[3] = arg3; analysisLog[logSize].arg[4] = arg4; +#endif } void helper_taint_event5_64(uint32_t op, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) { +#if 0 assert(logSize < MAX_LOG_ENTRIES); analysisLog[logSize].op = op; analysisLog[logSize].arg[0] = arg0; @@ -75,9 +141,11 @@ void helper_taint_event5_64(uint32_t op, uint64_t arg0, uint64_t arg1, analysisLog[logSize].arg[2] = arg2; analysisLog[logSize].arg[3] = arg3; analysisLog[logSize].arg[4] = arg4; +#endif } void DECAF_block_begin_for_analysis(void) { +#if 0 int32_t currentIndex; if (logSize == 0) return; /* Each temp is alive or dead. Alive temps are a concrete @@ -92,158 +160,168 @@ void DECAF_block_begin_for_analysis(void) { } currentIndex--; } +#endif +} +void helper_taint_log_pointer(uint32_t pointer,uint32_t taint_value) +{ + if(taint_value!=0) + fprintf(stderr,"0x%08x 0x%08x \n",pointer,taint_value); } -void helper_taint_log_deposit_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: deposit_i32()"); +void helper_taint_log_deposit_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: deposit_i32()\n"); } -void helper_taint_log_setcond2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5) { - fprintf(stderr, "log: setcond2_i32()"); +void helper_taint_log_setcond2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5) { + //fprintf(stderr, "log: setcond2_i32()\n"); } -void helper_taint_log_movi_i32(uint32_t reg1, uint32_t taint1) { - fprintf(stderr, "log: movi_i32(%d:%d, 0)\n", reg1, taint1); +void helper_taint_log_movi_i32(uint32_t reg1) { + insert_record0(INDEX_op_movi_i32); + //fprintf(stderr, "log: movi_i32(%d, 0)\n", reg1); } -void helper_taint_log_mov_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: mov_i32(%d:%d, %d:%d)\n", reg1, taint1, reg2, taint2); +void helper_taint_log_mov_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + insert_record0(INDEX_op_mov_i32); +// fprintf(stderr, "log: mov_i32(%d, %d:%d)\n", reg1, reg2, taint2); } +// No LHS change yet void helper_taint_log_qemu_ld(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t id) { - fprintf(stderr, "log: qemu_ld()"); + //fprintf(stderr, "log: qemu_ld()\n"); } +// No LHS change yet void helper_taint_log_qemu_st(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t id) { - fprintf(stderr, "log: qemu_st()"); + //fprintf(stderr, "log: qemu_st()"); } -void helper_taint_log_setcond_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: setcond_i32()"); +void helper_taint_log_setcond_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: setcond_i32()"); } -void helper_taint_log_shl_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: shl_i32()"); +void helper_taint_log_shl_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: shl_i32()\n"); } -void helper_taint_log_shr_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: shr_i32()"); +void helper_taint_log_shr_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: shr_i32()\n"); } -void helper_taint_log_sar_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: sar_i32()"); +void helper_taint_log_sar_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: sar_i32()\n"); } #if TCG_TARGET_HAS_rot_i32 -void helper_taint_log_rotl_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: rotl_i32()"); +void helper_taint_log_rotl_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: rotl_i32()\n"); } -void helper_taint_log_rotr_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: rotr_i32()"); +void helper_taint_log_rotr_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: rotr_i32()\n"); } #endif /* TCG_TARGET_HAS_rot_i32 */ -void helper_taint_log_add_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: add_i32()"); +void helper_taint_log_add_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: add_i32()\n"); } -void helper_taint_log_sub_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: sub_i32()"); +void helper_taint_log_sub_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: sub_i32()\n"); } -void helper_taint_log_mul_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: mul_i32()"); +void helper_taint_log_mul_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: mul_i32()\n"); } -void helper_taint_log_and_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: and_i32()"); +void helper_taint_log_and_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: and_i32()\n"); } -void helper_taint_log_or_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: or_i32()"); +void helper_taint_log_or_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: or_i32()\n"); } -void helper_taint_log_xor_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: xor_i32()"); +void helper_taint_log_xor_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: xor_i32()\n"); } #if TCG_TARGET_HAS_div_i32 -void helper_taint_log_div_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: div_i32()"); +void helper_taint_log_div_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: div_i32()\n"); } -void helper_taint_log_divu_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: divu_i32()"); +void helper_taint_log_divu_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: divu_i32()\n"); } -void helper_taint_log_rem_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: rem_i32()"); +void helper_taint_log_rem_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: rem_i32()\n"); } -void helper_taint_log_remu_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint1, uint32_t taint2, uint32_t taint3) { - fprintf(stderr, "log: remu_i32()"); +void helper_taint_log_remu_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t taint2, uint32_t taint3) { + //fprintf(stderr, "log: remu_i32()\n"); } #elif TCG_TARGET_HAS_div2_i32 -void helper_taint_log_div2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5) { - fprintf(stderr, "log: div2_i32()"); +void helper_taint_log_div2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint3, uint32_t taint4, uint32_t taint5) { + //fprintf(stderr, "log: div2_i32()\n"); } -void helper_taint_log_divu2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5) { - fprintf(stderr, "log: divu2_i32()"); +void helper_taint_log_divu2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t taint3, uint32_t taint4, uint32_t taint5) { + //fprintf(stderr, "log: divu2_i32()\n"); } #endif /* TCG_TARGET_HAS_div2_i32 */ -void helper_taint_log_mulu2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4) { - fprintf(stderr, "log: mulu2_i32()"); +void helper_taint_log_mulu2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t taint3, uint32_t taint4) { + //fprintf(stderr, "log: mulu2_i32()\n"); } -void helper_taint_log_add2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5, uint32_t taint6) { - fprintf(stderr, "log: add2_i32()"); +void helper_taint_log_add2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint3, uint32_t taint4, uint32_t taint5, uint32_t taint6) { + //fprintf(stderr, "log: add2_i32()\n"); } -void helper_taint_log_sub2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint1, uint32_t taint2, uint32_t taint3, uint32_t taint4, uint32_t taint5, uint32_t taint6) { - fprintf(stderr, "log: sub2_i32()"); +void helper_taint_log_sub2_i32(uint32_t reg1, uint32_t reg2, uint32_t reg3, uint32_t reg4, uint32_t reg5, uint32_t reg6, uint32_t taint3, uint32_t taint4, uint32_t taint5, uint32_t taint6) { + //fprintf(stderr, "log: sub2_i32()\n"); } #if TCG_TARGET_HAS_ext8s_i32 -void helper_taint_log_ext8s_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: ext8s_i32()"); +void helper_taint_log_ext8s_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: ext8s_i32()\n"); } #endif /* TCG_TARGET_HAS_ext8s_i32 */ #if TCG_TARGET_HAS_ext16s_i32 -void helper_taint_log_ext16s_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: ext16s_i32()"); +void helper_taint_log_ext16s_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: ext16s_i32()\n"); } #endif /* TCG_TARGET_HAS_ext16s_i32 */ #if TCG_TARGET_HAS_ext8u_i32 -void helper_taint_log_ext8u_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: ext8u_i32()"); +void helper_taint_log_ext8u_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: ext8u_i32()\n"); } #endif /* TCG_TARGET_HAS_ext8u_i32 */ #if TCG_TARGET_HAS_ext16u_i32 -void helper_taint_log_ext16u_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: ext16u_i32()"); +void helper_taint_log_ext16u_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: ext16u_i32()\n"); } #endif /* TCG_TARGET_HAS_ext16u_i32 */ #if TCG_TARGET_HAS_bswap16_i32 -void helper_taint_log_bswap16_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: bswap16_i32()"); +void helper_taint_log_bswap16_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: bswap16_i32()\n"); } #endif /* TCG_TARGET_HAS_bswap16_i32 */ #if TCG_TARGET_HAS_bswap32_i32 -void helper_taint_log_bswap32_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: bswap32_i32()"); +void helper_taint_log_bswap32_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: bswap32_i32()\n"); } #endif /* TCG_TARGET_HAS_bswap32_i32 */ #if TCG_TARGET_HAS_not_i32 -void helper_taint_log_not_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: not_i32()"); +void helper_taint_log_not_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { + //fprintf(stderr, "log: not_i32()\n"); } #endif /* TCG_TARGET_HAS_not_i32 */ #if TCG_TARGET_HAS_neg_i32 -void helper_taint_log_neg_i32(uint32_t reg1, uint32_t reg2, uint32_t taint1, uint32_t taint2) { - fprintf(stderr, "log: neg_i32()"); +void helper_taint_log_neg_i32(uint32_t reg1, uint32_t reg2, uint32_t taint2) { +// fprintf(stderr, "log: neg_i32()\n"); } #endif /* TCG_TARGET_HAS_neg_i32 */ diff --git a/shared/tainting/analysis_log.h b/shared/tainting/analysis_log.h index e48c918..b4a326e 100644 --- a/shared/tainting/analysis_log.h +++ b/shared/tainting/analysis_log.h @@ -10,9 +10,10 @@ extern "C" { /* This is the datatype for every analysis log entry. Not every log entry type uses all of these fields, but by using a fixed record size for each log entry, maintenance of the log becomes easier. */ +#define ANALYSIS_RECORD_SIZE 8 typedef struct { uint32_t op; - uint64_t arg[5]; + uint32_t arg[7]; } analysis_log_entry_t; /* When a new block begins, any pending taint events from the previous @@ -26,6 +27,13 @@ extern void DECAF_block_begin_for_analysis(void); /* When the MMU resolves a virtual address to a physical one, it gets logged */ extern void DECAF_resolved_phys_addr(uint32_t addr); +/* This is our analysis log that is being filled as the guest executes */ +extern analysis_log_entry_t *analysis_log; +extern uint16_t producer_index; +extern uint16_t consumer_index; +#define MAX_LOG_ENTRIES_PER_BLOCK 65536 +#define MAX_LOG_BLOCKS 16 + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shared/tainting/taint_memory.c b/shared/tainting/taint_memory.c index e97f7fa..0dc8c25 100644 --- a/shared/tainting/taint_memory.c +++ b/shared/tainting/taint_memory.c @@ -167,7 +167,7 @@ void REGPARM __taint_ldb_raw_paddr(ram_addr_t addr,gva_t vaddr) cpu_single_env->tempidx = (*(uint8_t *)(leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); cpu_single_env->tempidx = cpu_single_env->tempidx & 0xFF; //if (cpu_single_env->tempidx) { fprintf(stderr, "__taint_ldb_raw(0x%08x) -> 0x%08x\n", addr, cpu_single_env->tempidx); __asm__ ("int $3"); } - if (cpu_single_env->tempidx & DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)){ + if (cpu_single_env->tempidx && DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)){ helper_DECAF_invoke_read_taint_mem(vaddr,addr,1,(uint8_t *)(leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); } } @@ -195,7 +195,7 @@ void REGPARM __taint_ldw_raw_paddr(ram_addr_t addr,gva_t vaddr) cpu_single_env->tempidx = (*(uint16_t *)(leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); cpu_single_env->tempidx = cpu_single_env->tempidx & 0xFFFF; //if (cpu_single_env->tempidx) { fprintf(stderr, "__taint_ldw_raw(0x%08x) -> 0x%08x\n", addr, cpu_single_env->tempidx); __asm__ ("int $3"); } - if (cpu_single_env->tempidx & DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) { + if (cpu_single_env->tempidx && DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) { helper_DECAF_invoke_read_taint_mem(vaddr,addr,2,(uint8_t *)(leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); } } @@ -224,7 +224,7 @@ void REGPARM __taint_ldl_raw_paddr(ram_addr_t addr,gva_t vaddr) cpu_single_env->tempidx = cpu_single_env->tempidx & 0xFFFFFFFF; #endif /* TCG_TARGET_REG_BITS == 64 */ //if (cpu_single_env->tempidx) { fprintf(stderr, "__taint_ldl_raw(0x%08x) -> 0x%08x\n", addr, cpu_single_env->tempidx); __asm__ ("int $3"); } - if (cpu_single_env->tempidx & DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) { + if (cpu_single_env->tempidx && DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) { helper_DECAF_invoke_read_taint_mem(vaddr,addr,4,(uint8_t *)(leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); } @@ -267,7 +267,7 @@ void REGPARM __taint_ldq_raw_paddr(ram_addr_t addr,gva_t vaddr) } // 32 -bit debug //if (cpu_single_env->tempidx || cpu_single_env->tempidx2) { fprintf(stderr, "__taint_ldq_raw(0x%08x) -> 0x%08x, 0x%08x\n", addr, cpu_single_env->tempidx, cpu_single_env->tempidx2); __asm__ ("int $3"); } - if ((cpu_single_env->tempidx || cpu_single_env->tempidx2) & DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) + if ((cpu_single_env->tempidx || cpu_single_env->tempidx2) && DECAF_is_callback_needed(DECAF_READ_TAINTMEM_CB)) { taint_temp[0] = cpu_single_env->tempidx; taint_temp[1] = cpu_single_env->tempidx2; @@ -302,14 +302,23 @@ void REGPARM __taint_stb_raw_paddr(ram_addr_t addr,gva_t vaddr) { return; //if (cpu_single_env->tempidx & 0xFF) { fprintf(stderr, "__taint_stb_raw(0x%08x) -> 0x%08x\n", addr, cpu_single_env->tempidx & 0xFF); __asm__ ("int $3"); } + /* AWH - Keep track of whether the taint state has changed for this location. + If taint was 0 and it is 0 after this store, then change is 0. Otherwise, + it is 1. This is so any plugins can track that there has been a change + in taint. */ + uint16_t before, after; + char changed = 0; tbitpage_leaf_t *leaf_node = taint_st_general_i32(addr, cpu_single_env->tempidx & 0xFF); - if (leaf_node) + if (leaf_node) { + before = *(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); *(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)) = cpu_single_env->tempidx & 0xFF; - - if ( ( cpu_single_env->tempidx & 0xFF) & DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) + after = *(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); + if ((before != after) || (cpu_single_env->tempidx & 0xFF)) changed = 1; + } + if ( changed && DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) helper_DECAF_invoke_write_taint_mem(vaddr,addr,1,(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); return; } @@ -319,15 +328,25 @@ void REGPARM __taint_stw_raw_paddr(ram_addr_t addr,gva_t vaddr) { return; //if (cpu_single_env->tempidx & 0xFFFF) {fprintf(stderr, "__taint_stw_raw(0x%08x) -> 0x%08x\n", addr,cpu_single_env->tempidx & 0xFFFF);__asm__ ("int $3");} + /* AWH - Keep track of whether the taint state has changed for this location. + If taint was 0 and it is 0 after this store, then change is 0. Otherwise, + it is 1. This is so any plugins can track that there has been a change + in taint. */ + uint16_t before, after; + char changed = 0; tbitpage_leaf_t *leaf_node = taint_st_general_i32(addr, cpu_single_env->tempidx & 0xFFFF); - if (leaf_node) + if (leaf_node) { + before = *(uint16_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); *(uint16_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)) = (uint16_t) cpu_single_env->tempidx & 0xFFFF; - if ( ( cpu_single_env->tempidx & 0xFFFF) & DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) + after = *(uint16_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); + if ((before != after) || (cpu_single_env->tempidx & 0xFFFF)) changed = 1; + } + if ( changed && DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) { helper_DECAF_invoke_write_taint_mem(vaddr,addr,2,(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); - + } return; } @@ -336,14 +355,23 @@ void REGPARM __taint_stl_raw_paddr(ram_addr_t addr,gva_t vaddr) { return; //if (cpu_single_env->tempidx & 0xFFFFFFFF) {fprintf(stderr, "__taint_stl_raw(0x%08x) -> 0x%08x\n", addr,cpu_single_env->tempidx & 0xFFFFFFFF);__asm__ ("int $3");} + /* AWH - Keep track of whether the taint state has changed for this location. + If taint was 0 and it is 0 after this store, then change is 0. Otherwise, + it is 1. This is so any plugins can track that there has been a change + in taint. */ + uint16_t before, after; + char changed = 0; tbitpage_leaf_t *leaf_node = taint_st_general_i32(addr, cpu_single_env->tempidx & 0xFFFFFFFF); - if (leaf_node) + if (leaf_node) { + before = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)) = cpu_single_env->tempidx & 0xFFFFFFFF; - - if ( ( cpu_single_env->tempidx & 0xFFFFFFFF) & DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) + after = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); + if ((before != after) || (cpu_single_env->tempidx & 0xFFFFFFFF)) changed = 1; + } + if ( changed && DECAF_is_callback_needed( DECAF_WRITE_TAINTMEM_CB) ) helper_DECAF_invoke_write_taint_mem(vaddr,addr,4,(uint8_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK))); return; } @@ -351,6 +379,14 @@ void REGPARM __taint_stl_raw_paddr(ram_addr_t addr,gva_t vaddr) { void REGPARM __taint_stq_raw_paddr(ram_addr_t addr,gva_t vaddr) { if (!taint_memory_page_table || addr >= ram_size) return; + + /* AWH - Keep track of whether the taint state has changed for this location. + If taint was 0 and it is 0 after this store, then change is 0. Otherwise, + it is 1. This is so any plugins can track that there has been a change + in taint. */ + uint16_t before, after; + char changed = 0; + tbitpage_leaf_t *leaf_node = NULL, *leaf_node2 = NULL; uint32_t taint_temp[2]; @@ -372,15 +408,23 @@ void REGPARM __taint_stq_raw_paddr(ram_addr_t addr,gva_t vaddr) { leaf_node = taint_st_general_i32(addr, cpu_single_env->tempidx); leaf_node2 = taint_st_general_i32(addr + 4, cpu_single_env->tempidx2); - if (leaf_node) + if (leaf_node) { + before = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)) = cpu_single_env->tempidx; - if (leaf_node2) + after = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); + if ((before != after) || (cpu_single_env->tempidx & 0xFFFFFFFF)) changed = 1; + } + if (leaf_node2) { + before = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); *(uint32_t *) (leaf_node2->bitmap + ((addr+4) & LEAF_ADDRESS_MASK)) = cpu_single_env->tempidx2; + after = *(uint32_t *) (leaf_node->bitmap + (addr & LEAF_ADDRESS_MASK)); + if ((before != after) || (cpu_single_env->tempidx2 & 0xFFFFFFFF)) changed = 1; + } #endif /* TCG_TARGET_REG_BITS check */ - if ( ( cpu_single_env->tempidx || cpu_single_env->tempidx2 ) & DECAF_is_callback_needed (DECAF_WRITE_TAINTMEM_CB) ) + if ( changed && DECAF_is_callback_needed (DECAF_WRITE_TAINTMEM_CB) ) { taint_temp[0] = cpu_single_env->tempidx; taint_temp[1] = cpu_single_env->tempidx2; diff --git a/shared/tainting/taintcheck_opt.h b/shared/tainting/taintcheck_opt.h index c790064..6fae4db 100644 --- a/shared/tainting/taintcheck_opt.h +++ b/shared/tainting/taintcheck_opt.h @@ -34,8 +34,13 @@ extern "C" { static inline uint64_t taintcheck_register_check(int regid,int offset,int size,CPUState *env){ int off = offset*8; +#if defined(TARGET_MIPS) + return (size < 4) ? (env->active_tc.taint_regs[regid]>>off) + &size_to_mask(size):env->active_tc.taint_regs[regid]>>off; +#else return (size < 4) ? (env->taint_regs[regid]>>off)&size_to_mask(size): env->taint_regs[regid]>>off; +#endif /* CONFIG_MIPS */ } /* addr: physical addr @@ -63,7 +68,7 @@ static inline int taint_mem(uint32_t addr,int size,uint8_t *taint) taint_memory_page_table[middle_node_index]->leaf[leaf_node_index]=fetch_leaf_node_from_pool(); leaf_node=taint_memory_page_table[middle_node_index]->leaf[leaf_node_index]; } - leaf_node->bitmap[(addr+i)&LEAF_ADDRESS_MASK]=((uint8_t*)(taint+i)); + leaf_node->bitmap[(addr+i)&LEAF_ADDRESS_MASK]=taint[i]; } return 1; } diff --git a/shared/tainting/tcg_taint.c b/shared/tainting/tcg_taint.c index d9a1dd0..15ca1b6 100644 --- a/shared/tainting/tcg_taint.c +++ b/shared/tainting/tcg_taint.c @@ -12,33 +12,65 @@ #include "tcg.h" #include "tainting/tcg_taint.h" -//#include "TEMU_main_internal.h" #include "tainting/taint_memory.h" #include "config-target.h" #include "helper.h" // Taint helper functions, plus I386 IN/OUT helpers +#include "tcg_taint_branch.h" + +//#define BLOCK_SKIP_GREATER_EQUAL 68 +//#define BLOCK_SKIP_LESS_EQUAL 66 +//#define ALLOW_BSLE 1 +//#define ALLOW_BSGE 1 /* Target-specific metadata buffers are extern'd here so that the taint IR insertions can update them. */ +#ifdef CONFIG_TCG_TAINT #if defined(TARGET_I386) extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; #elif defined(TARGET_ARM) extern uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE]; #endif /* TARGET_I386 */ +#endif /* CONFIG_TCG_TAINT */ uint16_t *gen_old_opc_ptr; TCGArg *gen_old_opparam_ptr; +uint32_t block_count = 0; // AWH - Debugging + // Typedef the CPU state struct to make tempidx ld/st cleaner #if defined(TARGET_I386) typedef CPUX86State OurCPUState; #elif defined(TARGET_ARM) typedef CPUARMState OurCPUState; +#elif defined(TARGET_MIPS) +typedef CPUMIPSState OurCPUState; #endif /* TARGET_I386/ARM */ -#define TCG_BITWISE_TAINT 1 // AWH - In development -// #define TCG_LOGGING_TAINT 1 +//#define TCG_LOGGING_TAINT 1 +//#define TCG_TAINT_BRANCHING 1 +#define USE_TCG_OPTIMIZATIONS 1 +//#define LOG_POINTER +#define LOG_TAINTED_EIP +// AWH - Change these to change taint/pointer rules +#define TAINT_EXPENSIVE_ADDSUB 1 +#define TCG_BITWISE_TAINT 1 +#define TAINT_NEW_POINTER 1 + +#if defined(LOG_POINTER) || defined(LOG_TAINTED_EIP) +#define MAX_TAINT_LOG_TEMPS 10 +static TCGArg helper_arg_array[MAX_TAINT_LOG_TEMPS]; +#define MAX_TAINT_LOG_TEMPS 10 +static TCGv taint_log_temps[MAX_TAINT_LOG_TEMPS]; +static inline void set_con_i32(int index, TCGv arg) +{ + + tcg_gen_mov_i32(taint_log_temps[index], arg); + helper_arg_array[index] = taint_log_temps[index]; +} + +#endif // Exposed externs TCGv shadow_arg[TCG_MAX_TEMPS]; @@ -47,10 +79,205 @@ TCGv tempidx, tempidx2; // Extern in translate.c extern TCGv_ptr cpu_env; +#ifdef TCG_TAINT_BRANCHING + +static int local_no_taint_label = 0; +static int local_complete_label = 0; + +#if 0 // AWH - In development +/* Basic Block node type for SSA transformation process */ +typedef struct BB_node { + /* First opcode/param for this BB node */ + unsigned int begin_opcode_offset; /* Opcode index where this BB starts */ + unsigned int begin_opparam_offset; /* Opparam index where this BB starts */ + /* Size of this node in opcodes/params */ + unsigned int num_opcodes; + unsigned int num_params; + /* Buffers to hold the opcodes/params */ + uint16_t opc_buffer[OPC_BUF_SIZE]; + TCGArg opparam_buffer[OPPARAM_BUF_SIZE]; + /* IDs of next node(s) (-1 if none) */ + signed int BB_fallthrough_index; + signed int BB_branch_index; + /* When we first construct the graph, we'll have references to labels that + we have not come across yet. If this node has a branch to a label, that + label number is recorded here. Later, once we've identified all of the + nodes, we'll sweep through each and resolve BB_branch_index to the + proper BB_node. This is -1 if there is no label being branched to. */ + signed int waiting_for_label; + /* Label for this BB (-1 if none) */ + signed int BB_label; +} BB_node_t; + +/* This is an array of the CFG nodes, so we can just traverse them without + having to follow links (for resolving labels). */ +#define MAX_BB_NODES 1024 +static BB_node_t *BB_node_list[MAX_BB_NODES]; + +/* Create a BB node */ +static inline BB_node_t *createBBNode(void) { + BB_node_t *new_node = (BB_node_t *)calloc(1, sizeof(BB_node_t)); + new_node->BB_fallthrough_index = -1; + new_node->BB_branch_index = -1; + new_node->waiting_for_label = -1; + new_node->BB_label = -1; +} + +/* Sweep through the current TB and construct the CFG */ +static void constructCFG(int nb_opc, uint16_t *opc_buf, uint32_t *opparam_buf) +{ + int i = 0, x = 0; + uint16_t opc; + int opparam_index = 0; + int opc_index = 0; + int current_BB_node_index = 0; + BB_node_t *current_node = NULL; + + + /* Reset the CFG to empty */ + for (i = 0; i < MAX_BB_NODES; i++) + { + if (BB_node_list[i]) + { + free(BB_node_list[i]); + BB_node_list[i] = NULL; + } + } + + /* Create the first node */ + current_node = createBBNode(); + BB_node_list[current_BB_node_index++] = current_node; + + /* Traverse the opcodes of the TB */ + for (i = 0; i < nb_opc; i++) { + opc = opc_buf[i]; + + /* Determine the number and type of arguments for the opcode */ + if (opc == INDEX_op_call) { + TCGArg arg = opparam_buf[opparam_index]; + nb_oargs = arg >> 16; + nb_iargs = arg & 0xffff; + nb_cargs = tcg_op_defs[opc].nb_cargs; + nb_args = nb_oargs + nb_iargs + nb_cargs + 1; + } else if (opc == INDEX_op_nopn) { + nb_args = nb_cargs = opparam_buf[opparam_index]; + nb_oargs = nb_iargs = 0; + } else { + nb_args = tcg_op_defs[opc].nb_args; + nb_oargs = tcg_op_defs[opc].nb_oargs; + nb_iargs = tcg_op_defs[opc].nb_iargs; + nb_cargs = tcg_op_defs[opc].nb_cargs; + + /* Start the logic that places ops and opparms into BBs */ + switch (opc) { + + /* These are the ops that conditionally END a BB with a label */ + case INDEX_op_brcond_i32: + case INDEX_op_local_brcond_i32: + case INDEX_op_brcond_i64: + case INDEX_op_local_brcond_i64 +#if (TCG_TARGET_REG_BITS == 32) + case INDEX_op_brcond2_i32: + case INDEX_op_local_brcond2_i32: +#endif /* TCG_TARGET_REG_BITS */ + /* Set up fallthrough link */ + current_node->BB_fallthrough_index = current_BB_node_index; + /* Set the label to resolve later */ + current_node->waiting_for_label = + /* Add op and opparms to current BB */ + current_node->opc_buffer[current_node->num_opcodes++] = opc; + for (x = 0; x < nb_args; x++) + current_node->opparam_buffer[current_node->num_opparams++] = opparam_buf[opparam_index++]; + /* Create a new node */ + current_node = createBBNode(); + BB_node_list[current_BB_node_index++] = current_node; + break; + + /* These are the ops that unconditionally END a BB with a label */ + case INDEX_op_br: + case INDEX_op_local_br: + current_node->waiting_for_label = + /* These are the ops that unconditionally END a BB without a label */ + case INDEX_op_goto_tb: + case INDEX_op_exit_tb: + case INDEX_op_jmp: + /* Add op and opparams to current BB */ + current_node->opc_buffer[current_node->num_opcodes++] = opc; + for (x = 0; x < nb_args; x++) + current_node->opparam_buffer[current_node->num_opparams++] = opparam_buf[opparam_index++]; + /* Create a new node */ + current_node = createBBNode(); + BB_node_list[current_BB_node_index++] = current_node; + break; + + /* Mark the BB with its start label*/ + case INDEX_op_set_label: + current_node->BB_label = opparam_buf[opparam_index]; + /* The default case (just store the op and opparms in the BB */ + default: + /* Add op and opparams to current BB */ + current_node->opc_buffer[current_node->num_opcodes++] = opc; + for (x = 0; x < nb_args; x++) + current_node->opparam_buffer[current_node->num_opparams++] = opparam_buf[opparam_index++]; + break; + } + } + } +} +#endif // AWH - In development + +static int cc_in_use = 0; +static int global_in_use = 0; +static int cond_used = 0; + +#if defined(TARGET_I386) +// AWH - Defined in target-i386/translate.c +extern TCGv cpu_cc_src, cpu_cc_dst, cpu_cc_tmp; +extern TCGv_i32 cpu_cc_op; +#endif /* TARGET_I386 */ + +static inline int check_global_arg(TCGv arg) +{ + return (arg < tcg_ctx.nb_globals); +} + +static inline int check_cc_arg(TCGv arg) +{ +#if defined(TARGET_I386) + if((arg == cpu_cc_src) || + (arg == cpu_cc_dst) || + (arg == cpu_cc_tmp) || + (arg == cpu_cc_op)) + return 1; + else + return 0; +#else +#error Implement this +#endif /* TARGET_I386 */ +} + +/* This holds our metadata for each temporary register to tell + whether it has been initialized (1) or is still uninitialized + (0). If a temporary is used as an input to an IR, it is + considered to be initialized. All global registers are + considered to be initialized at all times. */ +static uint8_t gen_opc_init_metadata[METADATA_SIZE]; +#endif /* TCG_TAINT_BRANCHING */ + +/* This holds out metadata for each opcode to tell whether to + override the liveness optimizer pass (in tcg/tcg.c) for that + opcode. Even if an opcode looks like it should be removed + according to the rules, it won't be removed if this is set (1) + for that opcode. If it is not set (0), the opcode is not immune + from the optimization logic and can be removed if needed. This + is necessary to avoid having it optimize out taint branching + opcode paths. This is shared out to tcg.c via an extern. */ +uint8_t gen_opc_opt_immune_metadata[METADATA_SIZE]; + #ifdef TCG_LOGGING_TAINT /* These are the number of temps that are created for the purpose of passing concrete values and registers into the taint logging helpers. */ -#define MAX_TAINT_LOG_TEMPS 10 +#define MAX_TAINT_LOG_TEMPS 12 static TCGv taint_log_temps[MAX_TAINT_LOG_TEMPS]; /* Used for building up lists of args for the logging helper funcs */ @@ -58,7 +285,14 @@ static TCGArg helper_arg_array[MAX_TAINT_LOG_TEMPS]; static inline void set_concrete_i32(int index, TCGv arg) { - if (tcg_ctx.temps[arg].val_type == TEMP_VAL_DEAD) + tcg_gen_mov_i32(taint_log_temps[index], arg); + helper_arg_array[index] = taint_log_temps[index]; +} + +static inline void set_concrete_LHS_i32(int index, TCGv arg) +{ + //if (tcg_ctx.temps[arg].val_type == TEMP_VAL_DEAD) + if (arg >= tcg_ctx.nb_globals) tcg_gen_movi_i32(taint_log_temps[index], 0); else tcg_gen_mov_i32(taint_log_temps[index], arg); @@ -72,7 +306,7 @@ static inline void set_arg_i32(int index, TCGv arg) } #endif /* TCG_LOGGING_TAINT */ -static TCGv find_shadow_arg(TCGv arg) +/*static*/ TCGv find_shadow_arg(TCGv arg) { if (arg < tcg_ctx.nb_globals) return shadow_arg[arg]; @@ -108,12 +342,13 @@ void clean_shadow_arg(void) shadow taint temps in place */ static void DUMMY_TAINT(int nb_oargs, int nb_args) { - TCGv arg0; + TCGv arg0, orig0; int i = 0; for (i = 0; i < nb_oargs; i++) { arg0 = find_shadow_arg(gen_opparam_ptr[(-1 * nb_args) + i]); + orig0 = gen_opparam_ptr[(-1 * nb_args) + i]; if (arg0) { #if TCG_TARGET_REG_BITS == 32 tcg_gen_movi_i32(arg0, 0); @@ -121,11 +356,26 @@ static void DUMMY_TAINT(int nb_oargs, int nb_args) tcg_gen_movi_i64(arg0, 0); #endif } +#ifdef TCG_TAINT_BRANCHING + orig0 = gen_opparam_ptr[(-1 * nb_args) + i]; + if (orig0) { + gen_opc_init_metadata[orig0] = 1; + } +#endif /* TCG_TAINT_BRANCHING */ } } +#ifdef USE_TCG_OPTIMIZATIONS +/* This holds our metadata for each of the original opcodes to + tell whether it will be elimintaed in liveness checks (0) or + will still remain alive (1) and must be instrumented. */ +static uint8_t gen_old_liveness_metadata[OPC_BUF_SIZE]; +static void build_liveness_metadata(TCGContext *s); +#endif /* USE_TCG_OPTIMIZATIONS */ + static inline int gen_taintcheck_insn(int search_pc) { +#ifdef CONFIG_TCG_TAINT /* Opcode and parameter buffers */ static uint16_t gen_old_opc_buf[OPC_BUF_SIZE]; static TCGArg gen_old_opparam_buf[OPPARAM_BUF_SIZE]; @@ -149,12 +399,12 @@ static inline int gen_taintcheck_insn(int search_pc) int nb_args=0; int opc_index=0, opparam_index=0; - int i=0; + int i=0, x=0; uint16_t opc=0; int nb_oargs=0, nb_iargs=0, nb_cargs=0; TCGv arg0, arg1, arg2, arg3, arg4, arg5, arg6; - TCGv t0, t1, t2, t3; - TCGv orig0, orig1, orig2; + TCGv t0, t1, t2, t3, t4, t_zero; + TCGv orig0, orig1, orig2, orig3, orig4, orig5; /* Copy all of the existing ops/parms into a new buffer to back them up. */ memcpy(gen_old_opc_buf, gen_old_opc_ptr, sizeof(uint16_t)*(nb_opc)); @@ -183,7 +433,7 @@ static inline int gen_taintcheck_insn(int search_pc) gen_opc_ptr = gen_old_opc_ptr; gen_opparam_ptr = gen_old_opparam_ptr; -#ifdef TCG_LOGGING_TAINT +#if defined(TCG_LOGGING_TAINT) || defined(LOG_POINTER) || defined(LOG_TAINTED_EIP) /* Allocate our temps for logging taint */ for (i=0; i < MAX_TAINT_LOG_TEMPS; i++) #if TCG_TARGET_REG_BITS == 32 @@ -193,6 +443,88 @@ static inline int gen_taintcheck_insn(int search_pc) #endif /* TCG_TARGET_REG_BITS */ #endif /* TCG_LOGGING_TAINT */ +#ifdef TCG_TAINT_BRANCHING + cc_in_use = 0; + global_in_use = 0; + cond_used = 0; + + /* Initialize the metadata that marks which registers + have been initialized. */ + for (i = 0; i < tcg_ctx.nb_globals; i++) + gen_opc_init_metadata[i] = 1; + for (i = tcg_ctx.nb_globals; i < METADATA_SIZE; i++) + gen_opc_init_metadata[i] = 0; +#if 0 // AWH + /* Determine if this TB uses a brcond variant in it. If so, + we should implement branching on this TB. */ + for (i=0; i < nb_opc; i++) + { + if (cond_used) break; + + /* Check if we're using CC flags in this TB. If so, don't + instrument this TB with jumps. */ + opc = gen_old_opc_buf[i]; + + /* Determine the number and type of arguments for the opcode */ + if (opc == INDEX_op_call) { + TCGArg arg = gen_old_opparam_buf[opparam_index]; + nb_oargs = arg >> 16; + nb_iargs = arg & 0xffff; + nb_cargs = tcg_op_defs[opc].nb_cargs; + nb_args = nb_oargs + nb_iargs + nb_cargs + 1; + } else if (opc == INDEX_op_nopn) { + nb_args = nb_cargs = gen_old_opparam_buf[opparam_index]; + nb_oargs = nb_iargs = 0; + } else { + nb_args = tcg_op_defs[opc].nb_args; + nb_oargs = tcg_op_defs[opc].nb_oargs; + nb_iargs = tcg_op_defs[opc].nb_iargs; + nb_cargs = tcg_op_defs[opc].nb_cargs; + + /* Are any of the input/output args CC flags? */ + for (x=0; x < nb_oargs; x++) if(check_cc_arg(gen_old_opparam_buf[opparam_index+x])) cond_used = 1; + //for (x=0; x < nb_iargs; x++) if(check_cc_arg(??)) cond_used = 1; + } + opparam_index += nb_args; + + /* Check if we're using brcond* in this TB. If so, don't + instrument this TB with jumps. */ + switch(opc) + { + case INDEX_op_brcond_i32: + //case INDEX_op_setcond_i32: +#if (TCG_TARGET_REG_BITS == 32) + case INDEX_op_brcond2_i32: + //case INDEX_op_setcond2_i32: +#endif /* TCG_TARGET_REG_BITS */ + case INDEX_op_brcond_i64: + cond_used = 1; + i = nb_opc; + break; + } + } + opparam_index = 0; + cond_used = 0; // AWH - Testing + //if (!cond_used) fprintf(stderr, "No cond_used in this TB\n"); + //else fprintf(stderr, "COND_USED in this TB\n"); +#endif /* Remove cond check for now */ +#endif /* TCG_TAINT_BRANCHING */ + + /* Initialize the metadata that marks which opcodes are + immune to being optimized out. By default, if TCG_TAINT_BRANCHING + is defined, none can be optimized out (all are set to 1). + As we copy in opcodes, if the gen_old_liveness_metadata + for the new opcode shows that it is 0 (this opcode would + be optimized out anyway), then we set this to 0. If + TCG_TAINT_BRANCHING is not defined, then all can be + optimized out (all are set to 0). */ + for (i=0; i < METADATA_SIZE; i++) +#ifdef TCG_TAINT_BRANCHING + gen_opc_opt_immune_metadata[i] = 1; +#else + gen_opc_opt_immune_metadata[i] = 0; +#endif /* TCG_TAINT_BRANCHING */ + /* Copy and instrument the opcodes that need taint tracking */ while(opc_index < nb_opc) { /* If needed, copy all of the appropriate metadata */ @@ -239,6 +571,18 @@ static inline int gen_taintcheck_insn(int search_pc) entries we need to put in the metadata buffers to keep everything in sync. */ gen_old_opc_ptr = gen_opc_ptr; +#ifdef USE_TCG_OPTIMIZATIONS + /* Liveness check: If the opcode that we are going to instrument + will be eliminated in a later liveness check (according to the + metadata held in gen_old_liveness_metadata), then we won't + instrument it. */ + if(!gen_old_liveness_metadata[opc_index-1]) { + /* Tell the REAL optimizer pass in tcg/tcg.c that it is OK + to optimize this opcode out. */ + gen_opc_opt_immune_metadata[opc_index-1] = 0; + goto skip_instrumentation; + } +#endif /* USE_TCG_OPTIMIZATIONS */ switch(opc) { @@ -263,10 +607,16 @@ static inline int gen_taintcheck_insn(int search_pc) break; case INDEX_op_discard: // Remove associated shadow reg + orig0 = gen_opparam_ptr[-1]; arg0 = find_shadow_arg(gen_opparam_ptr[-1]); if (arg0) { tcg_gen_discard_tl(arg0); } +#ifdef TCG_TAINT_BRANCHING + /* LHS now uninitialized */ + if (orig0 >= tcg_ctx.nb_globals) + gen_opc_init_metadata[orig0] = 0; +#endif /* TCG_TAINT_BRANCHING */ break; case INDEX_op_call: // Always bit taint @@ -303,12 +653,10 @@ static inline int gen_taintcheck_insn(int search_pc) t0 = tcg_temp_new_i32(); tcg_gen_movi_i32(t0, 0); tcg_gen_st_tl(t0, cpu_env, offsetof(OurCPUState,tempidx)); - //tcg_temp_free_i32(t0); #else t0 = tcg_temp_new_i64(); tcg_gen_movi_i64(t0, 0); tcg_gen_st_tl(t0, cpu_env, offsetof(OurCPUState,tempidx)); - //tcg_temp_free_i64(t0); #endif /* TARGET_REG_BITS == 32 */ } // Manually insert the CALL opcode @@ -331,6 +679,7 @@ static inline int gen_taintcheck_insn(int search_pc) + i /* Skip to the output parm that we are interested in */ ]); if (arg0) { + orig0 = gen_opparam_ptr[(-1 * nb_args) + 1 + i]; // Check if this is a call to an IN helper function. // If so, we grab the tempidx after the function call. #ifdef TARGET_I386 @@ -340,6 +689,10 @@ static inline int gen_taintcheck_insn(int search_pc) } else #endif /* TARGET_I386 */ tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } } break; @@ -352,31 +705,70 @@ static inline int gen_taintcheck_insn(int search_pc) arg1 = find_shadow_arg(gen_opparam_ptr[-4]); // Input1 arg2 = find_shadow_arg(gen_opparam_ptr[-3]); // Input2 - // Pull out the two constant parameters - pos = gen_opparam_ptr[-2]; // Position of mask - len = gen_opparam_ptr[-1]; // Length of mask -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + /* Store opcode parms */ orig0 = gen_opparam_ptr[-5]; orig1 = gen_opparam_ptr[-4]; orig2 = gen_opparam_ptr[-3]; + pos = gen_opparam_ptr[-2]; // Position of mask + len = gen_opparam_ptr[-1]; // Length of mask + + /* Rewind the instruction stream */ gen_opparam_ptr -= 5; gen_opc_ptr--; + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_DEPOSIT_I32 + local_no_taint_label = gen_new_label(); + local_complete_label = gen_new_label(); + t0 = tcg_temp_new_i32(); + t1 = tcg_temp_new_i32(); + + /* Has LHS has been initialized? */ + if (!gen_opc_init_metadata[orig0]) { + if (arg1 && arg2) + tcg_gen_or_i32(t0, arg1, arg2); + else if (arg1) + tcg_gen_mov_i32(t0, arg1); + else if (arg2) + tcg_gen_mov_i32(t0, arg2); + else + tcg_gen_movi_i32(t0, 0); + } else { + if (arg1 && arg2) { + tcg_gen_or_i32(t1, arg0, arg1); + tcg_gen_or_i32(t0, t1, arg2); + } + else if (arg1) + tcg_gen_or_i32(t0, arg0, arg1); + else if (arg2) + tcg_gen_or_i32(t0, arg0, arg2); + else + tcg_gen_mov_i32(t0, arg0); + } + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + /* Skip logging/instrumentation if LHS and RHS don't have taint */ + tcg_gen_local_brcond_i32(TCG_COND_EQ, t0, t_zero, local_no_taint_label); +#endif /* BRANCH_DEPOSIT_I32 */ +#endif /* TCG_TAINT_BRANCHING */ + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_DEPOSIT_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); set_arg_i32(3, pos); set_arg_i32(4, len); - set_concrete_i32(5, arg0); - set_concrete_i32(6, arg1); - set_concrete_i32(7, arg2); + //set_concrete_LHS_i32(5, arg0); + set_concrete_i32(5, arg1); + set_concrete_i32(6, arg2); - tcg_gen_helperN(helper_taint_log_deposit_i32, 0, 0, TCG_CALL_DUMMY_ARG, 8, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_deposit_i32(orig0, orig1, orig2, pos, len); + tcg_gen_helperN(helper_taint_log_deposit_i32, 0, 0, TCG_CALL_DUMMY_ARG, 7, helper_arg_array); +#endif /* LOG_DEPOSIT_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint IR */ // Handle special 32-bit transfer case (copy arg2 taint) if (len == 32) tcg_gen_mov_i32(arg0, arg2); @@ -386,6 +778,18 @@ static inline int gen_taintcheck_insn(int search_pc) // Handle general case else tcg_gen_deposit_tl(arg0, arg1, arg2, pos, len); +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_DEPOSIT_I32 + tcg_gen_local_br(local_complete_label); + gen_local_set_label(local_no_taint_label); + tcg_gen_movi_i32(arg0, 0); + gen_local_set_label(local_complete_label); +#endif /* BRANCH_DEPOSIT_I32 */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + + /* Reinsert the original IR */ + tcg_gen_deposit_i32(orig0, orig1, orig2, pos, len); } break; @@ -397,16 +801,21 @@ static inline int gen_taintcheck_insn(int search_pc) arg2 = find_shadow_arg(gen_opparam_ptr[-4]); // Input1 high arg3 = find_shadow_arg(gen_opparam_ptr[-3]); // Input2 low arg4 = find_shadow_arg(gen_opparam_ptr[-2]); // Input2 high -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + + /* Store opcode parms */ orig0 = gen_opparam_ptr[-6]; orig1 = gen_opparam_ptr[-5]; orig2 = gen_opparam_ptr[-4]; orig3 = gen_opparam_ptr[-3]; orig4 = gen_opparam_ptr[-2]; orig5 = gen_opparam_ptr[-1]; + + /* Rewind the instruction stream */ gen_opparam_ptr -= 6; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_SETCOND2_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); @@ -414,16 +823,17 @@ static inline int gen_taintcheck_insn(int search_pc) set_arg_i32(3, orig3); set_arg_i32(4, orig4); set_arg_i32(5, orig5); + //set_concrete_LHS_i32(6, arg0); set_concrete_i32(6, arg1); set_concrete_i32(7, arg2); set_concrete_i32(8, arg3); set_concrete_i32(9, arg4); tcg_gen_helperN(helper_taint_log_setcond2_i32, 0, 0, TCG_CALL_DUMMY_ARG, 10, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_setcond2_i32(orig0, orig1, orig2, orig3, orig4, orig5); +#endif /* LOG_SETCOND2_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint IR */ // Combine high/low taint of Input 1 into t2 t2 = tcg_temp_new_i32(); if (arg1 && arg2) @@ -450,13 +860,18 @@ static inline int gen_taintcheck_insn(int search_pc) t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); tcg_gen_or_i32(t0, t2, t3); - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t1); // Reuse t2 + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); // Reuse t2 tcg_gen_neg_i32(arg0, t2); - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); - //tcg_temp_free_i32(t3); + +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + + /* Reinsert original opcode */ + tcg_gen_op6i_i32(INDEX_op_setcond2_i32, orig0, orig1, orig2, orig3, orig4, orig5); } break; #endif /* TCG_TARGET_REG_BITS */ @@ -482,21 +897,54 @@ static inline int gen_taintcheck_insn(int search_pc) //fprintf(stderr, "tcg_taint.c: movi_i32 out helper func\n"); } #endif /* TARGET_I386 */ -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + /* Store opcode parms */ orig0 = gen_opparam_ptr[-2]; orig1 = gen_opparam_ptr[-1]; + + /* Rewind the instruction stream */ gen_opparam_ptr -= 2; gen_opc_ptr--; + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_MOVI_I32 + local_no_taint_label = gen_new_label(); + /* Skip logging/instrumentation if LHS has not yet been used */ + if (!gen_opc_init_metadata[orig0]) { + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; + tcg_gen_movi_i32(arg0, 0); + /* Reinsert original opcode */ + tcg_gen_movi_i32(orig0, orig1); + break; + } + + /* Skip logging/instrumentation if LHS doesn't have taint */ + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_local_brcond_i32(TCG_COND_EQ, arg0, t_zero, local_no_taint_label); +#endif /* BRANCH_MOVI_I32 */ +#endif /* TCG_TAINT_BRANCHING */ + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_MOVI_I32 /* Insert logging */ set_arg_i32(0, orig0); - set_concrete_i32(1, arg0); - tcg_gen_helperN(helper_taint_log_movi_i32, 0, 0, TCG_CALL_DUMMY_ARG, 2, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_movi_i32(orig0, orig1); + //set_concrete_LHS_i32(1, arg0); + tcg_gen_helperN(helper_taint_log_movi_i32, 0, 0, TCG_CALL_DUMMY_ARG, 1, helper_arg_array); +#endif /* LOG_MOVI_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint propagation */ tcg_gen_movi_i32(arg0, 0); + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_MOVI_I32 + gen_local_set_label(local_no_taint_label); +#endif /* BRANCH_MOVI_I32 */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_movi_i32(orig0, orig1); } break; @@ -504,26 +952,86 @@ static inline int gen_taintcheck_insn(int search_pc) arg0 = find_shadow_arg(gen_opparam_ptr[-2]); arg1 = find_shadow_arg(gen_opparam_ptr[-1]); if (arg0) { -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + /* Store opcode parms */ orig0 = gen_opparam_ptr[-2]; orig1 = gen_opparam_ptr[-1]; + + /* Rewind the instruction stream */ gen_opparam_ptr -= 2; gen_opc_ptr--; + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_MOV_I32 +#ifdef ALLOW_BSLE // AWH - DEBUG +if (block_count <= BLOCK_SKIP_LESS_EQUAL) goto skip1; +#endif // ALLOW_BSLE +#ifdef ALLOW_BSGE // AWH - DEBUG +if (block_count >= BLOCK_SKIP_GREATER_EQUAL) goto skip1; +#endif // ALLOW_BSGE +#if 1 // AWH - Custom skip +if (opc_index < 11) goto skip1; +#endif + local_no_taint_label = gen_new_label(); + local_complete_label = gen_new_label(); + //if (!cond_used) { + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + /* Has LHS has been initialized? */ + if (!gen_opc_init_metadata[orig0]) { + tcg_gen_local_brcond_i32(TCG_COND_EQ, arg1, t_zero, local_no_taint_label); + } else { + t0 = tcg_temp_new_i32(); + tcg_gen_or_i32(t0, arg0, arg1); + /* Skip logging/instrumentation if LHS and RHS don't have taint */ + tcg_gen_local_brcond_i32(TCG_COND_EQ, t0, t_zero, local_no_taint_label); + } + //} +skip1: + +#endif /* BRANCH_MOV_I32 */ +#endif /* TCG_TAINT_BRANCHING */ + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_MOV_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); - set_concrete_i32(2, arg0); - set_concrete_i32(3, arg1); - tcg_gen_helperN(helper_taint_log_mov_i32, 0, 0, TCG_CALL_DUMMY_ARG, 4, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_mov_i32(orig0, orig1); + //set_concrete_LHS_i32(2, arg0); + set_concrete_i32(2, arg1); + tcg_gen_helperN(helper_taint_log_mov_i32, 0, 0, TCG_CALL_DUMMY_ARG, 3, helper_arg_array); +#endif /* LOG_MOV_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint propagation */ - if (arg1) - tcg_gen_mov_i32(arg0, arg1); - else + tcg_gen_mov_i32(arg0, arg1); + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_MOV_I32 +#ifdef ALLOW_BSLE // AWH - DEBUG +if (block_count <= BLOCK_SKIP_LESS_EQUAL) goto skip2; +#endif // ALLOW_BSLE +#ifdef ALLOW_BSGE // AWH - DEBUG +if (block_count >= BLOCK_SKIP_GREATER_EQUAL) goto skip2; +#endif // ALLOW_BSGE +#if 1 // AWH - Custom skip +if (opc_index < 11) goto skip2; +#endif + //if (cond_used) { + // tcg_gen_movi_i32(arg0, 0); + //} else + //{ + tcg_gen_local_br(local_complete_label); + gen_local_set_label(local_no_taint_label); tcg_gen_movi_i32(arg0, 0); + gen_local_set_label(local_complete_label); + //} +#endif /* BRANCH_MOV_I32 */ +skip2: + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + + /* Reinsert original opcode */ + tcg_gen_mov_i32(orig0, orig1); } break; @@ -545,36 +1053,68 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { /* Patch qemu_ld* opcode into taint_qemu_ld* */ gen_opc_ptr[-1] += (INDEX_op_taint_qemu_ld8u - INDEX_op_qemu_ld8u); - + orig0 = gen_opparam_ptr[-3]; /* Are we doing pointer tainting? */ if (taint_load_pointers_enabled) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); + int addr = gen_opparam_ptr[-2]; if (arg1) { +#ifdef LOG_POINTER + set_con_i32(0, addr); + set_con_i32(1, arg1); + tcg_gen_helperN(helper_taint_log_pointer, 0, 0, TCG_CALL_DUMMY_ARG, 2, helper_arg_array); + +#endif + #if (TCG_TARGET_REG_BITS == 64) - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - t2 = tcg_temp_new_i64(); - t3 = tcg_temp_new_i64(); + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + t2 = tcg_temp_new_i64(); + t3 = tcg_temp_new_i64(); + + /* Load taint from tempidx */ + tcg_gen_ld32u_tl(t3, cpu_env, offsetof(OurCPUState,tempidx)); + +#ifndef TAINT_NEW_POINTER //more selective pointer tainting + /* Check for pointer taint */ + t_zero = tcg_temp_new_i64(); + tcg_gen_movi_i64(t_zero, 0); + tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t_zero); +#else + t4 = tcg_temp_new_i64(); + tcg_gen_movi_i64(t2, 0xffff0000); + tcg_gen_and_i64(t0, arg1, t2);//t0 = H_taint + tcg_gen_movi_i64(t2, 0); + tcg_gen_setcond_i64(TCG_COND_EQ, t1, t0, t2); //t1=(H_taint==0) cond1 + tcg_gen_setcond_i64(TCG_COND_NE, t4, arg1, t2); //t4=(P_taint!=0) cond2 + tcg_gen_and_i64(t2, t1, t4); //t2 = cond1 & cond2 +#endif + tcg_gen_neg_i64(t0, t2); + + /* Combine pointer and tempidx taint */ + tcg_gen_or_i64(arg0, t0, t3); - /* Load taint from tempidx */ - tcg_gen_ld32u_tl(t3, cpu_env, offsetof(OurCPUState,tempidx)); - /* Check for pointer taint */ - tcg_gen_movi_i64(t1, 0); - tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t1); - tcg_gen_neg_i64(t0, t2); - /* Combine pointer and tempidx taint */ - tcg_gen_or_i64(arg0, t0, t3); #else t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); t3 = tcg_temp_new_i32(); - /* Load taint from tempidx */ tcg_gen_ld_i32(t3, cpu_env, offsetof(OurCPUState,tempidx)); /* Check for pointer taint */ - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, arg1, t1); +#ifndef TAINT_NEW_POINTER + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, arg1, t_zero); +#else + t4 = tcg_temp_new_i32(); + tcg_gen_movi_i32(t2, 0xffff0000); //?? + tcg_gen_and_i32(t0, arg1, t2);//t0 = H_taint + tcg_gen_movi_i32(t2, 0); + tcg_gen_setcond_i32(TCG_COND_EQ, t1, t0, t2); //t1=(H_taint==0) cond1 + tcg_gen_setcond_i32(TCG_COND_NE, t4, arg1, t2); //t4=(P_taint!=0) cond2 + tcg_gen_and_i32(t2, t1, t4); //t2 = cond1 & cond2 +#endif tcg_gen_neg_i32(t0, t2); /* Combine pointer and tempidx taint */ tcg_gen_or_i32(arg0, t0, t3); @@ -585,6 +1125,10 @@ static inline int gen_taintcheck_insn(int search_pc) } else /* Patch in opcode to load taint from tempidx */ tcg_gen_ld_i32(arg0, cpu_env, offsetof(OurCPUState,tempidx)); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; @@ -605,14 +1149,15 @@ static inline int gen_taintcheck_insn(int search_pc) t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); t3 = tcg_temp_new_i32(); - + /* Load taint from tempidx */ tcg_gen_ld_i32(t2, cpu_env, offsetof(OurCPUState,tempidx)); tcg_gen_ld_i32(t3, cpu_env, offsetof(OurCPUState, tempidx2)); /* Check for pointer taint */ - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, arg2, t0); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, arg2, t_zero); tcg_gen_neg_i32(t0, t1); /* Combine pointer and tempidx taint */ @@ -621,10 +1166,6 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg1) tcg_gen_or_i32(arg1, t0, t3); - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); - //tcg_temp_free_i32(t3); } else { /* Patch in opcode to load taint from tempidx */ if (arg0) @@ -658,17 +1199,13 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_ld_i64(t3, cpu_env, offsetof(OurCPUState,tempidx)); /* Check for pointer taint */ - tcg_gen_movi_i64(t1, 0); - tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t1); + t_zero = tcg_temp_new_i64(); + tcg_gen_movi_i64(t_zero, 0); + tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t_zero); tcg_gen_neg_i64(t0, t2); /* Combine pointer and tempidx taint */ tcg_gen_or_i64(arg0, t0, t3); - - //tcg_temp_free_i64(t0); - //tcg_temp_free_i64(t1); - //tcg_temp_free_i64(t2); - //tcg_temp_free_i64(t3); } else /* Patch in opcode to load taint from tempidx */ tcg_gen_ld_i64(arg0, cpu_env, offsetof(OurCPUState,tempidx)); @@ -682,9 +1219,18 @@ static inline int gen_taintcheck_insn(int search_pc) #endif // FIXME break; +#if 1 // AWH - DEBUG + case INDEX_op_qemu_st32: + //DUMMY_TAINT(nb_oargs, nb_args); + //break; + + case INDEX_op_qemu_st8: + case INDEX_op_qemu_st16: +#else case INDEX_op_qemu_st8: case INDEX_op_qemu_st16: case INDEX_op_qemu_st32: +#endif // AWH // TARGET_REG_BITS = 64 OR (TARGET_REG_BITS = 32, TARGET_LONG_BITS = 32) if (nb_iargs == 2) { arg0 = find_shadow_arg(gen_opparam_ptr[-3]); @@ -695,21 +1241,22 @@ static inline int gen_taintcheck_insn(int search_pc) int addr = gen_opparam_ptr[-2]; int ret = gen_opparam_ptr[-3]; int ir = gen_opc_ptr[-1]; - /* Back up to insert a new IR on top of the qemu_st* */ gen_opc_ptr--; gen_opparam_ptr -= 3; if (taint_store_pointers_enabled) { if (arg1) { + #if (TCG_TARGET_REG_BITS == 64) t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); t2 = tcg_temp_new_i64(); - + /* Check for pointer taint */ - tcg_gen_movi_i64(t1, 0); - tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t1); + t_zero = tcg_temp_new_i64(); + tcg_gen_movi_i64(t_zero, 0); + tcg_gen_setcond_i64(TCG_COND_NE, t2, arg1, t_zero); tcg_gen_neg_i64(t0, t2); /* Combine pointer and data taint */ tcg_gen_or_i64(t1, t0, arg0); @@ -719,16 +1266,18 @@ static inline int gen_taintcheck_insn(int search_pc) t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); - + /* Check for pointer taint */ - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, arg1, t1); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, arg1, t_zero); tcg_gen_neg_i32(t0, t2); /* Combine pointer and data taint */ tcg_gen_or_i32(t1, t0, arg0); /* Store combined taint to tempidx */ tcg_gen_st32_tl(t1, cpu_env, offsetof(OurCPUState,tempidx)); #endif /* TARGET_REG_BITS */ + } else tcg_gen_st32_tl(arg0, cpu_env, offsetof(OurCPUState,tempidx)); } else @@ -898,26 +1447,30 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-3]); // Input1 arg2 = find_shadow_arg(gen_opparam_ptr[-2]); // Input2 -#ifdef TCG_LOGGING_TAINT + /* Store opcode and parms and back up */ orig0 = gen_opparam_ptr[-4]; orig1 = gen_opparam_ptr[-3]; orig2 = gen_opparam_ptr[-2]; orig3 = gen_opparam_ptr[-1]; + + /* Rewind instruction stream */ gen_opparam_ptr -= 4; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_DEPOSIT_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); set_arg_i32(3, orig3); - set_concrete_i32(4, arg0); - set_concrete_i32(5, arg1); - set_concrete_i32(6, arg2); + //set_concrete_LHS_i32(4, arg0); + set_concrete_i32(4, arg1); + set_concrete_i32(5, arg2); - tcg_gen_helperN(helper_taint_log_setcond_i32, 0, 0, TCG_CALL_DUMMY_ARG, 7, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_setcond_i32(orig0, orig1, orig2, orig3); + tcg_gen_helperN(helper_taint_log_setcond_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); +#endif /* LOG_DEPOSIT_I32 */ #endif /* TCG_LOGGING_TAINT */ if (arg1 && arg2) { @@ -931,24 +1484,33 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_mov_i32(t0, arg2); } else { tcg_gen_mov_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_setcond_i32(orig0, orig1, orig2, orig3); break; } // Determine if there is any taint t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); - - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t1); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); tcg_gen_neg_i32(arg0, t2); - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + + /* Reinsert original opcode */ + tcg_gen_setcond_i32(orig0, orig1, orig2, orig3); } break; -#ifdef TCG_BITWISE_TAINT /* IN MEMCHECK (VALGRIND), LOOK AT: memcheck/mc_translate.c expr2vbits_Binop(), expr2vbits_Unop() */ case INDEX_op_shl_i32: // Special - scalarShift() @@ -956,28 +1518,39 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig2 = gen_opparam_ptr[-1]; -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + + /* Store opcode parms */ orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind instruction stream */ gen_opparam_ptr -= 3; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_SHL_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); - set_concrete_i32(3, arg0); - set_concrete_i32(4, arg1); - set_concrete_i32(5, arg2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); - tcg_gen_helperN(helper_taint_log_shl_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_shl_i32(orig0, orig1, orig2); + tcg_gen_helperN(helper_taint_log_shl_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_SHL_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_shl_i32(orig0, orig1, orig2); break; } @@ -988,8 +1561,9 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg2) { // Check if the shift amount (arg2) is tainted. If so, the // entire result will be tainted. - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, t0, arg2); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, t_zero, arg2); tcg_gen_neg_i32(t2, t1); } else tcg_gen_movi_i32(t2, 0); @@ -1001,6 +1575,12 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_or_i32(arg0, t0, t2); } else tcg_gen_mov_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_shl_i32(orig0, orig1, orig2); } break; @@ -1009,28 +1589,39 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig2 = gen_opparam_ptr[-1]; -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + + /* Store opcode parms */ orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind instruction stream */ gen_opparam_ptr -= 3; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_SHR_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); - set_concrete_i32(3, arg0); - set_concrete_i32(4, arg1); - set_concrete_i32(5, arg2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); - tcg_gen_helperN(helper_taint_log_shr_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_shr_i32(orig0, orig1, orig2); + tcg_gen_helperN(helper_taint_log_shr_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_SHR_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_shr_i32(orig0, orig1, orig2); break; } @@ -1041,8 +1632,9 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg2) { // Check if the shift amount (arg2) is tainted. If so, the // entire result will be tainted. - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, t0, arg2); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, t_zero, arg2); tcg_gen_neg_i32(t2, t1); } else tcg_gen_movi_i32(t2, 0); @@ -1054,6 +1646,12 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_or_i32(arg0, t0, t2); } else tcg_gen_mov_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_shr_i32(orig0, orig1, orig2); } break; @@ -1061,29 +1659,40 @@ static inline int gen_taintcheck_insn(int search_pc) arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); - arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig2 = gen_opparam_ptr[-1]; -#ifdef TCG_LOGGING_TAINT - /* Store opcode and parms and back up */ + arg2 = find_shadow_arg(gen_opparam_ptr[-1]); + + /* Store opcode parms */ orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind the instruction stream */ gen_opparam_ptr -= 3; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_SAR_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); - set_concrete_i32(3, arg0); - set_concrete_i32(4, arg1); - set_concrete_i32(5, arg2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); - tcg_gen_helperN(helper_taint_log_sar_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_sar_i32(orig0, orig1, orig2); + tcg_gen_helperN(helper_taint_log_sar_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_SAR_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_sar_i32(orig0, orig1, orig2); break; } @@ -1094,8 +1703,9 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg2) { // Check if the shift amount (arg2) is tainted. If so, the // entire result will be tainted. - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, t0, arg2); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, t_zero, arg2); tcg_gen_neg_i32(t2, t1); } else tcg_gen_movi_i32(t2, 0); @@ -1107,6 +1717,12 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_or_i32(arg0, t0, t2); } else tcg_gen_mov_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_sar_i32(orig0, orig1, orig2); } break; @@ -1116,28 +1732,39 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig2 = gen_opparam_ptr[-1]; -#ifdef TCG_LOGGING_TAINT + /* Store opcode and parms and back up */ orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind the instruction stream */ gen_opparam_ptr -= 3; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_ROTL_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); - set_concrete_i32(3, arg0); - set_concrete_i32(4, arg1); - set_concrete_i32(5, arg2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); - tcg_gen_helperN(helper_taint_log_rotl_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_rotl_i32(orig0, orig1, orig2); + tcg_gen_helperN(helper_taint_log_rotl_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_ROTL_I32 */ #endif /* TCG_LOGGING_TAINT */ - + + /* Insert tainting IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_rotl_i32(orig0, orig1, orig2); break; } @@ -1148,8 +1775,9 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg2) { // Check if the shift amount (arg2) is tainted. If so, the // entire result will be tainted. - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, t0, arg2); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, t_zero, arg2); tcg_gen_neg_i32(t2, t1); } else tcg_gen_movi_i32(t2, 0); @@ -1161,6 +1789,12 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_or_i32(arg0, t0, t2); } else tcg_gen_mov_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_rotl_i32(orig0, orig1, orig2); } break; @@ -1169,28 +1803,39 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig2 = gen_opparam_ptr[-1]; -#ifdef TCG_LOGGING_TAINT + /* Store opcode and parms and back up */ orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind instruction stream */ gen_opparam_ptr -= 3; gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_ROTR_I32 /* Insert logging */ set_arg_i32(0, orig0); set_arg_i32(1, orig1); set_arg_i32(2, orig2); - set_concrete_i32(3, arg0); - set_concrete_i32(4, arg1); - set_concrete_i32(5, arg2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); - tcg_gen_helperN(helper_taint_log_rotr_i32, 0, 0, TCG_CALL_DUMMY_ARG, 6, helper_arg_array); - /* Reinsert original opcode */ - tcg_gen_rotr_i32(orig0, orig1, orig2); + tcg_gen_helperN(helper_taint_log_rotr_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_ROTR_I32 */ #endif /* TCG_LOGGING_TAINT */ + /* Insert tainting IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_rotr_i32(orig0, orig1, orig2); break; } t0 = tcg_temp_new_i32(); @@ -1200,8 +1845,9 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg2) { // Check if the shift amount (arg2) is tainted. If so, the // entire result will be tainted. - tcg_gen_movi_i32(t0, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t1, t0, arg2); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t1, t_zero, arg2); tcg_gen_neg_i32(t2, t1); } else tcg_gen_movi_i32(t2, 0); @@ -1213,81 +1859,178 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_or_i32(arg0, t0, t2); } else tcg_gen_mov_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_rotr_i32(orig0, orig1, orig2); } break; #endif /* TCG_TARGET_HAS_rot_i32 */ -#if 0 // AWH - expensiveAddSub() for add_i32/or_i32 are buggy, use cheap one +#ifdef BITWISE_TAINT +#ifdef TAINT_EXPENSIVE_ADDSUB + // AWH - expensiveAddSub() for add_i32/or_i32 are buggy, use cheap one /* T0 = (T1 | T2) | ((V1_min + V2_min) ^ (V1_max + V2_max)) */ case INDEX_op_add_i32: // Special - expensiveAddSub() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { + //LOK: Changed the names of orig0 and orig 1 to orig1 and 2 + // so I don't get confused + // Basically arg is vxx and orig is x arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig0 = gen_opparam_ptr[-1]; + + //make sure we have a copy of the values first + orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + //delete the original operation + gen_opparam_ptr -= 3; + gen_opc_ptr--; + + + //LOK: Declared the new temporary variables that we need + t0 = tcg_temp_new_i32(); //scratch + t1 = tcg_temp_new_i32(); //a_min + t2 = tcg_temp_new_i32(); //b_min + t3 = tcg_temp_new_i32(); //a_max + t4 = tcg_temp_new_i32(); //b_max + /* Per the expensiveAddSub() logic: qaa = T1 = arg1 qbb = T2 = arg2 - aa = V1 = gen_opparam_ptr[-2] - bb = V2 = gen_opparam_ptr[-1] */ - tcg_gen_not_i32(t0, arg1); // ~T1 - tcg_gen_and_i32(t1, orig1, t0);//tcg_gen_and_i32(t1, gen_opparam_ptr[-2], t0); // V1 & ~T1 (a_min) - - tcg_gen_not_i32(t0, arg2); // ~T2 - tcg_gen_and_i32(t2, orig0, t0);//tcg_gen_and_i32(t2, gen_opparam_ptr[-1], t0); // V2 & ~T2 (b_min) + aa = V1 = orig1 + bb = V2 = orig2 */ - tcg_gen_or_i32(t3, orig1, arg1);//tcg_gen_or_i32(t3, gen_opparam_ptr[-2], arg1); // V1 | T1 (a_max) - tcg_gen_or_i32(t4, orig0, arg2);//tcg_gen_or_i32(t4, gen_opparam_ptr[-1], arg2); // V2 | T2 (b_max) - - tcg_gen_add_i32(t0, t3, t4); // a_max + b_max - tcg_gen_add_i32(t3, t1, t2); // a_min + b_min - tcg_gen_xor_i32(t1, t0, t3); // ((a_min + b_min)^(a_max + b_max)) - tcg_gen_or_i32(t0, t1, arg2); // T1 | all of that previous stuff - tcg_gen_or_i32(arg0, t0, arg1); // T2 | all of that previous stuff + //LOK: First lets calculate a_min = aa & ~qaa + tcg_gen_not_i32(t0, arg1); // ~qaa + tcg_gen_and_i32(t1, orig1, t0);//t1 = aa & ~qaa + + //LOK: Then calculate b_min + tcg_gen_not_i32(t0, arg2); // ~qbb + tcg_gen_and_i32(t2, orig2, t0);//t2 = bb & ~qbb + + //LOK: Then calculate a_max = aa | qaa + tcg_gen_or_i32(t3, orig1, arg1);//t3 = aa | qaa + tcg_gen_or_i32(t4, orig2, arg2);//t4 = bb | qbb + + //LOK: Now that we have the mins and maxes, we need to sum them + tcg_gen_add_i32(t0, t3, t4); // t0 = a_max + b_max + //LOK: Note that t3 is being reused in this case + tcg_gen_add_i32(t3, t1, t2); // t3 = a_min + b_min + tcg_gen_xor_i32(t1, t0, t3); // t1 = ((a_min + b_min)^(a_max + b_max)) + tcg_gen_or_i32(t0, arg1, arg2); // t0 = qa | qb + tcg_gen_or_i32(arg0, t0, t1); // arg0 = (qa | qb) | ( (a_min + b_min) ^ (a_max + b_max) + //put the original operation back + tcg_gen_add_i32(orig0, orig1, orig2); } break; /* T0 = (T1 | T2) | ((V1_min - V2_max) ^ (V1_max - V2_min)) */ case INDEX_op_sub_i32: // Special - expensiveAddSub() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { + //NOTE: It is important that we get the order of the operands correct + // Right now, the assumption is + // arg0 = arg1 - arg2 + // If there are errors - this could be the culprit + + //LOK: Changed the names of orig0 and orig 1 to orig1 and 2 + // so I don't get confused + // Basically arg is vxx and orig is x arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig0 = [-1]; + + //make sure we have a copy of the values first + orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + //delete the original operation + gen_opparam_ptr -= 3; + gen_opc_ptr--; + + //LOK: Declared the new temporary variables that we need + t0 = tcg_temp_new_i32(); //scratch + t1 = tcg_temp_new_i32(); //a_min + t2 = tcg_temp_new_i32(); //b_min + t3 = tcg_temp_new_i32(); //a_max + t4 = tcg_temp_new_i32(); //b_max /* Per the expensiveAddSub() logic: qaa = T1 = arg1 qbb = T2 = arg2 - aa = V1 = gen_opparam_ptr[-2] - bb = V2 = gen_opparam_ptr[-1] */ - tcg_gen_not_i32(t0, arg1); // ~T1 - tcg_gen_and_i32(t1, orig1, t0);//tcg_gen_and_i32(t1, gen_opparam_ptr[-2], t0); // V1 & ~T1 (a_min) - - tcg_gen_not_i32(t0, arg2); // ~T2 - tcg_gen_and_i32(t2, orig0, t0);//tcg_gen_and_i32(t2, gen_opparam_ptr[-1], t0); // V2 & ~T2 (b_min) + aa = V1 = orig1 + bb = V2 = orig2 */ - tcg_gen_or_i32(t3, orig1, arg1);//tcg_gen_or_i32(t3, gen_opparam_ptr[-2], arg1); // V1 | T1 (a_max) - tcg_gen_or_i32(t4, orig0, arg2);//tcg_gen_or_i32(t4, gen_opparam_ptr[-1], arg2); // V2 | T2 (b_max) - - tcg_gen_sub_i32(t0, t1, t4); // a_min - b_max - tcg_gen_sub_i32(t3, t3, t2); // a_max - b_min - tcg_gen_xor_i32(t1, t0, t3); // ((a_min - b_max)^(a_max - b_min)) - tcg_gen_or_i32(t0, t1, arg2); // T1 | all of that previous stuff - tcg_gen_or_i32(arg0, t0, arg1); // T2 | all of that previous stuff + //LOK: First lets calculate a_min = aa & ~qaa + tcg_gen_not_i32(t0, arg1); // ~qaa + tcg_gen_and_i32(t1, orig1, t0);//t1 = aa & ~qaa + + //LOK: Then calculate b_min + tcg_gen_not_i32(t0, arg2); // ~qbb + tcg_gen_and_i32(t2, orig2, t0);//t2 = bb & ~qbb + + //LOK: Then calculate a_max = aa | qaa + tcg_gen_or_i32(t3, orig1, arg1);//t3 = aa | qaa + tcg_gen_or_i32(t4, orig2, arg2);//t4 = bb | qbb + + //LOK: Now that we have the mins and maxes, we need to find the differences + //NOTE: This is why the order of the operands is important + tcg_gen_sub_i32(t0, t1, t4); // t0 = a_min - b_max + //LOK: Note that t3 is being reused in this case + tcg_gen_sub_i32(t4, t3, t2); // t4 = a_max - b_min + tcg_gen_xor_i32(t1, t0, t4); // t1 = ((a_min - b_max)^(a_max - b_min)) + tcg_gen_or_i32(t0, arg1, arg2); // t0 = qa | qb + tcg_gen_or_i32(arg0, t0, t1); // arg0 = (qa | qb) | ( (a_min - b_max) ^ (a_max - b_min) + + //put the original operation back + tcg_gen_sub_i32(orig0, orig1, orig2); } break; -#endif // AWH + // AWH +#else case INDEX_op_add_i32: // Up - cheap_AddSub32 case INDEX_op_sub_i32: // Up - cheap_AddSub32 +#endif case INDEX_op_mul_i32: // Up - mkUifU32(), mkLeft32(), mkPCastTo() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); + /* Store opcode and parms and back up */ + orig0 = gen_opparam_ptr[-3]; + orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + /* Rewind instruction stream */ + gen_opparam_ptr -= 3; + gen_opc_ptr--; + +#ifdef TCG_LOGGING_TAINT +#ifdef LOG_MUL_I32 + /* Insert logging */ + set_arg_i32(0, orig0); + set_arg_i32(1, orig1); + set_arg_i32(2, orig2); + //set_concrete_LHS_i32(3, arg0); + set_concrete_i32(3, arg1); + set_concrete_i32(4, arg2); + + tcg_gen_helperN(helper_taint_log_mul_i32, 0, 0, TCG_CALL_DUMMY_ARG, 5, helper_arg_array); +#endif /* LOG_MUL_I32 */ +#endif /* TCG_LOGGING_TAINT */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_mul_i32(orig0, orig1, orig2); break; } @@ -1304,6 +2047,12 @@ static inline int gen_taintcheck_insn(int search_pc) t1 = tcg_temp_new_i32(); tcg_gen_neg_i32(t1, t0); // (-s32) tcg_gen_or_i32(arg0, t0, t1); // (s32 | (-s32)) -> vLo32 +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_mul_i32(orig0, orig1, orig2); } break; @@ -1320,17 +2069,54 @@ static inline int gen_taintcheck_insn(int search_pc) if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); + + /* Store opcode parms */ orig0 = gen_opparam_ptr[-1];//V1 orig1 = gen_opparam_ptr[-2];//V2 - if (!arg1 && !arg2) { - tcg_gen_movi_i32(arg0, 0); - break; - } + orig2 = gen_opparam_ptr[-3]; + + /* Rewind instruction stream */ + gen_opparam_ptr -= 3; + gen_opc_ptr--; t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); t3 = tcg_temp_new_i32(); + +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_AND_I32 + local_no_taint_label = gen_new_label(); + local_complete_label = gen_new_label(); + + /* Has LHS has been initialized? */ + if (!gen_opc_init_metadata[orig2]) { + if (arg1 && arg2) + tcg_gen_or_i32(t0, arg1, arg2); + else if (arg1) + tcg_gen_mov_i32(t0, arg1); + else if (arg2) + tcg_gen_mov_i32(t0, arg2); + else + tcg_gen_movi_i32(t0, 0); + } else { + if (arg1 && arg2) { + tcg_gen_or_i32(t1, arg0, arg1); + tcg_gen_or_i32(t0, t1, arg2); + } + else if (arg1) + tcg_gen_or_i32(t0, arg0, arg1); + else if (arg2) + tcg_gen_or_i32(t0, arg0, arg2); + else + tcg_gen_mov_i32(t0, arg0); + } + /* Skip logging/instrumentation if LHS and RHS don't have taint */ + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_local_brcond_i32(TCG_COND_EQ, t0, t_zero, local_no_taint_label); +#endif /* BRANCH_AND_I32 */ +#endif /* TCG_TAINT_BRANCHING */ /* T1 -> arg1 V1 -> gen_opparam_ptr[-2] T2 -> arg2 @@ -1363,6 +2149,18 @@ static inline int gen_taintcheck_insn(int search_pc) // OR it all together tcg_gen_or_i32(t1, t2, t3); tcg_gen_or_i32(arg0, t0, t1); +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_AND_I32 + tcg_gen_local_br(local_complete_label); + gen_local_set_label(local_no_taint_label); + tcg_gen_movi_i32(arg0, 0); + gen_local_set_label(local_complete_label); +#endif /* BRANCH_AND_I32 */ + gen_opc_init_metadata[orig2] = 1; +#endif /* TCG_TAINT_BRANCHING */ + + /* Reinsert original opcode */ + tcg_gen_and_i32(orig2, orig1, orig0); } break; @@ -1381,15 +2179,35 @@ static inline int gen_taintcheck_insn(int search_pc) arg2 = find_shadow_arg(gen_opparam_ptr[-1]); orig0 = gen_opparam_ptr[-1];//V1 orig1 = gen_opparam_ptr[-2];//V2 - if (!arg1 && !arg2) { - tcg_gen_movi_i32(arg0, 0); - break; - } + orig2 = gen_opparam_ptr[-3]; + + /* Rewind instruction stream */ + gen_opparam_ptr -= 3; + gen_opc_ptr--; t0 = tcg_temp_new_i32(); t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); t3 = tcg_temp_new_i32(); +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_OR_I32 + local_no_taint_label = gen_new_label(); + local_complete_label = gen_new_label(); + + /* Has LHS has been initialized? */ + if (!gen_opc_init_metadata[orig2]) { + tcg_gen_or_i32(t0, arg1, arg2); + gen_opc_init_metadata[orig2] = 1; + } else { + tcg_gen_or_i32(t1, arg0, arg1); + tcg_gen_or_i32(t0, t1, arg2); + } + /* Skip logging/instrumentation if LHS and RHS don't have taint */ + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_local_brcond_i32(TCG_COND_EQ, t0, t_zero, local_no_taint_label); +#endif /* BRANCH_OR_I32 */ +#endif /* TCG_TAINT_BRANCHING */ /* T1 -> arg1 V1 -> gen_opparam_ptr[-2] T2 -> arg2 @@ -1422,10 +2240,20 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_mov_i32(t2, arg1); else if (arg2) tcg_gen_mov_i32(t2, arg2); - // OR it all together tcg_gen_or_i32(t3, t0, t1); tcg_gen_or_i32(arg0, t2, t3); +#ifdef TCG_TAINT_BRANCHING +#ifdef BRANCH_OR_I32 + tcg_gen_local_br(local_complete_label); + gen_local_set_label(local_no_taint_label); + tcg_gen_movi_i32(arg0, 0); + gen_local_set_label(local_complete_label); +#endif /* BRANCH_OR_I32 */ + gen_opc_init_metadata[orig2] = 1; +#endif /* TCG_TAINT_BRANCHING */ + /* Reinsert original opcode */ + tcg_gen_or_i32(orig2, orig1, orig0); } break; #else @@ -1438,22 +2266,11 @@ static inline int gen_taintcheck_insn(int search_pc) Step 3: temp2 = (temp0 != temp1) Step 4: arg0 = ~temp2 MemCheck: mkLazy2() for all of these */ - case INDEX_op_shl_i32: - case INDEX_op_shr_i32: - case INDEX_op_sar_i32: -#if TCG_TARGET_HAS_rot_i32 - case INDEX_op_rotl_i32: - case INDEX_op_rotr_i32: -#endif /* TCG_TARGET_HAS_rot_i32 */ case INDEX_op_add_i32: case INDEX_op_sub_i32: case INDEX_op_mul_i32: case INDEX_op_and_i32: case INDEX_op_or_i32: -#if 0 // DEBUG -DUMMY_TAINT(nb_oargs, nb_args); -break; -#else arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); @@ -1475,17 +2292,12 @@ break; } t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); - - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t1, t0); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t_zero, t0); tcg_gen_neg_i32(arg0, t2); - - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); } break; -#endif // DEBUG #endif /* TCG_BITWISE_TAINT */ case INDEX_op_mulu2_i32: // Bytewise, mkLazyN() arg0 = find_shadow_arg(gen_opparam_ptr[-4]); @@ -1493,7 +2305,12 @@ break; if (arg0 && arg1) { arg2 = find_shadow_arg(gen_opparam_ptr[-2]); arg3 = find_shadow_arg(gen_opparam_ptr[-1]); - + + orig0 = gen_opparam_ptr[-4]; + orig1 = gen_opparam_ptr[-3]; + orig2 = gen_opparam_ptr[-2]; + orig3 = gen_opparam_ptr[-1]; + if (arg2 && arg3) { t0 = tcg_temp_new_i32(); tcg_gen_or_i32(t0, arg2, arg3); @@ -1506,18 +2323,20 @@ break; } else { tcg_gen_movi_i32(arg0, 0); tcg_gen_movi_i32(arg1, 0); + break; //LOK: this is a bug - need to break it } t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); - - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t1); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; + gen_opc_init_metadata[orig1] = 1; +#endif /* TCG_TAINT_BRANCHING */ tcg_gen_neg_i32(arg0, t2); tcg_gen_neg_i32(arg1, t2); - - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); } break; @@ -1531,7 +2350,19 @@ break; arg4 = find_shadow_arg(gen_opparam_ptr[-2]); // Input2 low arg5 = find_shadow_arg(gen_opparam_ptr[-1]); // Input2 high + orig0 = gen_opparam_ptr[-6]; + orig1 = gen_opparam_ptr[-5]; + orig2 = gen_opparam_ptr[-4]; + orig3 = gen_opparam_ptr[-3]; + orig4 = gen_opparam_ptr[-2]; + orig5 = gen_opparam_ptr[-1]; + if (!(arg2 || arg3 || arg4 || arg5)) { +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; + gen_opc_init_metadata[orig1] = 1; +#endif /* TCG_TAINT_BRANCHING */ tcg_gen_movi_i32(arg0, 0); tcg_gen_movi_i32(arg1, 0); break; @@ -1564,15 +2395,16 @@ break; // Determine if there is any taint tcg_gen_or_i32(t0, t2, t3); - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t1); // Reuse t2 + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); // Reuse t2 tcg_gen_neg_i32(arg0, t2); tcg_gen_neg_i32(arg1, t2); - - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); - //tcg_temp_free_i32(t3); +#ifdef TCG_TAINT_BRANCHING + /* LHS now initialized */ + gen_opc_init_metadata[orig0] = 1; + gen_opc_init_metadata[orig1] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; @@ -1581,6 +2413,11 @@ break; if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); + + orig0 = gen_opparam_ptr[-3]; + orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + /* Perform an OR an arg1 and arg2 to find taint */ if (arg1 && arg2) tcg_gen_or_i32(arg0, arg1, arg2); @@ -1590,6 +2427,9 @@ break; tcg_gen_mov_i32(arg0, arg2); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; @@ -1602,7 +2442,11 @@ break; if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - + + orig0 = gen_opparam_ptr[-3]; + orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + if (arg1 && arg2) { t0 = tcg_temp_new_i32(); tcg_gen_or_i32(t0, arg1, arg2); @@ -1617,14 +2461,14 @@ break; } t1 = tcg_temp_new_i32(); t2 = tcg_temp_new_i32(); - - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t1); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); tcg_gen_neg_i32(arg0, t2); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ - //tcg_temp_free_i32(t0); - //tcg_temp_free_i32(t1); - //tcg_temp_free_i32(t2); } break; #elif TCG_TARGET_HAS_div2_i32 @@ -1636,9 +2480,20 @@ break; arg2 = find_shadow_arg(gen_opparam_ptr[-3]); arg3 = find_shadow_arg(gen_opparam_ptr[-2]); arg4 = find_shadow_arg(gen_opparam_ptr[-1]); + + orig0 = gen_opparam_ptr[-5]; + orig1 = gen_opparam_ptr[-4]; + orig2 = gen_opparam_ptr[-3]; + orig3 = gen_opparam_ptr[-2]; + orig4 = gen_opparam_ptr[-1]; + /* No shadows for any inputs */ if (!(arg2 || arg3 || arg4)) { +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; + gen_opc_init_metadata[orig1] = 1; +#endif /* TCG_TAINT_BRANCHING */ tcg_gen_movi_i32(arg0, 0); tcg_gen_movi_i32(arg1, 0); break; @@ -1663,10 +2518,15 @@ break; else tcg_gen_mov_i32(t2, t0); - tcg_gen_movi_i32(t1, 0); - tcg_gen_setcond_i32(TCG_COND_NE, t0, t2, t1); + t_zero = tcg_temp_new_i32(); + tcg_gen_movi_i32(t_zero, 0); + tcg_gen_setcond_i32(TCG_COND_NE, t0, t2, t_zero); tcg_gen_neg_i32(arg0, t0); tcg_gen_neg_i32(arg1, t0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; + gen_opc_init_metadata[orig1] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_div*_i32 */ @@ -1676,10 +2536,15 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; if (arg1) tcg_gen_ext8s_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_ext8s_i32 */ @@ -1688,10 +2553,15 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; if (arg1) tcg_gen_ext16s_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_ext16s_i32 */ @@ -1700,10 +2570,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_ext8u_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_ext8u_i32 */ @@ -1712,10 +2588,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_ext16u_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_ext16u_i32 */ @@ -1724,10 +2606,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_bswap16_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_bswap16_i32 */ @@ -1736,10 +2624,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_bswap32_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_bswap32_i32 */ @@ -1748,10 +2642,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_mov_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; #endif /* TCG_TARGET_HAS_not_i32 */ @@ -1760,10 +2660,16 @@ break; arg0 = find_shadow_arg(gen_opparam_ptr[-2]); if (arg0) { arg1 = find_shadow_arg(gen_opparam_ptr[-1]); + orig0 = gen_opparam_ptr[-2]; + orig1 = gen_opparam_ptr[-1]; + if (arg1) tcg_gen_mov_i32(arg0, arg1); else tcg_gen_movi_i32(arg0, 0); +#ifdef TCG_TAINT_BRANCHING + gen_opc_init_metadata[orig0] = 1; +#endif /* TCG_TAINT_BRANCHING */ } break; @@ -2003,35 +2909,61 @@ break; } break; #endif /* TCG_TARGET_HAS_rot_i64 */ -#if 0 // AWH - expensiveAddSub() for add_i64/or_i64 are buggy, use cheap one + // AWH - expensiveAddSub() for add_i64/or_i64 are buggy, use cheap one /* T0 = (T1 | T2) | ((V1_min + V2_min) ^ (V1_max + V2_max)) */ case INDEX_op_add_i64: // Special - expensiveAddSub() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { + //LOK: Changed the names of orig0 and orig 1 to orig1 and 2 + // so I don't get confused + // Basically arg is vxx and orig is x arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig0 = gen_opparam_ptr[-1]; + + //make sure we have a copy of the values first + orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + //delete the original operation + gen_opparam_ptr -= 3; + gen_opc_ptr--; + + //LOK: Declared the new temporary variables that we need + t0 = tcg_temp_new_i64(); //scratch + t1 = tcg_temp_new_i64(); //a_min + t2 = tcg_temp_new_i64(); //b_min + t3 = tcg_temp_new_i64(); //a_max + t4 = tcg_temp_new_i64(); //b_max /* Per the expensiveAddSub() logic: qaa = T1 = arg1 qbb = T2 = arg2 - aa = V1 = gen_opparam_ptr[-2] - bb = V2 = gen_opparam_ptr[-1] */ - tcg_gen_not_i64(t0, arg1); // ~T1 - tcg_gen_and_i64(t1, orig1, t0);//tcg_gen_and_i64(t1, gen_opparam_ptr[-2], t0); // V1 & ~T1 (a_min) - - tcg_gen_not_i64(t0, arg2); // ~T2 - tcg_gen_and_i64(t2, orig0, t0);//tcg_gen_and_i64(t2, gen_opparam_ptr[-1], t0); // V2 & ~T2 (b_min) - - tcg_gen_or_i64(t3, orig1, arg1);//tcg_gen_or_i64(t3, gen_opparam_ptr[-2], arg1); // V1 | T1 (a_max) - tcg_gen_or_i64(t4, orig0, arg2);//tcg_gen_or_i64(t4, gen_opparam_ptr[-1], arg2); // V2 | T2 (b_max) + aa = V1 = orig1 + bb = V2 = orig2 */ - tcg_gen_add_i64(t0, t3, t4); // a_max + b_max - tcg_gen_add_i64(t3, t1, t2); // a_min + b_min - tcg_gen_xor_i64(t1, t0, t3); // ((a_min + b_min)^(a_max + b_max)) - tcg_gen_or_i64(t0, t1, arg2); // T1 | all of that previous stuff - tcg_gen_or_i64(arg0, t0, arg1); // T2 | all of that previous stuff + //LOK: First lets calculate a_min = aa & ~qaa + tcg_gen_not_i64(t0, arg1); // ~qaa + tcg_gen_and_i64(t1, orig1, t0);//t1 = aa & ~qaa + + //LOK: Then calculate b_min + tcg_gen_not_i64(t0, arg2); // ~qbb + tcg_gen_and_i64(t2, orig2, t0);//t2 = bb & ~qbb + + //LOK: Then calculate a_max = aa | qaa + tcg_gen_or_i64(t3, orig1, arg1);//t3 = aa | qaa + tcg_gen_or_i64(t4, orig2, arg2);//t4 = bb | qbb + + //LOK: Now that we have the mins and maxes, we need to sum them + tcg_gen_add_i64(t0, t3, t4); // t0 = a_max + b_max + //LOK: Note that t3 is being reused in this case + tcg_gen_add_i64(t3, t1, t2); // t3 = a_min + b_min + tcg_gen_xor_i64(t1, t0, t3); // t1 = ((a_min + b_min)^(a_max + b_max)) + tcg_gen_or_i64(t0, arg1, arg2); // t0 = qa | qb + tcg_gen_or_i64(arg0, t0, t1); // arg0 = (qa | qb) | ( (a_min + b_min) ^ (a_max + b_max) + + //put the original back + tcg_gen_add_i64(orig0, orig1, orig2); } break; @@ -2039,34 +2971,67 @@ break; case INDEX_op_sub_i64: // Special - expensiveAddSub() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { + //NOTE: It is important that we get the order of the operands correct + // Right now, the assumption is + // arg0 = arg1 - arg2 + // If there are errors - this could be the culprit + + //LOK: Changed the names of orig0 and orig 1 to orig1 and 2 + // so I don't get confused + // Basically arg is vxx and orig is x arg1 = find_shadow_arg(gen_opparam_ptr[-2]); arg2 = find_shadow_arg(gen_opparam_ptr[-1]); - orig0 = gen_opparam_ptr[-1]; + + //make sure we have a copy of the values first + orig0 = gen_opparam_ptr[-3]; orig1 = gen_opparam_ptr[-2]; + orig2 = gen_opparam_ptr[-1]; + + //delete the original operation + gen_opparam_ptr -= 3; + gen_opc_ptr--; + + //LOK: Declared the new temporary variables that we need + t0 = tcg_temp_new_i64(); //scratch + t1 = tcg_temp_new_i64(); //a_min + t2 = tcg_temp_new_i64(); //b_min + t3 = tcg_temp_new_i64(); //a_max + t4 = tcg_temp_new_i64(); //b_max + /* Per the expensiveAddSub() logic: qaa = T1 = arg1 qbb = T2 = arg2 - aa = V1 = gen_opparam_ptr[-2] - bb = V2 = gen_opparam_ptr[-1] */ - tcg_gen_not_i64(t0, arg1); // ~T1 - tcg_gen_and_i64(t1, orig1, t0);//tcg_gen_and_i64(t1, gen_opparam_ptr[-2], t0); // V1 & ~T1 (a_min) - - tcg_gen_not_i64(t0, arg2); // ~T2 - tcg_gen_and_i64(t2, orig0, t0);//tcg_gen_and_i64(t2, gen_opparam_ptr[-1], t0); // V2 & ~T2 (b_min) + aa = V1 = orig1 + bb = V2 = orig2 */ - tcg_gen_or_i64(t3, orig1, arg1);//tcg_gen_or_i64(t3, gen_opparam_ptr[-2], arg1); // V1 | T1 (a_max) - tcg_gen_or_i64(t4, orig0, arg2)//tcg_gen_or_i64(t4, gen_opparam_ptr[-1], arg2); // V2 | T2 (b_max) - - tcg_gen_sub_i64(t0, t1, t4); // a_min - b_max - tcg_gen_sub_i64(t3, t3, t2); // a_max - b_min - tcg_gen_xor_i64(t1, t0, t3); // ((a_min - b_max)^(a_max - b_min)) - tcg_gen_or_i64(t0, t1, arg2); // T1 | all of that previous stuff - tcg_gen_or_i64(arg0, t0, arg1); // T2 | all of that previous stuff + //LOK: First lets calculate a_min = aa & ~qaa + tcg_gen_not_i64(t0, arg1); // ~qaa + tcg_gen_and_i64(t1, orig1, t0);//t1 = aa & ~qaa + + //LOK: Then calculate b_min + tcg_gen_not_i64(t0, arg2); // ~qbb + tcg_gen_and_i64(t2, orig2, t0);//t2 = bb & ~qbb + + //LOK: Then calculate a_max = aa | qaa + tcg_gen_or_i64(t3, orig1, arg1);//t3 = aa | qaa + tcg_gen_or_i64(t4, orig2, arg2);//t4 = bb | qbb + + //LOK: Now that we have the mins and maxes, we need to find the differences + //NOTE: This is why the order of the operands is important + tcg_gen_sub_i64(t0, t1, t4); // t0 = a_min - b_max + //LOK: Note that t3 is being reused in this case + tcg_gen_sub_i64(t4, t3, t2); // t4 = a_max - b_min + tcg_gen_xor_i64(t1, t0, t4); // t1 = ((a_min - b_max)^(a_max - b_min)) + tcg_gen_or_i64(t0, arg1, arg2); // t0 = qa | qb + tcg_gen_or_i64(arg0, t0, t1); // arg0 = (qa | qb) | ( (a_min - b_max) ^ (a_max - b_min) + //put the original back + tcg_gen_sub_i64(orig0, orig1, orig2); } break; -#endif +#if 0 case INDEX_op_add_i64: // Up - cheap_AddSub64 case INDEX_op_sub_i64: // Up - cheap_AddSub64 +#endif case INDEX_op_mul_i64: // Up - mkUifU64(), mkLeft64(), mkPCastTo() arg0 = find_shadow_arg(gen_opparam_ptr[-3]); if (arg0) { @@ -2552,6 +3517,26 @@ break; case INDEX_op_st32_i64: case INDEX_op_st_i64: DUMMY_TAINT(nb_oargs, nb_args); + /* check eip,its value and taint value*/ +#ifdef LOG_TAINTED_EIP + arg0 = gen_opparam_ptr[-3]; + arg1 = gen_opparam_ptr[-2]; + arg2 = gen_opparam_ptr[-1]; +#if defined(TARGET_I386) + if(/*arg0 == cpu_T[0] && */arg2 == offsetof(CPUState, eip)) { +#elif defined(TARGET_ARM) + if(arg2 == offsetof(CPUState, regs[15])) { +#elif defined(TARGET_MIPS) + if(arg2 == (offsetof(CPUState, active_tc) + offsetof(TCState, gpr[29]))) { +#endif /* TARGET_I386/ARM */ + TCGv shadow = shadow_arg[arg0]; + if (shadow != 0) { + set_con_i32(0, arg0); + set_con_i32(1, shadow); + tcg_gen_helperN(helper_DECAF_invoke_eip_check_callback, 0, 0, TCG_CALL_DUMMY_ARG, 2, helper_arg_array); + } + } +#endif break; /* No taint info propagated (register liveness gets these) */ default: @@ -2560,24 +3545,215 @@ break; assert(1==0); break; } /* End switch */ +//#ifdef USE_TCG_OPTIMIZATIONS + skip_instrumentation:; +//#endif /* USE_TCG_OPTIMIZATIONS */ } /* End taint while loop */ return return_lj; +#else + return 0; +#endif /* CONFIG_TCG_TAINT */ } int optimize_taint(int search_pc) { -#ifdef USE_TCG_OPTIMIZATIONS +int retVal; +#ifdef USE_TCG_OPTIMIZATIONS + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { + qemu_log("OP partial buffer before optimization:\n"); + tcg_dump_ops(&tcg_ctx, logfile); + qemu_log("\n"); + } + gen_opparam_ptr = tcg_optimize(&tcg_ctx, gen_opc_ptr, gen_opparam_buf, tcg_op_defs); +#if 0 // AWH - Causes phantom taint in tempidx, so remove for now + build_liveness_metadata(&tcg_ctx); +#endif // AWH #endif + block_count++; + if (unlikely(qemu_loglevel_mask( + CPU_LOG_TB_OUT_ASM | CPU_LOG_TB_IN_ASM | + CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT)) ) + { + qemu_log("------------ BEGIN BLOCK %u ---------------------\n", block_count); + } + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) { - qemu_log("OP partial buffer before optimization:\n"); + qemu_log("OP partial buffer before taint instrumentation\n"); + tcg_dump_ops(&tcg_ctx, logfile); + qemu_log("\n"); + } + + retVal = gen_taintcheck_insn(search_pc); + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { + qemu_log("OP after taint instrumentation\n"); tcg_dump_ops(&tcg_ctx, logfile); qemu_log("\n"); } - return(gen_taintcheck_insn(search_pc)); + return(retVal); } +#ifdef USE_TCG_OPTIMIZATIONS +static void build_liveness_metadata(TCGContext *s) +{ + int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops; + TCGOpcode op; + TCGArg *args; + const TCGOpDef *def; + uint8_t *dead_temps; + unsigned int dead_args; + + nb_ops = gen_opc_ptr - gen_opc_buf; + + dead_temps = tcg_malloc(s->nb_temps); + memset(dead_temps, 1, s->nb_temps); + + args = gen_opparam_ptr; + op_index = nb_ops - 1; + while (op_index >= 0) { +//fprintf(stderr, "op_index: %d\n", op_index); + /* Liveness metadata (alive by default) */ + gen_old_liveness_metadata[op_index] = 1; + op = gen_opc_buf[op_index]; + def = &tcg_op_defs[op]; + switch(op) { + case INDEX_op_call: + { + int call_flags; + + nb_args = args[-1]; + args -= nb_args; + nb_iargs = args[0] & 0xffff; + nb_oargs = args[0] >> 16; + args++; + call_flags = args[nb_oargs + nb_iargs]; + + /* pure functions can be removed if their result is not + used */ + if (call_flags & TCG_CALL_PURE) { + for(i = 0; i < nb_oargs; i++) { + arg = args[i]; + if (!dead_temps[arg]) + goto do_not_remove_call; + } + /* Mark the liveness metadata that this will be + eliminated during liveness checks */ + gen_old_liveness_metadata[op_index] = 0; +//fprintf(stderr, "Setting opc index: %d as dead\n", op_index); + //tcg_set_nop(s, gen_opc_buf + op_index,args - 1, nb_args); + } else { + do_not_remove_call: + + /* output args are dead */ + dead_args = 0; + for(i = 0; i < nb_oargs; i++) { + arg = args[i]; + if (dead_temps[arg]) { + dead_args |= (1 << i); + } + dead_temps[arg] = 1; + } + + if (!(call_flags & TCG_CALL_CONST)) { + /* globals are live (they may be used by the call) */ + memset(dead_temps, 0, s->nb_globals); + } + + /* input args are live */ + for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) { + arg = args[i]; + if (arg != TCG_CALL_DUMMY_ARG) { + if (dead_temps[arg]) { + dead_args |= (1 << i); + } + dead_temps[arg] = 0; + } + } + } + args--; + } + break; + case INDEX_op_set_label: + args--; + /* mark end of basic block */ + // AWH tcg_la_bb_end(s, dead_temps); + break; + case INDEX_op_debug_insn_start: + args -= def->nb_args; + break; + case INDEX_op_nopn: + nb_args = args[-1]; + args -= nb_args; + break; + case INDEX_op_discard: + args--; + /* mark the temporary as dead */ + dead_temps[args[0]] = 1; + break; + case INDEX_op_end: + break; + /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */ + default: + args -= def->nb_args; + nb_iargs = def->nb_iargs; + nb_oargs = def->nb_oargs; + + /* Test if the operation can be removed because all + its outputs are dead. We assume that nb_oargs == 0 + implies side effects */ + if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) { + for(i = 0; i < nb_oargs; i++) { + arg = args[i]; + if (!dead_temps[arg]) + goto do_not_remove; + } + /* Mark the liveness metadata that this will be + eliminated during liveness checks */ + gen_old_liveness_metadata[op_index] = 0; +//fprintf(stderr, "Setting opc index: %d as dead\n", op_index); + //tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args); +#ifdef CONFIG_PROFILER +// s->del_op_count++; +#endif + } else { + do_not_remove: + + /* output args are dead */ + dead_args = 0; + for(i = 0; i < nb_oargs; i++) { + arg = args[i]; + if (dead_temps[arg]) { + dead_args |= (1 << i); + } + dead_temps[arg] = 1; + } + + /* if end of basic block, update */ + if (def->flags & TCG_OPF_BB_END) { + // AWH tcg_la_bb_end(s, dead_temps); + } else if (def->flags & TCG_OPF_CALL_CLOBBER) { + /* globals are live */ + memset(dead_temps, 0, s->nb_globals); + } + + /* input args are live */ + for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) { + arg = args[i]; + if (dead_temps[arg]) { + dead_args |= (1 << i); + } + dead_temps[arg] = 0; + } + } + break; + } + op_index--; + } + if (args != gen_opparam_buf) + tcg_abort(); +} +#endif /* USE_TCG_OPTIMIZATIONS */ #endif /* CONFIG_TCG_TAINT */ diff --git a/shared/tainting/tcg_taint.h b/shared/tainting/tcg_taint.h index 1e915bf..f5e3291 100644 --- a/shared/tainting/tcg_taint.h +++ b/shared/tainting/tcg_taint.h @@ -13,6 +13,10 @@ extern int nb_tcg_sweeps; extern void clean_shadow_arg(void); extern int optimize_taint(int search_pc); +extern TCGv find_shadow_arg(TCGv arg); + +#define METADATA_SIZE 2048 +extern uint8_t gen_opc_opt_immune_metadata[METADATA_SIZE]; #endif /* __DECAF_TCG_TAINT_H__ */ diff --git a/shared/vmi.cpp b/shared/vmi.cpp index ee53991..79bdbf6 100644 --- a/shared/vmi.cpp +++ b/shared/vmi.cpp @@ -69,7 +69,7 @@ static os_handle_c handle_funds_c[] = { { WIN7_SP0_C, &find_win7sp0, &win_vmi_init, }, { WIN7_SP1_C, &find_win7sp1, &win_vmi_init, }, #endif - //{ LINUX_2_6_C, &find_linux, &linux_vmi_init,}, + { LINUX_GENERIC_C, &find_linux, &linux_vmi_init,}, }; @@ -203,6 +203,7 @@ int procmod_insert_modinfoV(uint32_t pid, uint32_t base, module *mod) { //We also need to removed the previous modules if they happen to sit on the same region for (uint32_t vaddr = base; vaddr < base + mod->size; vaddr += 4096) { proc->resolved_pages.insert(vaddr >> 12); + proc->pending_pages.erase(vaddr >> 12); proc->module_list.erase(vaddr); } @@ -486,28 +487,44 @@ dprocess *find_all_processes_infoV(size_t * num_proc) static void block_end_cb(DECAF_Callback_Params* temp) { - int i=0; - int cflag=0; - for(i=0; iie.env,insn_handle_c)==1) + if(handle_funds_c[i].find(temp->ie.env, insn_handle_c) == 1) { - GuestOS_index_c=i; - cflag=1; + GuestOS_index_c = i; + found_guest_os = 1; } } - if(GuestOS_index_c == 0||GuestOS_index_c == 1) + +#ifdef TARGET_I386 + if(GuestOS_index_c == 0 || GuestOS_index_c == 1) monitor_printf(default_mon, "its win xp \n"); - else if(GuestOS_index_c == 2||GuestOS_index_c == 3) + else if(GuestOS_index_c == 2 || GuestOS_index_c == 3) monitor_printf(default_mon, "its win 7 \n"); - //else if(GuestOS_index_c == 4) - // monitor_printf(default_mon, "its linux \n"); + else if(GuestOS_index_c == 4) + monitor_printf(default_mon, "its linux \n"); +#endif - if(cflag) + if(found_guest_os) { - DECAF_unregister_callback(DECAF_BLOCK_END_CB, insn_handle_c); + DECAF_unregister_callback(DECAF_TLB_EXEC_CB, insn_handle_c); handle_funds_c[GuestOS_index_c].init(); } + +_skip_probe: + + if (count_out-- <= 0) {// does not find + DECAF_unregister_callback(DECAF_TLB_EXEC_CB, insn_handle_c); + monitor_printf(default_mon, "oops! guest OS type cannot be decided. \n"); + } } @@ -535,6 +552,17 @@ process * findProcessByCR3(uint32_t cr3) } +process *findProcessByPid(uint32_t pid) +{ + unordered_map < uint32_t, process * >::iterator iter = + process_pid_map.find(pid); + + if (iter == process_pid_map.end()) + return NULL; + + return iter->second; +} + int findCr3(uint32_t cr3){ unordered_set::const_iterator got = cr3s.find (cr3); if(got==cr3s.end()){ @@ -603,7 +631,8 @@ module* findModule(char *key) void vmi_init() { monitor_printf(default_mon, "inside vmi init \n"); - insn_handle_c = DECAF_register_callback(DECAF_BLOCK_END_CB, block_end_cb, NULL); + //insn_handle_c = DECAF_register_callback(DECAF_BLOCK_END_CB, block_end_cb, NULL); + insn_handle_c = DECAF_register_callback(DECAF_TLB_EXEC_CB, block_end_cb, NULL); } #endif diff --git a/shared/vmi.h b/shared/vmi.h index 6a64f15..3bae26d 100644 --- a/shared/vmi.h +++ b/shared/vmi.h @@ -28,14 +28,14 @@ extern "C" { #define MAX_NAME_LENGTHC 64 typedef enum { - WINXP_SP2_C = 0, WINXP_SP3_C, WIN7_SP0_C, WIN7_SP1_C, LINUX_2_6_C, + WINXP_SP2_C = 0, WINXP_SP3_C, WIN7_SP0_C, WIN7_SP1_C, LINUX_GENERIC_C, } GUEST_OS_C; class module{ public: char name[32]; - char fullname[128]; + char fullname[256]; //string fullname; uint32_t size; uint32_t codesize; // use these to identify dll @@ -58,6 +58,7 @@ class process{ unordered_map < uint32_t,module * >module_list; //a set of virtual pages that have been resolved with module information unordered_set< uint32_t > resolved_pages; + unordered_set< uint32_t > pending_pages; }; /* typedef struct _cr3_info_c{ @@ -73,7 +74,10 @@ typedef struct os_handle_c{ // add process info to process list int addProcV(process *proc); + int findProcessByPidH(uint32_t pid); +process *findProcessByPid(uint32_t pid); + process * findProcessByCR3(uint32_t cr3); // remove process from list int removeProcV(uint32_t pid); diff --git a/shared/vmi_include.h b/shared/vmi_include.h index 720a7c1..d7fafb5 100644 --- a/shared/vmi_include.h +++ b/shared/vmi_include.h @@ -23,7 +23,7 @@ extern "C" { //unordered_map < uint32_t, process_info_t * >process_map; typedef struct _dmodule{ char name[32]; -char fullname[128]; +char fullname[256]; uint32_t base; uint32_t size; } dmodule; @@ -46,7 +46,7 @@ extern int get_loaded_modules_countV(uint32_t pid); extern void get_proc_modulesV(uint32_t pid, dmodule *buf, int size); extern dmodule *locate_moduleV(uint32_t eip, uint32_t cr3); extern dmodule *locate_module_bynameV(char *name, uint32_t pid); -void vmi_init(); +extern void vmi_init(); #ifdef __cplusplus }; #endif diff --git a/shared/windows_vmi.cpp b/shared/windows_vmi.cpp index 6242502..020739d 100644 --- a/shared/windows_vmi.cpp +++ b/shared/windows_vmi.cpp @@ -37,7 +37,7 @@ #include #include #include -#include "sqlite3/sqlite3.h" +#include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -86,6 +86,10 @@ BYTE *recon_file_data_raw = 0; /* Timer to check for proc exits */ static QEMUTimer *recon_timer = NULL; + +unordered_map < uint32_t, pair > phys_module_map; + + static inline int is_page_resolved(process *proc, uint32_t page_num) { return (proc->resolved_pages.find(page_num>>12) != proc->resolved_pages.end()); @@ -217,13 +221,13 @@ static process* get_new_process() { static inline int get_IMAGE_NT_HEADERS(uint32_t cr3, uint32_t base, IMAGE_NT_HEADERS *nth) { IMAGE_DOS_HEADER DosHeader; - DECAF_read_mem_with_pgd(cpu_single_env, cr3, base, sizeof(IMAGE_DOS_HEADER), &DosHeader); + DECAF_read_mem(cpu_single_env, base, sizeof(IMAGE_DOS_HEADER), &DosHeader); if (DosHeader.e_magic != (0x5a4d)) { return -1; } - if(DECAF_read_mem_with_pgd(cpu_single_env, cr3, base + DosHeader.e_lfanew, + if(DECAF_read_mem(cpu_single_env, base + DosHeader.e_lfanew, sizeof(IMAGE_NT_HEADERS), nth) < 0) { //monitor_printf(default_mon, "Reading NTHeader failed. :'(\n"); //monitor_printf(default_mon, "%s, 0x%08x, %d\n", fullname, base, DosHeader->e_lfanew); @@ -242,47 +246,42 @@ static inline int readustr_with_cr3(uint32_t addr, uint32_t cr3, void *buf, uint8_t unicode_str[MAX_UNICODE_LENGTH] = { '\0' }; char *store = (char *) buf; - if (cr3 != 0) { - if (DECAF_memory_rw_with_pgd(env, cr3, addr, (void *) &unicode_data, - sizeof(unicode_data), 0) < 0) { - store[0] = '\0'; - goto done; - } - } else { - if (DECAF_read_mem(env, addr, sizeof(unicode_data), unicode_data) < 0) { - store[0] = '\0'; - goto done; - } + if (DECAF_read_mem(env, addr, sizeof(unicode_data), unicode_data) < 0) { + store[0] = '\0'; + goto done; } unicode_len = (int) (unicode_data[0] & 0xFFFF); if (unicode_len > MAX_UNICODE_LENGTH) unicode_len = MAX_UNICODE_LENGTH; - if (cr3 != 0) { - if (DECAF_memory_rw_with_pgd(env, cr3, unicode_data[1], - (void *) unicode_str, unicode_len, 0) < 0) { - store[0] = '\0'; - goto done; - } - } else { - if (DECAF_memory_rw(env, unicode_data[1], (void *) unicode_str, - unicode_len, 0) < 0) { - store[0] = '\0'; - goto done; - } + if (DECAF_memory_rw(env, unicode_data[1], (void *) unicode_str, unicode_len, 0) < 0) { + store[0] = '\0'; + goto done; } for (i = 0, j = 0; i < unicode_len; i += 2, j++) { - if (unicode_str[i] < 0x20 || unicode_str[i] > 0x7e) //Non_printable character - break; +// if (unicode_str[i] < 0x20 || unicode_str[i] > 0x7e) //Non_printable character +// break; store[j] = tolower(unicode_str[i]); } store[j] = '\0'; done: - return strlen(store); + return j; //strlen(store); +} + + +/* this function convert a full DLL name to a base name. */ +static char * get_basename(char *fullname) +{ + int i = 0, last_slash = -1, j; + for(; fullname[i] != 0; i++) + if (fullname[i] == '/' || (fullname[i] == '\\')) + last_slash = i; + + return fullname + last_slash + 1; } static void update_kernel_modules(CPUState *env, target_ulong vaddr) { @@ -294,8 +293,7 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { return; //If this page has been resolved, return immediately - if (is_page_resolved(kernel_proc, vaddr)) - return; + //if (is_page_resolved(kernel_proc, vaddr)) return; DECAF_read_mem(env, gkpcr + KDVB_OFFSET, 4, &kdvb); DECAF_read_mem(env, kdvb + PSLM_OFFSET, 4, &psLM); @@ -306,7 +304,7 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { uint32_t base = 0; DECAF_read_mem(env, curr_mod + handle_funds[GuestOS_index].offset->DLLBASE_OFFSET, - 4, &base); // dllbase DLLBASE_OFFSET + 4, &base); if (is_page_resolved(kernel_proc, base)) goto next; @@ -314,9 +312,11 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { char name[512]; char key[512]; + char *base_name; readustr_with_cr3(curr_mod + handle_funds[GuestOS_index].offset->DLLNAME_OFFSET, 0, name, env); + base_name = get_basename(name); //We get checksum and use base module name along with checksum as the key to //uniquely identify a module. @@ -325,7 +325,7 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { if(get_IMAGE_NT_HEADERS(env->cr[3], base, &nth) < 0) goto next; - snprintf(key, sizeof(key)-1, "%s:%08x", name, nth.OptionalHeader.CheckSum); + snprintf(key, sizeof(key)-1, "%s:%08x", base_name, nth.OptionalHeader.CheckSum); //See if we have extracted detailed info about this module curr_entry = findModule(key); if (!curr_entry) { @@ -334,8 +334,9 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { curr_mod + handle_funds[GuestOS_index].offset->SIZE_OFFSET, 4, &curr_entry->size); // dllsize SIZE_OFFSET - strncpy(curr_entry->name, name, sizeof(curr_entry->name)-1); + strncpy(curr_entry->name, base_name, sizeof(curr_entry->name)-1); readustr_with_cr3(curr_mod + 0x24, 0, curr_entry->fullname, env); + addModule(curr_entry, key); } procmod_insert_modinfoV(kernel_proc->pid, base, curr_entry); @@ -352,6 +353,7 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { } curr_mod = next_mod; } + } static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, @@ -363,11 +365,9 @@ static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, if (peb == 0x00) return; - if (is_page_resolved(proc, vaddr)) return; - - DECAF_read_mem_with_pgd(env, cr3, peb + 0xc, 4, &ldr); + DECAF_read_mem(env, peb + 0xc, 4, &ldr); memlist = ldr + 0xc; - DECAF_read_mem_with_pgd(env, cr3, memlist, 4, &first_dll); + DECAF_read_mem(env, memlist, 4, &first_dll); if (first_dll == 0) return; @@ -376,15 +376,14 @@ static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, IMAGE_NT_HEADERS nth; count++; uint32_t base = 0; //, size = 0; - if (DECAF_read_mem_with_pgd(env, cr3, curr_dll + 0x18, 4, &base) < 0) + if (DECAF_read_mem(env, curr_dll + 0x18, 4, &base) < 0) break; - //FIXME: why do we check base > 0x00300000? - if (base > 0x00300000 && !is_page_resolved(proc, base)) { + if (!is_page_resolved(proc, base)) { char name[512]; char key[512]; - readustr_with_cr3(curr_dll + 0x2c, cr3, name, env); + readustr_with_cr3(curr_dll + 0x2c, 0, name, env); //We get checksum and use base module name along with checksum as the key to //uniquely identify a module. @@ -399,19 +398,22 @@ static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, if(!curr_entry) { //We haven't seen this module before, even in other process memory spaces curr_entry = new module(); - readustr_with_cr3(curr_dll + 0x24, cr3, curr_entry->fullname, env); - DECAF_read_mem_with_pgd(env, cr3, curr_dll + 0x20, 4, &curr_entry->size); + readustr_with_cr3(curr_dll + 0x24, 0, curr_entry->fullname, env); + DECAF_read_mem(env, curr_dll + 0x20, 4, &curr_entry->size); strncpy(curr_entry->name, name, sizeof(curr_entry->name)-1); + addModule(curr_entry, key); } procmod_insert_modinfoV(proc->pid, base, curr_entry); message_m(proc->pid, cr3, base, curr_entry); + } next: //read the next DLL - DECAF_read_mem_with_pgd(env, cr3, curr_dll, 4, &curr_dll); + DECAF_read_mem(env, curr_dll, 4, &curr_dll); } while (curr_dll != 0 && curr_dll != first_dll && count < MAX); + } static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t base, module *mod) @@ -427,7 +429,7 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b edt_va = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; edt_size = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - if(DECAF_read_mem_with_pgd(env, cr3, base + edt_va, sizeof(ied), &ied) < 0) { + if(DECAF_read_mem(env, base + edt_va, sizeof(ied), &ied) < 0) { //monitor_printf(default_mon, "Unable to read exp dir from image: mod=%s:%d base=%08x, va=%08x.\n", mod->name, ver, base, edt_va); //DECAF_stop_vm(); goto done; @@ -444,17 +446,17 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b if(!func_addrs || !name_addrs || !ordinals) goto done; - if(DECAF_read_mem_with_pgd(env, cr3, base + ied.AddressOfFunctions, + if(DECAF_read_mem(env, base + ied.AddressOfFunctions, sizeof(DWORD) * ied.NumberOfFunctions, func_addrs) < 0) { goto done; } - if(DECAF_read_mem_with_pgd(env, cr3, base + ied.AddressOfNames, + if(DECAF_read_mem(env, base + ied.AddressOfNames, sizeof(DWORD) * ied.NumberOfNames, name_addrs) < 0) { goto done; } - if(DECAF_read_mem_with_pgd(env, cr3, base + ied.AddressOfNameOrdinals, + if(DECAF_read_mem(env, base + ied.AddressOfNameOrdinals, sizeof(WORD) * ied.NumberOfNames, ordinals) < 0) { goto done; } @@ -464,7 +466,7 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b if(index >= ied.NumberOfFunctions) continue; - DECAF_read_mem_with_pgd(env, cr3, base + name_addrs[i], sizeof(name)-1, name); + DECAF_read_mem(env, base + name_addrs[i], sizeof(name)-1, name); name[127] = 0; snprintf(msg, sizeof(msg)-1, "F %s %s %08x\n", mod->name, name, func_addrs[index]); handle_guest_message(msg); @@ -508,22 +510,12 @@ static void retrieve_missing_symbols(process *proc) for(; iter!=proc->module_list.end(); iter++) { module *cur_mod = iter->second; - if(cur_mod->symbols_extracted) continue; - - extract_PE_info(proc->cr3, iter->first, cur_mod); - - if(cur_mod->symbols_extracted) { - //Now the symbols in this module have been extracted. - //Add this module into our module map, so we don't need to extract again. - char key[512]; - snprintf(key, sizeof(key)-1, "%s:%08x", cur_mod->name, cur_mod->checksum); - addModule(cur_mod, key); - } - + if(!cur_mod->symbols_extracted) + extract_PE_info(proc->cr3, iter->first, cur_mod); } } -static void get_new_modules(CPUState* env, process * proc, target_ulong vaddr) +static inline void get_new_modules(CPUState* env, process * proc, target_ulong vaddr) { uint32_t base = 0, self = 0, pid = 0; if (proc == kernel_proc) { @@ -556,30 +548,22 @@ static void tlb_call_back(DECAF_Callback_Params *temp) { kernel_proc->cr3 = cr3; } else { proc = findProcessByCR3(cr3); - if (proc == NULL) { -#if 0 - //If we haven't found system process, do it now. - if (system_proc == NULL) { - system_proc = find_new_process(env, cr3); - if(system_proc == NULL || strcasecmp(system_proc->name, "System")) { - monitor_printf(default_mon, - "System proc not found!!!\n"); - abort(); - } - - //update_kernel_modules(env, vaddr); - - proc = system_proc; - } else { -#endif + if (proc == NULL) proc = find_new_process(env, cr3); - } } - //getting_new_mods++; - //monitor_printf(default_mon,"%d\n", getting_new_mods++); - if (proc) { - get_new_modules(env, proc, vaddr); + if (proc ) { + if (!is_page_resolved(proc, vaddr)) + get_new_modules(env, proc, vaddr); + + if (!is_page_resolved(proc, vaddr)) { + if (proc->pending_pages.find(vaddr>>12) == proc->pending_pages.end()) + proc->pending_pages.insert(vaddr>>12); + else { + proc->pending_pages.erase(vaddr>>12); + proc->resolved_pages.insert(vaddr>>12); + } + } retrieve_missing_symbols(proc); } } @@ -664,7 +648,8 @@ uint32_t get_ntoskrnl(CPUState *env) { return ntoskrnl_base; } -static void probe_windows(CPUState *env) +/*FIXME: Supports only 32bit guest. */ +static uint32_t probe_windows(CPUState *env) { uint32_t base; @@ -676,11 +661,15 @@ static void probe_windows(CPUState *env) get_os_version(env); base = get_ntoskrnl(env); + monitor_printf(default_mon, + "The base address of ntoskrnl.exe is %08x\n", base); if (!base) { monitor_printf(default_mon, "Unable to locate kernel base. Stopping VM...\n"); //vm_stop(RUN_STATE_DEBUG); - return; + return 0; + } else { + return base; } } } @@ -737,10 +726,9 @@ void check_procexit(void *) { if (proc->parent_pid == 0) continue; //0x78 for xp, 0x88 for win7 - cpu_memory_rw_debug(env, - (proc->EPROC_base_addr) + DECAF_read_mem(env, (proc->EPROC_base_addr) + handle_funds[GuestOS_index].offset->PEXIT_TIME, - (uint8_t *) &end_time[0], 8, 0); + 8, end_time); if (end_time[0] | end_time[1]) { removeProcV(proc->pid); diff --git a/shared/windows_vmi.h b/shared/windows_vmi.h index 6b1019d..4e615a1 100644 --- a/shared/windows_vmi.h +++ b/shared/windows_vmi.h @@ -48,7 +48,7 @@ extern "C" { #include "config.h" #include "DECAF_callback_common.h" // AWH -#define MAX_NAME_LENGTH 64 +#define MAX_NAME_LENGTH 128 #define MAX_UNICODE_LENGTH 2*MAX_NAME_LENGTH #ifdef __x86_64__ @@ -79,7 +79,7 @@ extern "C" { #define MODULES 0 #define PROC 1 #define THRD 2 -#define FILE 3 +//#define FILE 3 #define IMAGE_SIZEOF_SHORT_NAME 8 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 diff --git a/target-arm/helper.h b/target-arm/helper.h index d94cee6..7817c2e 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -16,6 +16,11 @@ DEF_HELPER_3(DECAF_invoke_block_end_callback, void, ptr, ptr, tl) DEF_HELPER_1(DECAF_invoke_insn_begin_callback, void, ptr) DEF_HELPER_1(DECAF_invoke_insn_end_callback, void, ptr) +#ifdef CONFIG_TCG_TAINT +DEF_HELPER_2(DECAF_invoke_eip_check_callback,void,i32,i32) +DEF_HELPER_0(DECAF_taint_patch,void) +#endif /* CONFIG_TCG_TAINT */ + DEF_HELPER_1(clz, i32, i32) DEF_HELPER_1(sxtb16, i32, i32) DEF_HELPER_1(uxtb16, i32, i32) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 1892b35..9169d1c 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -428,3 +428,8 @@ uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i) return ((uint32_t)x >> shift) | (x << (32 - shift)); } } + +#ifdef CONFIG_TCG_TAINT +void helper_DECAF_taint_patch(void) { } +#endif /* CONFIG_TCG_TAINT */ + diff --git a/target-arm/translate.c b/target-arm/translate.c index d0e6fff..3f8dfbe 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -91,7 +91,7 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE]; #define DISAS_WFI 4 #define DISAS_SWI 5 -static TCGv_ptr cpu_env; +/* AWH static */ TCGv_ptr cpu_env; /* We reuse the same 64-bit temporaries for efficiency. */ static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; static TCGv_i32 cpu_R[16]; @@ -9874,6 +9874,17 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) gen_exception_insn(s, 2, EXCP_UDEF); } +#ifdef CONFIG_TCG_IR_LOG +inline void log_tcg_ir(TranslationBlock *tb) +{ + /* AWH - Store the IRs for logging to disk later by plugin, if needed. */ + tb->DECAF_num_opc = (gen_opc_ptr - gen_opc_buf) / sizeof(uint16_t); + tb->DECAF_num_opparam = (gen_opparam_ptr - gen_opparam_buf) / sizeof(TCGArg); + memcpy(tb->DECAF_gen_opc_buf, gen_opc_buf, tb->DECAF_num_opc * sizeof(uint16_t)); + memcpy(tb->DECAF_gen_opparam_buf, gen_opparam_buf, tb->DECAF_num_opparam * sizeof(TCGArg)); +} +#endif /* CONFIG_TCG_IR_LOG */ + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ @@ -10008,6 +10019,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, } #else if (dc->pc >= 0xfffffff0 && IS_M(env)) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) { lj = optimize_taint(search_pc); @@ -10025,6 +10039,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == dc->pc) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) { lj = optimize_taint(search_pc); @@ -10093,7 +10110,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, !singlestep && dc->pc < next_page_start && num_insns < max_insns); - +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (not_tainted && taint_tracking_enabled) lj = optimize_taint(search_pc); @@ -10193,6 +10212,13 @@ static inline void gen_intermediate_code_internal(CPUState *env, tb->size = dc->pc - pc_start; tb->icount = num_insns; } +#ifdef CONFIG_TCG_IR_LOG + /* AWH - Store the IRs for logging to disk later by plugin, if needed. */ + tb->DECAF_num_opc = (gen_opc_ptr - gen_opc_buf) / sizeof(uint16_t); + tb->DECAF_num_opparam = (gen_opparam_ptr - gen_opparam_buf) / sizeof(TCGArg); + memcpy(tb->DECAF_gen_opc_buf, gen_opc_buf, tb->DECAF_num_opc * sizeof(uint16_t)); + memcpy(tb->DECAF_gen_opparam_buf, gen_opparam_buf, tb->DECAF_num_opparam * sizeof(TCGArg)); +#endif /* CONFIG_TCG_IR_LOG */ } void gen_intermediate_code(CPUState *env, TranslationBlock *tb) diff --git a/target-i386/DECAF_target.c b/target-i386/DECAF_target.c index 1e84ceb..d89074b 100644 --- a/target-i386/DECAF_target.c +++ b/target-i386/DECAF_target.c @@ -56,11 +56,6 @@ int insn_tainted = 0; //Indicates if the current instruction is tainted int plugin_taint_record_size = 0; #endif -//Aravind - call backs for the instruction handlers -void (*insn_cbl1[16*16]) (uint32_t eip, uint32_t op); //Used to get l1 callbacks (all opcodes except 0x0f) insn_cbl1[byte1byte2] holds the cb for that opcode -void (*insn_cbl2[16*16]) (uint32_t eip, uint32_t op); //Used to get l2 callbacks (when first 2 bytes are 0x0f, next two bytes are indexed in this array) -//end - Aravind - // AWH extern CPUState *first_cpu; #if 0 @@ -227,49 +222,6 @@ int DECAF_get_page_access(CPUState* env, uint32_t addr) } -//Aravind - Function to register cb handlers for instruction ranges -void DECAF_register_insn_cb_range(uint32_t start_opcode, uint32_t end_opcode, void (*insn_cb_handler) (uint32_t, uint32_t)) -{ - int i; - - if(end_opcode < start_opcode) { - fprintf(stderr, "end_opcode can't be less than start_opcode.\n"); - return; - } - - if(start_opcode <= 0xff) { - for(i = start_opcode; i <= end_opcode; i++) { - insn_cbl1[i] = insn_cb_handler; - } - } - - if(start_opcode >= 0x0f00) { - insn_cbl1[0x0f] = (void *)1; //Indicator that l2 cbs exist - for(i = start_opcode; i <= end_opcode; i++) { - insn_cbl2[i-0x0f00] = insn_cb_handler; - } - } - //Flush the tb - tb_flush(cpu_single_env); -} - -//Function to cleanup callbacks. Called when plugin cleansup -void DECAF_cleanup_insn_cbs(void) -{ - int i; - //Aravind - reset insn_cbs - for(i = 0; i < 16*16; i++) { - insn_cbl1[i] = 0; - insn_cbl2[i] = 0; - } - tb_flush(cpu_single_env); - //end - Aravind -} - -//end - Aravind - - - diff --git a/target-i386/DECAF_target.h b/target-i386/DECAF_target.h index 9ff14c8..9fc61ee 100644 --- a/target-i386/DECAF_target.h +++ b/target-i386/DECAF_target.h @@ -198,7 +198,7 @@ extern uint32_t *DECAF_cc_op; //Aravind - Function to register cb for range of insns. extern void DECAF_register_insn_cb_range(uint32_t start_opcode, uint32_t end_opcode, void (*insn_cb_handler) (uint32_t, uint32_t)); //Function to cleanup insn_cbs. TODO: Should automatically happen when plugin exits. -extern void DECAF_cleanup_insn_cbs(void); +//extern void DECAF_cleanup_insn_cbs(void); //end - Aravind /// \brief Given a virtual address, this function returns the page access status. diff --git a/target-i386/cpu.h b/target-i386/cpu.h index e36ea72..7e2a336 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -621,6 +621,7 @@ typedef struct CPUX86State { #endif /* CONFIG_TCG_TAINT */ target_ulong tempidx; // AWH - added for DECAF target_ulong tempidx2; // AWH - added for DECAF + target_ulong eip_taint; // AWH - EIP callback target_ulong eip; target_ulong eflags; /* eflags register. During CPU emulation, CC flags and DF are set to zero because they are @@ -653,8 +654,8 @@ typedef struct CPUX86State { uint16_t fpus; uint16_t fpuc; // AWH - //target_ulong fpip; //added by Heng Yin for better FPU emulation - target_ulong fpcs; //added by Heng Yin for better FPU emulation + target_ulong fpip_t; //added by Heng Yin for better FPU emulation + target_ulong fpcs_t; //added by Heng Yin for better FPU emulation target_ulong branch_cnt; //JMK: added by manju mjayacha@syr.edu to store the branch count value uint8_t fptags[8]; /* 0 = valid, 1 = empty */ diff --git a/target-i386/helper.h b/target-i386/helper.h index bbf55af..cc9c001 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -5,8 +5,11 @@ DEF_HELPER_FLAGS_1(cc_compute_all, TCG_CALL_PURE, i32, int) DEF_HELPER_FLAGS_1(cc_compute_c, TCG_CALL_PURE, i32, int) -//Aravind - Generic insn_range_cb_dispatcher -DEF_HELPER_3(insn_cb_dispatch, void, tl, tl, i32) //insn_cb_dispatch(eip, next_eip, opcode) next_eip used if insn branches +//Aravind - Generic opcode_range_cb_dispatcher +//DECAF_invoke_opcode_range_callback(CPUState *env, target_ulong eip, target_ulong next_eip, uint32_t op) +DEF_HELPER_4(DECAF_invoke_opcode_range_callback, void, ptr, tl, tl, i32) +//TODO: insn_cb_dispatch must go after range_callback impl is complete +//DEF_HELPER_3(insn_cb_dispatch, void, tl, tl, i32) //insn_cb_dispatch(eip, next_eip, opcode) next_eip used if insn branches //end - Aravind //DEF_HELPER_1(DECAF_invoke_callback, void, i32) @@ -19,8 +22,11 @@ DEF_HELPER_3(DECAF_invoke_block_end_callback, void, ptr, ptr, tl) DEF_HELPER_1(DECAF_invoke_insn_begin_callback, void, ptr) DEF_HELPER_1(DECAF_invoke_insn_end_callback, void, ptr) +//added by Hu for better fpu emulation +DEF_HELPER_0(DECAF_update_fpu, void); + #ifdef CONFIG_TCG_TAINT -DEF_HELPER_1(DECAF_invoke_eip_check_callback,void,tl) +DEF_HELPER_2(DECAF_invoke_eip_check_callback,void,i32,i32) DEF_HELPER_0(DECAF_taint_patch,void) #endif /* CONFIG_TCG_TAINT */ diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index c11330c..063a5e5 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -4468,8 +4468,11 @@ void helper_fstenv(target_ulong ptr, int data32) stl(ptr, env->fpuc); stl(ptr + 4, fpus); stl(ptr + 8, fptag); - stl(ptr + 12, 0); /* fpip */ - stl(ptr + 16, 0); /* fpcs */ + // stl(ptr + 12, 0); /* fpip */ + // stl(ptr + 16, 0); /* fpcs */ + //added by Hu for better fpu emulation + stl(ptr + 12, cpu_single_env->fpip_t); + stl(ptr + 16, cpu_single_env->fpcs_t); stl(ptr + 20, 0); /* fpoo */ stl(ptr + 24, 0); /* fpos */ } else { @@ -5903,6 +5906,8 @@ extern void (*insn_cbl2[16*16]) (uint32_t eip, uint32_t next_eip, uint32_t op); void helper_insn_cb_dispatch(uint32_t eip, uint32_t next_eip, uint32_t op2) { + + //LOK: Segmentation Fault return; uint32_t op; @@ -5940,29 +5945,42 @@ void helper_insn_cb_dispatch(uint32_t eip, uint32_t next_eip, uint32_t op2) /* patch for keystroke propagation on windows xp sp2 and sp3 */ -void helper_DECAF_taint_patch(void) { +void helper_DECAF_taint_patch(void) +{ + if (!taint_tracking_enabled) return; + if (cpu_single_env->eip != 0xbf8a4bde && cpu_single_env->eip != 0xbf84a74f && cpu_single_env->eip != 0xbf848d65 && //for sp3 cpu_single_env->eip != 0xbf848d1c) // updated sp3 - return 0; + return ; uint32_t phys_addr, addr, addr2, phys_addr2; - uint8_t taint, taint_check; + uint8_t taint_check; addr = cpu_single_env->regs[R_EBP] + 8; phys_addr = DECAF_get_phys_addr(cpu_single_env, addr); if (phys_addr == -1) - return 0; + return ; taint_mem_check(phys_addr, 1, &taint_check); if (!taint_check) - return 0; + return ; addr2 = cpu_single_env->regs[R_EBP] + 0x14; if (DECAF_read_mem(cpu_single_env, addr2, 4, &addr2) >= 0 && (phys_addr2 = DECAF_get_phys_addr(cpu_single_env, addr2)) != -1) { - taint_mem(phys_addr2, 1, &taint); + taint_mem(phys_addr2, 1,(uint8_t*) &taint_check); } } #endif /* CONFIG_TCG_TAINT */ +/* + * patch for better FPU emulation added by Hu + * + */ + +void helper_DECAF_update_fpu(void) +{ + cpu_single_env->fpip_t = cpu_single_env->eip; + cpu_single_env->fpcs_t = cpu_single_env->segs[R_CS].selector; +} diff --git a/target-i386/translate.c b/target-i386/translate.c index 097187b..821c1ce 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -86,12 +86,16 @@ static target_ulong cur_pc; /* global register indexes */ /* AWH static */ TCGv_ptr cpu_env; -static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp; -static TCGv_i32 cpu_cc_op; +static TCGv cpu_A0; +/* AWH - No longer static so tcg_taint.c can see them */ +TCGv cpu_cc_src, cpu_cc_dst, cpu_cc_tmp; +TCGv_i32 cpu_cc_op; + static TCGv cpu_regs[CPU_NB_REGS]; #ifdef CONFIG_TCG_TAINT static TCGv taint_cpu_regs[CPU_NB_REGS]; static TCGv /*taint_cpu_A0,*/ taint_cpu_cc_src, taint_cpu_cc_dst, taint_cpu_cc_tmp; +static TCGv eip_taint; // AWH - Now in shared/DECAF_tcg_taint.c static TCGv tempidx, tempidx2; #endif /* CONFIG_TCG_TAINT */ @@ -104,6 +108,7 @@ static TCGv_i32 cpu_tmp2_i32, cpu_tmp3_i32; static TCGv_i64 cpu_tmp1_i64; static TCGv cpu_tmp5; #ifdef CONFIG_TCG_TAINT +static TCGv cpu_tmp6; /* This needs to be accessable to the taint generation function so that this metadata can be updated as more taint IRs are added to the TB. */ uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; @@ -435,10 +440,6 @@ static inline void gen_op_addl_T0_T1(void) static inline void gen_op_jmp_T0(void) { -#ifdef CONFIG_TCG_TAINT - if(DECAF_is_callback_needed(DECAF_EIP_CHECK_CB)) - gen_helper_DECAF_invoke_eip_check_callback(cpu_T[0]); -#endif /* CONFIG_TCG_TAINT */ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip)); } @@ -636,11 +637,14 @@ static inline void gen_jmp_im(target_ulong pc) //LOK: Update the value of next_pc next_pc = pc; tcg_gen_movi_tl(cpu_tmp0, pc); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip)); #ifdef CONFIG_TCG_TAINT - if(DECAF_is_callback_needed(DECAF_EIP_CHECK_CB)) - gen_helper_DECAF_invoke_eip_check_callback(cpu_T[0]); + if(DECAF_is_callback_needed(DECAF_EIP_CHECK_CB)) { + cpu_tmp6 = tcg_temp_local_new(); + tcg_gen_movi_tl(cpu_tmp6, 0); + gen_helper_DECAF_invoke_eip_check_callback(cpu_tmp0, cpu_tmp6); + } #endif /* CONFIG_TCG_TAINT */ - tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip)); } static inline void gen_string_movl_A0_ESI(DisasContext *s) @@ -4177,11 +4181,6 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r) /* convert one instruction. s->is_jmp is set if the translation must be stopped. Return the next pc value */ -//Aravind - extern defs for the cb array -extern void (*insn_cbl1[16*16]) (uint32_t eip, uint32_t next_eip, uint32_t op); -extern void (*insn_cbl2[16*16]) (uint32_t eip, uint32_t next_eip, uint32_t op); -//end - Aravind - static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) { int b, prefixes, aflag, dflag; @@ -4346,39 +4345,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) /* now check op code */ reswitch: - //Aravind - invoke cbs the opcode if they exist. extended_op is set in case 0x0f. - if(b != 0x0f) { - if(extended_op == 1) { - if(insn_cbl2[b-0x100]) { - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_opcode = tcg_const_i32(0x0f00+b-0x100); - gen_helper_insn_cb_dispatch(tmp_eip, 0, tmp_opcode); //This is the insn_begin callback - tcg_temp_free(tmp_eip); - tcg_temp_free_i32(tmp_opcode); - } - } - else if(insn_cbl1[b]) { - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_opcode = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, 0, tmp_opcode); //This is the insn_begin callback - tcg_temp_free(tmp_eip); - tcg_temp_free_i32(tmp_opcode); - } - extended_op = 0; + //Aravind - invoke opcode cbs. + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_opcode = tcg_const_i32(b); + //This is an insn_begin callback + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, 0, tmp_opcode); + tcg_temp_free(tmp_eip); + tcg_temp_free_i32(tmp_opcode); } //end - Aravind switch(b) { case 0x0f: /**************************/ /* extended op code */ - extended_op = 1; //Aravind - This is an extended opcode - b = ldub_code(s->pc++) | 0x100; goto reswitch; @@ -4792,19 +4773,20 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) next_eip = s->pc - s->cs_base; gen_movtl_T1_im(next_eip); gen_push_T1(s); - //Aravind - to get the call target - //LOK: Updated to use target_ulong instead of i32 - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip,current_eip); - - tmp_op = tcg_const_i32(b); - //tmp_op = tcg_const_i32(0xff); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[0], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - //tcg_temp_free_i32(tmp_eip); - tcg_temp_free(tmp_eip); - //end - to get call target + + //Aravind - to get the call target + //LOK: Updated to use target_ulong instead of i32 + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip,current_eip); + + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[0], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target + gen_op_jmp_T0(); gen_eob(s); break; @@ -4813,15 +4795,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); gen_op_ldu_T0_A0(OT_WORD + s->mem_index); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[1], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[1], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + } + //end - to get call target do_lcall: if (s->pe && !s->vm86) { @@ -4844,16 +4828,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->dflag == 0) gen_op_andl_T0_ffff(); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[0], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[0], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target gen_op_jmp_T0(); gen_eob(s); @@ -4869,16 +4855,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_jmp_im(pc_start - s->cs_base); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[1], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[1], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target gen_helper_ljmp_protected(cpu_tmp2_i32, cpu_T[1], tcg_const_i32(s->pc - pc_start)); @@ -4886,16 +4874,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_op_movl_seg_T0_vm(R_CS); gen_op_movl_T0_T1(); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[0], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[0], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target gen_op_jmp_T0(); } @@ -6195,6 +6185,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) goto illegal_op; } } + //added by Hu for better FPU emulation + gen_helper_DECAF_update_fpu(); + break; /************************/ /* string ops */ @@ -6409,16 +6402,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->dflag == 0) gen_op_andl_T0_ffff(); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { tmp_eip = tcg_temp_new(); tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[0], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - //end - to get call target + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[0], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target gen_op_jmp_T0(); gen_eob(s); @@ -6429,16 +6424,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->dflag == 0) gen_op_andl_T0_ffff(); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { tmp_eip = tcg_temp_new(); tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, cpu_T[0], tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - //end - to get call target + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, cpu_T[0], tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + } + //end - to get call target gen_op_jmp_T0(); gen_eob(s); @@ -6512,19 +6509,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_movtl_T0_im(next_eip); gen_push_T0(s); - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_next_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_next_eip, tval); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, tmp_next_eip, tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - tcg_temp_free(tmp_next_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_next_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_next_eip, tval); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, tmp_next_eip, tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + tcg_temp_free(tmp_next_eip); + } + //end - to get call target gen_jmp(s, tval); } @@ -6554,19 +6553,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) else if(!CODE64(s)) tval &= 0xffffffff; - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_next_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_next_eip, tval); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, tmp_next_eip, tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - tcg_temp_free(tmp_next_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_next_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_next_eip, tval); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, tmp_next_eip, tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + tcg_temp_free(tmp_next_eip); + } + //end - to get call target gen_jmp(s, tval); break; @@ -6590,19 +6591,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (s->dflag == 0) tval &= 0xffff; - //Aravind - to get the call target - //LOK: Updated to use target_ulong - //tmp_eip = tcg_const_i32(current_eip); - tmp_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_eip, current_eip); - tmp_next_eip = tcg_temp_new(); - tcg_gen_movi_tl(tmp_next_eip, tval); - tmp_op = tcg_const_i32(b); - gen_helper_insn_cb_dispatch(tmp_eip, tmp_next_eip, tmp_op); //This is the branch target - tcg_temp_free_i32(tmp_op); - tcg_temp_free(tmp_eip); - tcg_temp_free(tmp_next_eip); - //end - to get call target + //Aravind - to get the call target + //LOK: Updated to use target_ulong + //tmp_eip = tcg_const_i32(current_eip); + if(DECAF_is_callback_needed(DECAF_OPCODE_RANGE_CB)) { + tmp_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_eip, current_eip); + tmp_next_eip = tcg_temp_new(); + tcg_gen_movi_tl(tmp_next_eip, tval); + tmp_op = tcg_const_i32(b); + gen_helper_DECAF_invoke_opcode_range_callback(cpu_env, tmp_eip, tmp_next_eip, tmp_op); //This is the branch target + tcg_temp_free_i32(tmp_op); + tcg_temp_free(tmp_eip); + tcg_temp_free(tmp_next_eip); + } + //end - to get call target gen_jmp(s, tval); break; @@ -7965,6 +7968,8 @@ void optimize_flags_init(void) taint_cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, taint_cc_tmp), "taint_cc_tmp"); + eip_taint = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, eip_taint), + "eip_taint"); shadow_arg[(int)cpu_cc_src] = taint_cpu_cc_src; shadow_arg[(int)cpu_cc_dst] = taint_cpu_cc_dst; shadow_arg[(int)cpu_cc_tmp] = taint_cpu_cc_tmp; @@ -8116,6 +8121,17 @@ void optimize_flags_init(void) #include "helper.h" } +#ifdef CONFIG_TCG_IR_LOG +inline void log_tcg_ir(TranslationBlock *tb) +{ + /* AWH - Store the IRs for logging to disk later by plugin, if needed. */ + tb->DECAF_num_opc = (gen_opc_ptr - gen_opc_buf) / sizeof(uint16_t); + tb->DECAF_num_opparam = (gen_opparam_ptr - gen_opparam_buf) / sizeof(TCGArg); + memcpy(tb->DECAF_gen_opc_buf, gen_opc_buf, tb->DECAF_num_opc * sizeof(uint16_t)); + memcpy(tb->DECAF_gen_opparam_buf, gen_opparam_buf, tb->DECAF_num_opparam * sizeof(TCGArg)); +} +#endif /* CONFIG_TCG_IR_LOG */ + /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ @@ -8232,6 +8248,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == pc_ptr && !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) lj = optimize_taint(search_pc); @@ -8263,15 +8282,16 @@ static inline void gen_intermediate_code_internal(CPUState *env, num_insns++; /* stop translation if indicated */ if (dc->is_jmp) -#ifdef CONFIG_TCG_TAINT { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ +#ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) lj = optimize_taint(search_pc); +#endif /* CONFIG_TCG_TAINT */ break; } -#else - break; -#endif /* CONFIG_TCG_TAINT */ /* if single step mode, we generate only one instruction and generate an exception */ /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear @@ -8279,6 +8299,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, change to be happen */ if (dc->tf || dc->singlestep_enabled || (flags & HF_INHIBIT_IRQ_MASK)) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) lj = optimize_taint(search_pc); @@ -8291,6 +8314,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, if (gen_opc_ptr >= gen_opc_end || (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) || num_insns >= max_insns) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) lj = optimize_taint(search_pc); @@ -8300,6 +8326,9 @@ static inline void gen_intermediate_code_internal(CPUState *env, break; } if (singlestep) { +#ifdef CONFIG_TCG_IR_LOG + log_tcg_ir(tb); +#endif /* CONFIG_TCG_IR_LOG */ #ifdef CONFIG_TCG_TAINT if (taint_tracking_enabled) lj = optimize_taint(search_pc); diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 79e2558..3c79332 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -145,6 +145,9 @@ typedef struct mips_def_t mips_def_t; typedef struct TCState TCState; struct TCState { target_ulong gpr[32]; +#ifdef CONFIG_TCG_TAINT + target_ulong taint_regs[32]; +#endif /* CONFIG_TCG_TAINT */ target_ulong PC; target_ulong HI[MIPS_DSP_ACC]; target_ulong LO[MIPS_DSP_ACC]; @@ -177,6 +180,8 @@ struct TCState { typedef struct CPUMIPSState CPUMIPSState; struct CPUMIPSState { + target_ulong tempidx; // AWH - added for DECAF + target_ulong tempidx2; // AWH - added for DECAF TCState active_tc; CPUMIPSFPUContext active_fpu; diff --git a/target-mips/helper.h b/target-mips/helper.h index 442f684..f5fac6c 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -1,4 +1,25 @@ #include "def-helper.h" +#ifdef CONFIG_TCG_TAINT +#include "shared/tainting/DECAF_taint_helper.h" +#endif /* CONFIG_TCG_TAINT */ +//Aravind - Generic insn_range_cb_dispatcher +//DEF_HELPER_3(insn_cb_dispatch, void, tl, tl, i32) //insn_cb_dispatch(eip, next_eip, opcode) next_eip used if insn branches +//end - Aravind + +//DEF_HELPER_1(DECAF_invoke_callback, void, i32) +//EK - helper for adding taint +//DEF_HELPER_1(taint_add, void, i32) + +//LOK: The new callback helpers +DEF_HELPER_2(DECAF_invoke_block_begin_callback, void, ptr, ptr) +DEF_HELPER_3(DECAF_invoke_block_end_callback, void, ptr, ptr, tl) +DEF_HELPER_1(DECAF_invoke_insn_begin_callback, void, ptr) +DEF_HELPER_1(DECAF_invoke_insn_end_callback, void, ptr) + +#ifdef CONFIG_TCG_TAINT +DEF_HELPER_2(DECAF_invoke_eip_check_callback,void,i32,i32) +DEF_HELPER_0(DECAF_taint_patch,void) +#endif /* CONFIG_TCG_TAINT */ DEF_HELPER_2(raise_exception_err, void, i32, int) DEF_HELPER_1(raise_exception, void, i32) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index c51b9cb..6f0be96 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -3409,3 +3409,8 @@ FOP_COND_PS(le, float32_le(fst0, fst1, &env->active_fpu.fp_status), float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) FOP_COND_PS(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || float32_le(fst0, fst1, &env->active_fpu.fp_status), float32_unordered(fsth1, fsth0, &env->active_fpu.fp_status) || float32_le(fsth0, fsth1, &env->active_fpu.fp_status)) + +#ifdef CONFIG_TCG_TAINT +void helper_DECAF_taint_patch(void) { } +#endif /* CONFIG_TCG_TAINT */ + diff --git a/target-mips/translate.c b/target-mips/translate.c index d5b1c76..e369b0d 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -479,7 +479,7 @@ enum { }; /* global register indices */ -static TCGv_ptr cpu_env; +/* AWH static */ TCGv_ptr cpu_env; static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC]; static TCGv cpu_dspctrl, btarget, bcond; diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 71712a3..f5f9ef1 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1476,12 +1476,19 @@ static void tcg_out_taint_qemu_st(TCGContext *s, const TCGArg *args, int opc) { mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)]; s_bits = opc; + /* AWH - Save the virtual address */ + tcg_out_push(s, args[addrlo_idx]); + tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args, label_ptr, offsetof(CPUTLBEntry, addr_write)); /* TLB Hit. */ + /* AWH - Restore the virtual address */ + tcg_out_pop(s, args[addrlo_idx]); tcg_out_push(s, data_reg); // Store for call to qemu_st_direct() below tcg_out_push(s, tcg_target_call_iarg_regs[0]); // Same + tcg_out_mov(s, TCG_TYPE_I32, + tcg_target_call_iarg_regs[1], args[addrlo_idx]); switch (opc) { case 0: tcg_out_calli(s, (tcg_target_long)__taint_stb_raw); @@ -1517,6 +1524,10 @@ static void tcg_out_taint_qemu_st(TCGContext *s, const TCGArg *args, int opc) { if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { *label_ptr[1] = s->code_ptr - label_ptr[1] - 1; } + + /* AWH - Pop the virtual address off the stack */ + tcg_out_pop(s, args[addrlo_idx]); + /* XXX: move that code at the end of the TB */ /* TCG_TARGET_REG_BITS == 64 case in x86_op_defs[] */ if (TCG_TARGET_REG_BITS == 64) { /* qemu_st8/16/32/64 */ @@ -1591,6 +1602,9 @@ static void tcg_out_taint_qemu_ld(TCGContext *s, const TCGArg *args, int opc) mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)]; s_bits = opc & 3; + /* AWH - Save the virtual address */ + tcg_out_push(s, args[addrlo_idx]); + tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args, label_ptr, offsetof(CPUTLBEntry, addr_read)); @@ -1598,11 +1612,15 @@ static void tcg_out_taint_qemu_ld(TCGContext *s, const TCGArg *args, int opc) /* AWH - Before we call the functionality in the function tcg_out_qemu_ld_direct(), we push some parms, call our "raw" taint load functions, pop the original parms, and then call tcg_out_qemu_ld_direct(). */ + tcg_out_pop(s, args[addrlo_idx]); + if (s_bits == 3) tcg_out_push(s, data_reg2); tcg_out_push(s, data_reg); tcg_out_push(s, tcg_target_call_iarg_regs[0]); - + tcg_out_push(s, tcg_target_call_iarg_regs[1]); + tcg_out_mov(s, TCG_TYPE_I32, + tcg_target_call_iarg_regs[1], args[addrlo_idx]); switch (s_bits) { case 0: case 0 | 4: @@ -1621,6 +1639,7 @@ static void tcg_out_taint_qemu_ld(TCGContext *s, const TCGArg *args, int opc) default: tcg_abort(); } + tcg_out_pop(s, tcg_target_call_iarg_regs[1]); tcg_out_pop(s, tcg_target_call_iarg_regs[0]); tcg_out_pop(s, data_reg); if (s_bits == 3) @@ -1642,6 +1661,10 @@ static void tcg_out_taint_qemu_ld(TCGContext *s, const TCGArg *args, int opc) if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { *label_ptr[1] = s->code_ptr - label_ptr[1] - 1; } + + /* AWH - Pop the virtual address off the stack */ + tcg_out_pop(s, args[addrlo_idx]); + /* XXX: move that code at the end of the TB */ /* The first argument is already loaded with addrlo. */ arg_idx = 1; @@ -1745,6 +1768,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; case INDEX_op_br: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_br: +#endif /* CONFIG_TCG_TAINT */ tcg_out_jxx(s, JCC_JMP, args[0], 0); break; case INDEX_op_movi_i32: @@ -1875,11 +1901,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1], args[3], 0); break; +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond_i32: +#endif /* CONFIG_TCG_TAINT */ + tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1], + args[3], 0); + break; case INDEX_op_setcond_i32: tcg_out_setcond32(s, args[3], args[0], args[1], args[2], const_args[2]); break; - OP_32_64(bswap16): tcg_out_rolw_8(s, args[0]); break; @@ -1981,6 +2012,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, #if TCG_TARGET_REG_BITS == 32 case INDEX_op_brcond2_i32: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond2_i32: +#endif /* CONFIG_TCG_TAINT */ tcg_out_brcond2(s, args, const_args, 0); break; case INDEX_op_setcond2_i32: @@ -2031,6 +2065,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_brcond_i64: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond_i64: +#endif /* CONFIG_TCG_TAINT */ tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1], args[3], 0); break; @@ -2079,6 +2116,9 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_call, { "ri" } }, { INDEX_op_jmp, { "ri" } }, { INDEX_op_br, { } }, +#if 0 //def CONFIG_TCG_TAINT + { INDEX_op_local_br, { } }, +#endif /* CONFIG_TCG_TAINT */ { INDEX_op_mov_i32, { "r", "r" } }, { INDEX_op_movi_i32, { "r" } }, { INDEX_op_ld8u_i32, { "r", "r" } }, @@ -2106,6 +2146,9 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_rotr_i32, { "r", "0", "ci" } }, { INDEX_op_brcond_i32, { "r", "ri" } }, +#if 0 //def CONFIG_TCG_TAINT + { INDEX_op_local_brcond_i32, { "r", "ri" } }, +#endif /* CONFIG_TCG_TAINT */ { INDEX_op_bswap16_i32, { "r", "0" } }, { INDEX_op_bswap32_i32, { "r", "0" } }, @@ -2128,6 +2171,9 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } }, { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } }, { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } }, +#if 0 //def CONFIG_TCG_TAINT + { INDEX_op_local_brcond2_i32, { "r", "r", "ri", "ri" } }, +#endif /* CONFIG_TCG_TAINT */ { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } }, #else { INDEX_op_mov_i64, { "r", "r" } }, @@ -2160,6 +2206,9 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_rotr_i64, { "r", "0", "ci" } }, { INDEX_op_brcond_i64, { "r", "re" } }, +#if 0 //def CONFIG_TCG_TAINT + { INDEX_op_local_brcond_i64, { "r", "re" } }, +#endif /* CONFIG_TCG_TAINT */ { INDEX_op_setcond_i64, { "r", "r", "re" } }, { INDEX_op_bswap16_i64, { "r", "0" } }, diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index c3cd54e..8d2ec78 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -359,6 +359,32 @@ static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 arg1, *gen_opparam_ptr++ = arg6; } +#if 0 //def CONFIG_TCG_TAINT +static inline void gen_local_set_label(int n) +{ + tcg_gen_op1i(INDEX_op_local_set_label, n); +} + +static inline void tcg_gen_local_brcond_i32(TCGCond cond, TCGv_i32 arg1, + TCGv_i32 arg2, int label_index) +{ + tcg_gen_op4ii_i32(INDEX_op_local_brcond_i32, arg1, arg2, cond, label_index); +} + +static inline void tcg_gen_local_brcond_i64(TCGCond cond, TCGv_i64 arg1, + TCGv_i64 arg2, int label_index) +{ + tcg_gen_op6ii_i32(INDEX_op_local_brcond2_i32, + TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2), + TCGV_HIGH(arg2), cond, label_index); +} + +static inline void tcg_gen_local_br(int label) +{ + tcg_gen_op1i(INDEX_op_local_br, label); +} +#endif /* CONFIG_TCG_TAINT */ + static inline void gen_set_label(int n) { tcg_gen_op1i(INDEX_op_set_label, n); diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h index e67d5c3..1c06aa7 100644 --- a/tcg/tcg-opc.h +++ b/tcg/tcg-opc.h @@ -48,6 +48,15 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS) # define IMPL64 TCG_OPF_64BIT #endif +#if 0 //def CONFIG_TCG_TAINT +DEF(local_br, 0, 0, 1, TCG_OPF_SIDE_EFFECTS) +DEF(local_set_label, 0, 0, 1, 0) +DEF(local_brcond_i32, 0, 2, 2, TCG_OPF_SIDE_EFFECTS) +DEF(local_brcond_i64, 0, 2, 2, TCG_OPF_SIDE_EFFECTS | IMPL64) +DEF(local_brcond2_i32, 0, 4, 2, + TCG_OPF_SIDE_EFFECTS | IMPL(TCG_TARGET_REG_BITS == 32)) +#endif /* CONFIG_TCG_TAINT */ + DEF(mov_i32, 1, 1, 0, 0) DEF(movi_i32, 1, 0, 1, 0) DEF(setcond_i32, 1, 2, 1, 0) diff --git a/tcg/tcg.c b/tcg/tcg.c index e4e9cad..c0cbb4a 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -23,8 +23,10 @@ */ /* define it to use liveness analysis (better code) */ +#if 0 // AWH - TCG_TAINT - DEBUG #define USE_LIVENESS_ANALYSIS #define USE_TCG_OPTIMIZATIONS +#endif // AWH #include "config.h" @@ -892,11 +894,12 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) int i, k, nb_oargs, nb_iargs, nb_cargs, first_insn; const TCGOpDef *def; char buf[128]; - + int op_index = 0; // AWH first_insn = 1; opc_ptr = gen_opc_buf; args = gen_opparam_buf; while (opc_ptr < gen_opc_ptr) { + fprintf(outfile, "%d: ", op_index); // AWH c = *opc_ptr++; def = &tcg_op_defs[c]; if (c == INDEX_op_debug_insn_start) { @@ -997,10 +1000,19 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) } switch (c) { case INDEX_op_brcond_i32: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond_i32: +#endif /* CONFIG_TCG_TAINT */ #if TCG_TARGET_REG_BITS == 32 case INDEX_op_brcond2_i32: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond2_i32: +#endif /* CONFIG_TCG_TAINT */ #elif TCG_TARGET_REG_BITS == 64 case INDEX_op_brcond_i64: +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_brcond_i64: +#endif /* CONFIG_TCG_TAINT */ #endif case INDEX_op_setcond_i32: #if TCG_TARGET_REG_BITS == 32 @@ -1027,6 +1039,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) } fprintf(outfile, "\n"); args += nb_iargs + nb_oargs + nb_cargs; + op_index++; // AWH } } @@ -1274,16 +1287,16 @@ if (!presweep) /* pure functions can be removed if their result is not used */ -#ifdef CONFIG_TCG_TAINT - if (!presweep && (call_flags & TCG_CALL_PURE)) { -#else if (call_flags & TCG_CALL_PURE) { -#endif /* CONFIG_TCG_TAINT */ for(i = 0; i < nb_oargs; i++) { arg = args[i]; if (!dead_temps[arg]) goto do_not_remove_call; } +#ifdef CONFIG_TCG_TAINT + if (gen_opc_opt_immune_metadata[op_index]) + goto do_not_remove_call; +#endif /* CONFIG_TCG_TAINT */ tcg_set_nop(s, gen_opc_buf + op_index, args - 1, nb_args); } else { @@ -1315,7 +1328,7 @@ if (!presweep) } } #ifdef CONFIG_TCG_TAINT -if (!presweep) + if (!presweep) #endif /* CONFIG_TCG_TAINT */ s->op_dead_args[op_index] = dead_args; } @@ -1327,6 +1340,11 @@ if (!presweep) /* mark end of basic block */ tcg_la_bb_end(s, dead_temps); break; +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_set_label: + args--; + break; +#endif /* CONFIG_TCG_TAINT */ case INDEX_op_debug_insn_start: args -= def->nb_args; break; @@ -1356,6 +1374,10 @@ if (!presweep) if (!dead_temps[arg]) goto do_not_remove; } +#ifdef CONFIG_TCG_TAINT + if (gen_opc_opt_immune_metadata[op_index]) + goto do_not_remove; +#endif /* CONFIG_TCG_TAINT */ tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args); #ifdef CONFIG_PROFILER s->del_op_count++; @@ -1404,7 +1426,11 @@ if (!presweep) } #else /* dummy liveness analysis */ +#ifdef CONFIG_TCG_TAINT +/*static*/ void tcg_liveness_analysis(TCGContext *s, int presweep) +#else static void tcg_liveness_analysis(TCGContext *s) +#endif /* CONFIG_TCG_TAINT */ { int nb_ops; nb_ops = gen_opc_ptr - gen_opc_buf; @@ -2170,6 +2196,9 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, break; case INDEX_op_set_label: tcg_reg_alloc_bb_end(s, s->reserved_regs); +#if 0 //def CONFIG_TCG_TAINT + case INDEX_op_local_set_label: +#endif /* CONFIG_TCG_TAINT */ tcg_out_label(s, args[0], (long)s->code_ptr); break; case INDEX_op_call: diff --git a/tcg/tcg.h b/tcg/tcg.h index bb88ca8..ef00af7 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -144,11 +144,12 @@ typedef struct TCGPool { #define TCG_POOL_CHUNK_SIZE 32768 -#define TCG_MAX_LABELS 512 #ifdef CONFIG_TCG_TAINT +#define TCG_MAX_LABELS 4096 #define TCG_MAX_TEMPS 2048 #define TCG_STATIC_CALL_ARGS_SIZE (32 * 10 * 2) #else +#define TCG_MAX_LABELS 512 #define TCG_MAX_TEMPS 512 /* when the size of the arguments of a called function is smaller than diff --git a/translate-all.c b/translate-all.c index 1ebe181..0dfd32d 100644 --- a/translate-all.c +++ b/translate-all.c @@ -82,6 +82,9 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr) if (taint_tracking_enabled) clean_shadow_arg(); #endif /* CONFIG_TCG_TAINT */ +#ifdef CONFIG_TCG_IR_LOG + tb->DECAF_logged = 0; /* AWH - Generating new code, so this TB isn't on disk */ +#endif /* CONFIG_TCG_IR_LOG */ gen_intermediate_code(env, tb); /* generate machine code */ @@ -141,6 +144,9 @@ int cpu_restore_state(TranslationBlock *tb, if (taint_tracking_enabled) clean_shadow_arg(); #endif /* CONFIG_TCG_TAINT */ +#ifdef CONFIG_TCG_IR_LOG + tb->DECAF_logged = 0; /* AWH - Generating new code, so this TB isn't on disk */ +#endif /* CONFIG_TCG_IR_LOG */ gen_intermediate_code_pc(env, tb); if (use_icount) { diff --git a/vl.c b/vl.c index e40f308..7ec8e73 100644 --- a/vl.c +++ b/vl.c @@ -2156,8 +2156,9 @@ static void free_and_trace(gpointer mem) free(mem); } -extern void DECAF_cleanup_insn_cbs(void); -extern void do_load_plugin_internal(Monitor* mon, const char* plugin_path); +//extern void DECAF_cleanup_insn_cbs(void); +extern void do_load_plugin_internal(Monitor* mon, const char* plugin_path); +extern int DECAF_kvm_enabled; //end - Aravind int main(int argc, char **argv, char **envp) @@ -2802,9 +2803,12 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_after_loadvm: // TEMU option after_loadvm = optarg; break; - case QEMU_OPTION_load_plugin: // TEMU option + case QEMU_OPTION_load_plugin: // DECAF option load_plugin = optarg; break; + case QEMU_OPTION_toggle_kvm: + DECAF_kvm_enabled = optarg; + break; case QEMU_OPTION_full_screen: full_screen = 1; break;