From fc23752f2024febae5839ead222711d442e5b92c Mon Sep 17 00:00:00 2001 From: "xchu87@gmail.com" Date: Wed, 28 May 2014 15:49:18 +0000 Subject: [PATCH] update for decaf 1.8 --- Makefile.objs | 5 +- configure | 19 +- exec-all.h | 19 + exec.c | 13 +- hw/ps2.c | 4 +- shared/DECAF_callback.c | 118 +++--- shared/DECAF_callback.h | 25 +- shared/DECAF_callback_common.h | 13 + shared/DECAF_callback_to_QEMU.h | 7 +- shared/DECAF_cmds.c | 1 + shared/DECAF_main.c | 85 +++- shared/DECAF_main.h | 4 +- shared/DECAF_types.h | 12 +- shared/disasm-i386.cpp | 2 +- shared/disasm-pp.h | 2 +- shared/function_map.cpp | 5 +- shared/hookapi.cpp | 1 + shared/junk.c | 2 +- shared/linux_procinfo.cpp | 311 +++++++++++++- shared/linux_procinfo.h | 22 +- shared/linux_vmi.cpp | 585 +++++++++++++++++++++++---- shared/linux_vmi.h | 1 + shared/tainting/DECAF_taint_helper.h | 4 + shared/tainting/taint_memory.c | 8 +- shared/tainting/taintcheck_opt.c | 8 +- shared/tainting/taintcheck_opt.h | 14 +- shared/tainting/tainting.c | 1 + shared/tainting/tcg_taint.c | 260 +----------- shared/utils/SimpleCallback.c | 2 +- shared/vmi.cpp | 3 +- shared/vmi.h | 2 +- shared/vmi_c_wrapper.cpp | 34 +- shared/vmi_c_wrapper.h | 2 +- shared/windows_vmi.cpp | 99 ++--- softmmu_header.h | 6 +- softmmu_taint_template.h | 36 +- softmmu_template.h | 10 +- target-arm/DECAF_target.h | 9 +- target-arm/helper.h | 3 - target-arm/translate.c | 5 +- target-i386/DECAF_target.h | 13 +- target-i386/helper.h | 5 +- target-i386/op_helper.c | 8 +- target-i386/translate.c | 37 +- target-mips/DECAF_target.c | 46 ++- target-mips/DECAF_target.h | 22 +- target-mips/cpu.h | 5 +- target-mips/helper.h | 3 - target-mips/translate.c | 202 ++++++++- translate-all.c | 8 +- vl.c | 2 +- 51 files changed, 1512 insertions(+), 601 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index 3909fdb..97d4ff9 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -428,15 +428,14 @@ vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) QEMU_CFLAGS+=$(GLIB_CFLAGS) #libdecaf AWH -QEMU_CPPFLAGS+=$(QEMU_CFLAGS) +QEMU_CPPFLAGS+=-fPIC #LOK: moved the callback interface into the shared directory libdecaf-y=DECAF_callback.o DECAF_main.o DECAF_cmds.o libdecaf-y+=hookapi.o windows_vmi.o vmi.o vmi_c_wrapper.o 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/taint_memory.o tainting/tcg_taint.o tainting/analysis_log.o -#libdecaf-y+=sqlite3/sqlite3.o +libdecaf-y+=tainting/taint_memory.o tainting/tcg_taint.o libdecaf-y+=DECAF_vm_compress.o libdecaf-y+=utils/HashtableWrapper.o libdecaf-y+=utils/Output.o diff --git a/configure b/configure index fc2bfec..22ed170 100755 --- a/configure +++ b/configure @@ -108,6 +108,8 @@ target_list="" # Distributions want to ensure that several features are compiled in, and it # is impossible without a --enable-foo that exits if a feature is not found. +#AWH - LLVM support disabled by default +tcg_llvm="no" #AWH - VMI enabled by default enable_vmi="yes" #AWH - TCG tainting off by default @@ -811,11 +813,17 @@ for opt do ;; --disable-tcg-ir-log) tcg_ir_log="no" ;; + # AWH - TCG LLVM support + --enable-tcg-llvm) tcg_llvm="yes" + ;; + --disable-tcg-llvm) tcg_llvm="no" + ;; # AWH - VMI support --enable-vmi) enable_vmi="yes" ;; --disable-vmi) enable_vmi="no" ;; + *) echo "ERROR: unknown option $opt"; show_help="yes" ;; esac @@ -905,6 +913,7 @@ if [ "$softmmu" = "yes" ] ; then default_target_list="\ i386-softmmu \ arm-softmmu \ +mips-softmmu \ " fi #x86_64-softmmu \ @@ -1115,6 +1124,9 @@ 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 - TCG-to-LLVM translation +echo " --disable-tcg-llvm disable TCG-to-LLVM translation (default)" +echo " --enable-tcg-llvm enable TCG-to-LLVM translation" # AWH - VMI enable echo " --disable-vmi disable VMI support" echo " --enable-vmi enable VMI support (default)" @@ -2919,6 +2931,8 @@ echo "build guest agent $guest_agent" echo "enable TCG taint $tcg_taint" # AWH - TCG IR logging echo "enable IR logging $tcg_ir_log" +#AWH - TCG LLVM +echo "enable TCG LLVM $tcg_llvm" # AWH - VMI echo "enable VMI $enable_vmi" @@ -2967,7 +2981,10 @@ esac if test "$enable_vmi" = "yes" ; then echo "CONFIG_VMI_ENABLE=y" >> $config_host_mak fi - +#AWH - TCG LLVM +if test "$tcg_llvm" = "yes" ; then + echo "CONFIG_TCG_LLVM=y" >> $config_host_mak +fi #AWH - TCG tainting if test "$tcg_taint" = "yes" ; then echo "CONFIG_TCG_TAINT=y" >> $config_host_mak diff --git a/exec-all.h b/exec-all.h index 3ea2930..b5713b5 100644 --- a/exec-all.h +++ b/exec-all.h @@ -170,6 +170,17 @@ void tlb_set_page(CPUState *env, target_ulong vaddr, #define USE_DIRECT_JUMP #endif +#ifdef CONFIG_TCG_LLVM +struct TCGLLVMTranslationBlock; +struct TCGLLVMContext; +#ifdef __cplusplus +namespace llvm { class Function; } +using llvm::Function; +#else +struct Function; +#endif +#endif /* CONFIG_TCG_LLVM */ + struct TranslationBlock { target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ target_ulong cs_base; /* CS base for this block */ @@ -203,6 +214,14 @@ struct TranslationBlock { struct TranslationBlock *jmp_next[2]; struct TranslationBlock *jmp_first; uint32_t icount; +#ifdef CONFIG_TCG_LLVM + /* pointer to LLVM translated code */ + struct TCGLLVMContext *tcg_llvm_context; + struct Function *llvm_function; + uint8_t *llvm_tc_ptr; + uint8_t *llvm_tc_end; + struct TranslationBlock* llvm_tb_next[2]; +#endif /* CONFIG_TCG_LLVM */ #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 */ diff --git a/exec.c b/exec.c index c0bdefa..5dfb798 100644 --- a/exec.c +++ b/exec.c @@ -575,20 +575,19 @@ 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. */ +#if defined(CONFIG_TCG_IR_LOG) +/* AWH - IR storage requires too much RAM for the default code_gen_max_blocks. + So, 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) */ +#endif /* CONFIG_TCG_IR_LOG */ 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+ TCG_IR_LOG_PADDING) * sizeof(uint16_t) * code_gen_max_blocks); +fprintf(stderr, "AWH: code_gen_alloc(): gDECAF_gen_opc_buf: %dk\n", ((OPC_MAX_SIZE+ TCG_IR_LOG_PADDING) * sizeof(uint16_t) * code_gen_max_blocks) >> 10); gDECAF_gen_opc_buf = g_malloc((OPC_MAX_SIZE + TCG_IR_LOG_PADDING) * sizeof(uint16_t) * code_gen_max_blocks); -fprintf(stderr, "AWH: code_gen_alloc(): gDECAF_gen_opparam_buf: %d\n", (OPC_MAX_SIZE + TCG_IR_LOG_PADDING) * sizeof(TCGArg) * 6 * code_gen_max_blocks); +fprintf(stderr, "AWH: code_gen_alloc(): gDECAF_gen_opparam_buf: %dk\n", ((OPC_MAX_SIZE + TCG_IR_LOG_PADDING) * sizeof(TCGArg) * 6 * code_gen_max_blocks) >> 10); gDECAF_gen_opparam_buf = g_malloc((OPC_MAX_SIZE + TCG_IR_LOG_PADDING) * sizeof(TCGArg) * 6 * code_gen_max_blocks); for (i = 0; i < code_gen_max_blocks; i++) { diff --git a/hw/ps2.c b/hw/ps2.c index d7808e4..9c8b0a7 100644 --- a/hw/ps2.c +++ b/hw/ps2.c @@ -28,6 +28,8 @@ extern void * cpu_single_env; extern int taint_keystroke_enabled; extern void DECAF_taint_keystroke(int keycode); +extern void DECAF_keystroke_read(uint8_t taint_status); +extern void DECAF_keystroke_place(int keycode); #endif /* CONFIG_TCG_TAINT */ /* debug PC keyboard */ @@ -157,7 +159,7 @@ void ps2_queue(void *opaque, int b) } #ifdef CONFIG_TCG_TAINT -void ps2_queue_taint(void *opaque, int b) +static void ps2_queue_taint(void *opaque, int b) { PS2State *s = (PS2State *)opaque; PS2Queue *q = &s->queue; diff --git a/shared/DECAF_callback.c b/shared/DECAF_callback.c index 00d05a2..a23c18d 100644 --- a/shared/DECAF_callback.c +++ b/shared/DECAF_callback.c @@ -28,9 +28,6 @@ If you have any questions about DECAF,please post it on #include "shared/DECAF_callback.h" #include "shared/DECAF_callback_to_QEMU.h" #include "shared/utils/HashtableWrapper.h" -#ifdef CONFIG_TCG_TAINT -#include "shared/tainting/analysis_log.h" -#endif /* CONFIG_TCG_TAINT */ #if 0 // AWH #define PUSH_ALL() __asm__ __volatile__ ("push %rax"); \ __asm__ __volatile__ ("push %rbx"); \ @@ -372,7 +369,7 @@ DECAF_Handle DECAF_registerOpcodeRangeCallbacks ( cb_struct->callback = handler; cb_struct->from = start_opcode; cb_struct->to = end_opcode; - cb_struct->enabled = condition; + cb_struct->enabled = (int *)condition; for(i = start_opcode; i <= end_opcode; i++) { instructionCallbacks[i] = cb_struct; @@ -782,7 +779,7 @@ void helper_DECAF_invoke_opcode_range_callback( } //Condition violated - if(temp & *(cb_struct->enabled) == 0) + if(temp & (*(cb_struct->enabled) == 0) ) return; } @@ -795,23 +792,30 @@ void helper_DECAF_invoke_opcode_range_callback( cb_struct->callback(¶ms); } +#ifndef LIST_FOREACH_SAFE +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + void helper_DECAF_invoke_block_begin_callback(CPUState* env, TranslationBlock* tb) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct, *tmp; + static DECAF_Callback_Params params; if ((env == NULL) || (tb == NULL)) { return; } -PUSH_ALL() - params.bb.env = env; params.bb.tb = tb; +PUSH_ALL() + //FIXME: not thread safe - LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_BLOCK_BEGIN_CB], link) { + LIST_FOREACH_SAFE(cb_struct, &callback_list_heads[DECAF_BLOCK_BEGIN_CB], link, tmp){ // If it is a global callback or it is within the execution context, // invoke this callback if(!cb_struct->enabled || *cb_struct->enabled) @@ -849,17 +853,17 @@ POP_ALL() void helper_DECAF_invoke_block_end_callback(CPUState* env, TranslationBlock* tb, gva_t from) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; if (env == NULL) return; -PUSH_ALL() - params.be.env = env; params.be.tb = tb; params.be.cur_pc = from; +PUSH_ALL() + #ifdef TARGET_I386 params.be.next_pc = env->eip + env->segs[R_CS].base; #elif defined(TARGET_ARM) @@ -901,15 +905,13 @@ POP_ALL() void helper_DECAF_invoke_insn_begin_callback(CPUState* env) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; if (env == 0) return; -PUSH_ALL() - params.ib.env = env; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_INSN_BEGIN_CB], link) { // If it is a global callback or it is within the execution context, @@ -923,13 +925,12 @@ POP_ALL() void helper_DECAF_invoke_insn_end_callback(CPUState* env) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; if (env == 0) return; -PUSH_ALL() params.ie.env = env; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_INSN_END_CB], link) { // If it is a global callback or it is within the execution context, @@ -944,14 +945,14 @@ POP_ALL() void helper_DECAF_invoke_mem_read_callback(gva_t virt_addr,gpa_t phy_addr,DATA_TYPE data_type) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.mr.dt=data_type; params.mr.paddr=phy_addr; params.mr.vaddr=virt_addr; //if (cpu_single_env == 0) return; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_MEM_READ_CB], link) { @@ -962,17 +963,18 @@ void helper_DECAF_invoke_mem_read_callback(gva_t virt_addr,gpa_t phy_addr,DATA_T cb_struct->callback(¶ms); } } +POP_ALL() } void helper_DECAF_invoke_eip_check_callback(gva_t source_eip, gva_t target_eip, gva_t target_eip_taint) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; - PUSH_ALL() //AWH + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; + params.ec.source_eip = source_eip; params.ec.target_eip = target_eip; params.ec.target_eip_taint = target_eip_taint; //if (cpu_single_env == 0) return; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_EIP_CHECK_CB], link) { @@ -983,14 +985,13 @@ void helper_DECAF_invoke_eip_check_callback(gva_t source_eip, gva_t target_eip, cb_struct->callback(¶ms); } } -out: POP_ALL() // AWH } void helper_DECAF_invoke_keystroke_callback(int keycode,uint32_t *taint_mark) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.ks.keycode=keycode; params.ks.taint_mark=taint_mark; //if (cpu_single_env == 0) return; @@ -1011,8 +1012,8 @@ void helper_DECAF_invoke_keystroke_callback(int keycode,uint32_t *taint_mark) void helper_DECAF_invoke_mem_write_callback(gva_t virt_addr,gpa_t phy_addr,DATA_TYPE data_type) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.mw.dt=data_type; params.mw.paddr=phy_addr; params.mw.vaddr=virt_addr; @@ -1032,14 +1033,14 @@ void helper_DECAF_invoke_mem_write_callback(gva_t virt_addr,gpa_t phy_addr,DATA_ void helper_DECAF_invoke_nic_rec_callback(const uint8_t * buf,int size,int cur_pos,int start,int stop) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.nr.buf=buf; params.nr.size=size; params.nr.cur_pos=cur_pos; params.nr.start=start; params.nr.stop=stop; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_NIC_REC_CB], link) { @@ -1049,12 +1050,13 @@ void helper_DECAF_invoke_nic_rec_callback(const uint8_t * buf,int size,int cur_p if (!cb_struct->enabled || *cb_struct->enabled) cb_struct->callback(¶ms); } +POP_ALL() } void helper_DECAF_invoke_nic_send_callback(uint32_t addr,int size, const uint8_t *buf) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.ns.addr=addr; params.ns.size=size; params.ns.buf=buf; @@ -1073,13 +1075,13 @@ POP_ALL() // AWH void helper_DECAF_invoke_read_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,uint8_t *taint_info) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.rt.paddr = paddr; params.rt.vaddr = vaddr; params.rt.size = size; params.rt.taint_info = taint_info; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_READ_TAINTMEM_CB], link) { @@ -1089,17 +1091,18 @@ void helper_DECAF_invoke_read_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,ui if (!cb_struct->enabled || *cb_struct->enabled) cb_struct->callback(¶ms); } +POP_ALL() } void helper_DECAF_invoke_write_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,uint8_t *taint_info) { - callback_struct_t *cb_struct; - DECAF_Callback_Params params; + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; params.wt.paddr = paddr; params.wt.vaddr = vaddr; params.wt.size = size; params.wt.taint_info = taint_info; - +PUSH_ALL() //FIXME: not thread safe LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_WRITE_TAINTMEM_CB], link) { @@ -1109,9 +1112,29 @@ void helper_DECAF_invoke_write_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,u if (!cb_struct->enabled || *cb_struct->enabled) cb_struct->callback(¶ms); } +POP_ALL() } - +#ifdef CONFIG_TCG_LLVM +void helper_DECAF_invoke_block_trans_callback( + const struct TranslationBlock *tb, + const struct TCGContext *tcg_ctx) +{ + static callback_struct_t *cb_struct; + static DECAF_Callback_Params params; + params.bt.tb = tb; + params.bt.tcg_ctx = tcg_ctx; +PUSH_ALL() + // FIXME: not thread safe + LIST_FOREACH(cb_struct, &callback_list_heads[DECAF_BLOCK_TRANS_CB], link) + { + params.cbhandle = (DECAF_Handle)cb_struct; + if (!cb_struct->enabled || *cb_struct->enabled) + cb_struct->callback(¶ms); + } +POP_ALL() +} +#endif /* CONFIG_TCG_LLVM */ void DECAF_callback_init(void) { int i; @@ -1131,3 +1154,4 @@ void DECAF_callback_init(void) bEnableAllBlockEndCallbacks = 0; enableAllBlockEndCallbacksCount = 0; } + diff --git a/shared/DECAF_callback.h b/shared/DECAF_callback.h index 13111b1..22e23fd 100644 --- a/shared/DECAF_callback.h +++ b/shared/DECAF_callback.h @@ -49,27 +49,40 @@ extern DECAF_Handle DECAF_register_callback( extern int DECAF_unregister_callback(DECAF_callback_type_t cb_type, DECAF_Handle handle); -DECAF_Handle DECAF_registerOpcodeRangeCallbacks ( +extern DECAF_Handle DECAF_registerOpcodeRangeCallbacks ( DECAF_callback_func_t handler, OpcodeRangeCallbackConditions *condition, uint16_t start_opcode, uint16_t end_opcode); -DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( +extern DECAF_Handle DECAF_registerOptimizedBlockBeginCallback( DECAF_callback_func_t cb_func, int *cb_cond, gva_t addr, OCB_t type); -DECAF_Handle DECAF_registerOptimizedBlockEndCallback( +extern DECAF_Handle DECAF_registerOptimizedBlockEndCallback( DECAF_callback_func_t cb_func, int *cb_cond, gva_t from, gva_t to); -int DECAF_unregisterOptimizedBlockBeginCallback(DECAF_Handle handle); - -int DECAF_unregisterOptimizedBlockEndCallback(DECAF_Handle handle); +extern int DECAF_unregisterOptimizedBlockBeginCallback(DECAF_Handle handle); + +extern int DECAF_unregisterOptimizedBlockEndCallback(DECAF_Handle handle); + +extern DECAF_errno_t DECAF_unregisterOpcodeRangeCallbacks(DECAF_Handle handle); +extern void helper_DECAF_invoke_block_begin_callback(CPUState* env, TranslationBlock* tb); +extern void helper_DECAF_invoke_block_end_callback(CPUState* env, TranslationBlock* tb, gva_t from); +extern void helper_DECAF_invoke_insn_begin_callback(CPUState* env); +extern void helper_DECAF_invoke_insn_end_callback(CPUState* env); +extern void helper_DECAF_invoke_eip_check_callback(gva_t source_eip, gva_t target_eip, gva_t target_eip_taint); +extern void helper_DECAF_invoke_opcode_range_callback( + CPUState *env, + target_ulong eip, + target_ulong next_eip, + uint32_t op); +extern void DECAF_callback_init(void); #ifdef __cplusplus } diff --git a/shared/DECAF_callback_common.h b/shared/DECAF_callback_common.h index e02a306..59f5462 100644 --- a/shared/DECAF_callback_common.h +++ b/shared/DECAF_callback_common.h @@ -56,6 +56,9 @@ typedef enum { DECAF_TLB_EXEC_CB, DECAF_READ_TAINTMEM_CB, DECAF_WRITE_TAINTMEM_CB, +#ifdef CONFIG_TCG_LLVM + DECAF_BLOCK_TRANS_CB, +#endif /* CONFIG_TCG_LLVM */ DECAF_LAST_CB, //place holder for the last position, no other uses. } DECAF_callback_type_t; @@ -189,6 +192,13 @@ typedef struct _DECAF_Read_Write_Mem uint8_t *taint_info; }DECAF_Write_Taint_Mem; +#ifdef CONFIG_TCG_LLVM +typedef struct _DECAF_Block_Trans_Params +{ + struct TranslationBlock *tb; + struct TCGContext *tcg_ctx; +}DECAF_Block_Trans_Params; +#endif /* CONFIG_TCG_LLVM */ //LOK: A dummy type typedef struct _DECAF_Callback_Params { @@ -208,6 +218,9 @@ typedef struct _DECAF_Callback_Params DECAF_Tlb_Exec_Params tx; DECAF_Read_Taint_Mem rt; DECAF_Write_Taint_Mem wt; +#ifdef CONFIG_TCG_LLVM + DECAF_Block_Trans_Params bt; +#endif /* CONFIG_TCG_LLVM */ }; } DECAF_Callback_Params; diff --git a/shared/DECAF_callback_to_QEMU.h b/shared/DECAF_callback_to_QEMU.h index bf94dc1..eddfd02 100644 --- a/shared/DECAF_callback_to_QEMU.h +++ b/shared/DECAF_callback_to_QEMU.h @@ -49,8 +49,11 @@ void helper_DECAF_invoke_mem_write_callback(gva_t virt_addr,gpa_t phy_addr,DATA_ void helper_DECAF_invoke_keystroke_callback(int keycode,uint32_t *taint_mark); void helper_DECAF_invoke_read_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,uint8_t *taint_info); void helper_DECAF_invoke_write_taint_mem(gva_t vaddr,gpa_t paddr,uint32_t size,uint8_t *taint_info); - - +void helper_DECAF_invoke_log_pointer_read(gva_t virt_addr,gva_t taint_info); +void helper_DECAF_invoke_log_pointer_write(gva_t virt_addr, gva_t taint_info); +#ifdef CONFIG_TCG_LLVM +void helper_DECAF_invoke_block_trans_callback(const struct TranslationBlock *tb, const struct TCGContext *tcg_ctx); +#endif /* CONFIG_TCG_LLVM */ //The following prototypes are not needed since they are defined in // helper.h //void helper_DECAF_invoke_block_begin_callback(CPUState* env, TranslationBlock* tb); diff --git a/shared/DECAF_cmds.c b/shared/DECAF_cmds.c index 50322ae..59ba94c 100644 --- a/shared/DECAF_cmds.c +++ b/shared/DECAF_cmds.c @@ -13,6 +13,7 @@ web site at: If you have any questions about DECAF,please post it on http://code.google.com/p/decaf-platform/ */ +#include "DECAF_main.h" #include "DECAF_cmds.h" #include "vmi_c_wrapper.h" diff --git a/shared/DECAF_main.c b/shared/DECAF_main.c index 299cf1d..f5eedd3 100644 --- a/shared/DECAF_main.c +++ b/shared/DECAF_main.c @@ -37,7 +37,7 @@ #endif /* CONFIG_TCG_TAINT */ #ifdef CONFIG_VMI_ENABLE -extern void VMI_init(); +extern void VMI_init(void); #endif int DECAF_kvm_enabled = 0; @@ -57,18 +57,15 @@ mon_cmd_t DECAF_info_cmds[] = { #include "DECAF_info_cmds.h" { NULL, NULL , }, }; -gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr) { + + +static void convert_endian_4b(uint32_t *data); + + +static gpa_t _DECAF_get_phys_addr(CPUState* env, gva_t addr) { int mmu_idx, index; uint32_t phys_addr; - if (env == NULL ) { -#ifdef DECAF_NO_FAIL_SAFE - return(INV_ADDR); -#else - env = cpu_single_env ? cpu_single_env : first_cpu; -#endif - } - index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = cpu_mmu_index(env); if (__builtin_expect( @@ -91,6 +88,34 @@ gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr) { return (gpa_t) qemu_ram_addr_from_host_nofail(p); } +gpa_t DECAF_get_phys_addr(CPUState* env, gva_t addr) +{ + gpa_t phys_addr; + if (env == NULL ) + { +#ifdef DECAF_NO_FAIL_SAFE + return(INV_ADDR); +#else + env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; +#endif + } + +#ifdef TARGET_MIPS + uint32_t ori_hflags = env->hflags; + env->hflags &= ~MIPS_HFLAG_UM; + env->hflags &= ~MIPS_HFLAG_SM; +#endif + + phys_addr = _DECAF_get_phys_addr(env, addr); + + // restore hflags +#ifdef TARGET_MIPS + env->hflags = ori_hflags; +#endif + return phys_addr; + +} + DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len, int is_write) { int l; @@ -100,15 +125,18 @@ DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len, #ifdef DECAF_NO_FAIL_SAFE return(INV_ADDR); #else - env = cpu_single_env ? cpu_single_env : first_cpu; + env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; #endif } + int ret = 0; + while (len > 0) { page = addr & TARGET_PAGE_MASK; phys_addr = DECAF_get_phys_addr(env, page); if (phys_addr == -1 || phys_addr > ram_size) { - return -1; + ret = -1; + break; } l = (page + TARGET_PAGE_SIZE) - addr; if (l > len) @@ -121,7 +149,8 @@ DECAF_errno_t DECAF_memory_rw(CPUState* env, uint32_t addr, void *buf, int len, buf += l; addr += l; } - return 0; + + return ret; } DECAF_errno_t DECAF_memory_rw_with_pgd(CPUState* env, target_ulong pgd, @@ -130,7 +159,7 @@ DECAF_errno_t DECAF_memory_rw_with_pgd(CPUState* env, target_ulong pgd, #ifdef DECAF_NO_FAIL_SAFE return (INV_ADDR); #else - env = cpu_single_env ? cpu_single_env : first_cpu; + env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; #endif } @@ -210,7 +239,7 @@ void DECAF_flushTranslationBlock_env(CPUState *env, uint32_t addr) { #ifdef DECAF_NO_FAIL_SAFE return; #else - env = cpu_single_env ? cpu_single_env : first_cpu; + env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; #endif } @@ -231,7 +260,7 @@ void DECAF_flushTranslationPage_env(CPUState* env, uint32_t addr) #ifdef DECAF_NO_FAIL_SAFE return; #else - env = cpu_single_env ? cpu_single_env : first_cpu; + env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; #endif } @@ -475,7 +504,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); void DECAF_init(void) { DECAF_callback_init(); @@ -571,7 +599,7 @@ void DECAF_nic_in(const uint32_t addr, const int size) { * Keystroke related functions * */ -int taint_keystroke_enabled = 0; +uint32_t taint_keystroke_enabled = 0; void DECAF_keystroke_place(int keycode) { if (DECAF_is_callback_needed(DECAF_KEYSTROKE_CB)) helper_DECAF_invoke_keystroke_callback(keycode, @@ -586,3 +614,24 @@ void DECAF_keystroke_read(uint8_t taint_status) { } #endif /*CONFIG_TCG_TAINT*/ } + + +DECAF_errno_t DECAF_read_ptr(CPUState* env, gva_t vaddr, gva_t *pptr) +{ + int ret = DECAF_read_mem(env, vaddr, sizeof(gva_t), pptr); + if(0 == ret) + { +#ifdef TARGET_WORDS_BIGENDIAN + convert_endian_4b(pptr); +#endif + } + return ret; +} + +static void convert_endian_4b(uint32_t *data) +{ + *data = ((*data & 0xff000000) >> 24) + | ((*data & 0x00ff0000) >> 8) + | ((*data & 0x0000ff00) << 8) + | ((*data & 0x000000ff) << 24); +} diff --git a/shared/DECAF_main.h b/shared/DECAF_main.h index 7f4169a..4745e48 100644 --- a/shared/DECAF_main.h +++ b/shared/DECAF_main.h @@ -146,10 +146,12 @@ extern DECAF_errno_t DECAF_write_mem(CPUState* env, gva_t vaddr, int len, void * extern DECAF_errno_t DECAF_read_mem_with_pgd(CPUState* env, target_ulong pgd, gva_t vaddr, int len, void *buf); extern DECAF_errno_t DECAF_write_mem_with_pgd(CPUState* env, target_ulong pgd, gva_t vaddr, int len, void *buf); - +DECAF_errno_t DECAF_read_ptr(CPUState *env, gva_t vaddr, gva_t *pptr); extern void * DECAF_KbdState; +extern void DECAF_keystroke_read(uint8_t taint_status); +extern void DECAF_keystroke_place(int keycode); /// \brief Set monitor context. /// diff --git a/shared/DECAF_types.h b/shared/DECAF_types.h index f278342..14f6468 100644 --- a/shared/DECAF_types.h +++ b/shared/DECAF_types.h @@ -22,6 +22,9 @@ If you have any questions about DECAF,please post it on #ifndef DECAF_TYPES_H #define DECAF_TYPES_H +#ifdef __cplusplus +#define __STDC_LIMIT_MACROS 1 +#endif /* __cplusplus */ #include #include "qemu-common.h" @@ -33,14 +36,13 @@ typedef target_ulong gpa_t; // We use the same logic as defined in tcg.h //typedef tcg_target_ulong hva_t; //typedef tcg_target_ulong hpa_t; -#if UINTPTR_MAX == UINT32_MAX - typedef uint32_t hva_t; - typedef uint32_t hpa_t; -#elif UINTPTR_MAX == UINT64_MAX +//#if UINTPTR_MAX == UINT32_MAX +#if __WORDSIZE == 64 typedef uint64_t hva_t; typedef uint64_t hpa_t; #else - #error BLARB + typedef uint32_t hva_t; + typedef uint32_t hpa_t; #endif typedef uintptr_t DECAF_Handle; diff --git a/shared/disasm-i386.cpp b/shared/disasm-i386.cpp index 87ac8d9..b2a28e8 100644 --- a/shared/disasm-i386.cpp +++ b/shared/disasm-i386.cpp @@ -17,7 +17,7 @@ If you have any questions about DECAF,please post it on /* Recursive i386 Disassembler Opcodes */ /******************************************************************************/ -#include "disasm.h" +// #include "disasm.h" // AWH - Moved these here from disasm.h because of a conflict with target-i386/cpu.h #define ST OP_ST, 0 diff --git a/shared/disasm-pp.h b/shared/disasm-pp.h index 4d47f0e..87c2ae3 100644 --- a/shared/disasm-pp.h +++ b/shared/disasm-pp.h @@ -16,7 +16,7 @@ If you have any questions about DECAF,please post it on #ifndef _DISASM_PP_H #define _DISASM_PP_H -#include "disasm.h" +// #include "disasm.h" #include #include //#include diff --git a/shared/function_map.cpp b/shared/function_map.cpp index 71916c6..31dcd00 100644 --- a/shared/function_map.cpp +++ b/shared/function_map.cpp @@ -53,7 +53,7 @@ map > map_function_offset; // Map "module name" -> "offset" -> "function name" map > map_offset_function; - +target_ulong funcmap_get_pc(const char *module_name, const char *function_name, target_ulong cr3) __attribute__((optimize("O0"))); target_ulong funcmap_get_pc(const char *module_name, const char *function_name, target_ulong cr3) { target_ulong base; @@ -127,9 +127,10 @@ void parse_function(const char *message) funcmap_insert_function(module, fname, offset); } - +// void funcmap_insert_function(const char *module, const char *fname, uint32_t offset) __attribute__((optimize("O0"))); void funcmap_insert_function(const char *module, const char *fname, uint32_t offset) { + // cout << module << fname << offset << endl; map >::iterator iter = map_function_offset.find(module); if (iter == map_function_offset.end()) { map func_offset; diff --git a/shared/hookapi.cpp b/shared/hookapi.cpp index c63b35d..d7e5d88 100644 --- a/shared/hookapi.cpp +++ b/shared/hookapi.cpp @@ -576,6 +576,7 @@ void check_unresolved_hooks() } } +// uintptr_t hookapi_hook_function_byname(const char *mod_name, const char *fun_name, int is_global, target_ulong cr3, hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque) __attribute__((optimize("O0"))); uintptr_t hookapi_hook_function_byname(const char *mod_name, const char *fun_name, int is_global, target_ulong cr3, hook_proc_t fnhook, void *opaque, uint32_t sizeof_opaque) { diff --git a/shared/junk.c b/shared/junk.c index 01ad5af..c524551 100644 --- a/shared/junk.c +++ b/shared/junk.c @@ -22,7 +22,7 @@ If you have any questions about DECAF,please post it on #include #include -#include "disasm.h" +// #include "disasm.h" InstDigraphs digraphs; diff --git a/shared/linux_procinfo.cpp b/shared/linux_procinfo.cpp index 34b3161..a4e2de3 100644 --- a/shared/linux_procinfo.cpp +++ b/shared/linux_procinfo.cpp @@ -23,12 +23,19 @@ #include #include #include +#include #include #include #include #include #include #include + +#include +#include +#include +#include + #include #include #include @@ -37,12 +44,13 @@ #include #include #include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "cpu.h" #include "config.h" -#include "hw/hw.h" // AWH +#include "hw/hw.h" // AWH #include "DECAF_main.h" #include "DECAF_target.h" #ifdef __cplusplus @@ -57,6 +65,7 @@ extern "C" { #include "shared/utils/SimpleCallback.h" + #ifdef TARGET_I386 #define T_FMT "" #define PI_R_EAX "eax" @@ -117,7 +126,7 @@ typedef target_int target_pid_t; #define INV_OFFSET ((target_ulong) -1) #define INV_UINT ((target_uint) -1) -#if defined(TARGET_I386) || defined(TARGET_ARM) +#if defined(TARGET_I386) || defined(TARGET_ARM)// || defined(TARGET_MIPS) //this is the default value - but keep in mind that a custom built // kernel can change this #define TARGET_PAGE_OFFSET 0xC0000000 @@ -127,6 +136,11 @@ typedef target_int target_pid_t; #define TARGET_KERNEL_IMAGE_START TARGET_PAGE_OFFSET #define TARGET_MIN_STACK_START 0xA0000000 //trial and error? #define TARGET_KERNEL_IMAGE_SIZE (0) +#elif defined(TARGET_MIPS) + #define TARGET_PAGE_OFFSET 0x80000000UL + #define TARGET_KERNEL_IMAGE_START TARGET_PAGE_OFFSET + #define TARGET_MIN_STACK_START 0xA0000000UL //trial and error? + #define TARGET_KERNEL_IMAGE_SIZE (0) #else //See: http://lxr.linux.no/#linux+v3.11/Documentation/x86/x86_64/mm.txt // for the memory regions @@ -189,7 +203,8 @@ typedef target_int target_pid_t; // 0xC0000000 are valid, some are not // depending on whether the virtual address range is used // we can figure this out by searching through the page tables -static inline int isKernelAddress(gva_t addr) +static inline +int isKernelAddress(gva_t addr) { return ( //the normal kernel memory area @@ -255,7 +270,8 @@ static inline int get_mem_at(CPUState *env, gva_t addr, void* buf, size_t count) //The idea is to go through the data structures and find an // item that points back to the threadinfo //ASSUMES PTR byte aligned -gva_t findTaskStructFromThreadInfo(CPUState * env, gva_t threadinfo, ProcInfo* pPI, int bDoubleCheck) +// gva_t findTaskStructFromThreadInfo(CPUState * env, gva_t threadinfo, ProcInfo* pPI, int bDoubleCheck) __attribute__((optimize("O0"))); +gva_t findTaskStructFromThreadInfo(CPUState * env, gva_t threadinfo, ProcInfo* pPI, int bDoubleCheck) { int bFound = 0; target_ulong i = 0; @@ -274,7 +290,9 @@ gva_t findTaskStructFromThreadInfo(CPUState * env, gva_t threadinfo, ProcInfo* p for (i = 0; i < MAX_THREAD_INFO_SEARCH_SIZE; i+= sizeof(target_ptr)) { temp = (threadinfo + i); - candidate = (get_target_ulong_at(env, temp)); + candidate = 0; + // candidate = (get_target_ulong_at(env, temp)); + DECAF_read_ptr(env, temp, &candidate); //if it looks like a kernel address if (isKernelAddress(candidate)) { @@ -283,8 +301,10 @@ gva_t findTaskStructFromThreadInfo(CPUState * env, gva_t threadinfo, ProcInfo* p { temp2 = (candidate + j); //if there is an entry that has the same - // value as threadinfo then we are set - if (get_target_ulong_at(env, temp2) == threadinfo) + // value as threadinfo then we are set + target_ulong val = 0; + DECAF_read_ptr(env, temp2, &val); + if (val == threadinfo) { if (bFound) { @@ -1580,3 +1600,280 @@ int printProcInfo(ProcInfo* pPI) return (0); } +void get_executable_directory(string &sPath) +{ + int rval; + char szPath[1024]; + sPath = ""; + rval = readlink("/proc/self/exe", szPath, sizeof(szPath)-1); + if(-1 == rval) + { + monitor_printf(default_mon, "can't get path of main executable.\n"); + return; + } + szPath[rval-1] = '\0'; + sPath = szPath; + sPath = sPath.substr(0, sPath.find_last_of('/')); + sPath += "/"; + return; +} + +void get_procinfo_directory(string &sPath) +{ + get_executable_directory(sPath); + sPath += "../shared/kernelinfo/procinfo_generic/"; + return; +} + +// given the section number, load the offset values +#define FILL_TARGET_ULONG_FIELD(field) pi.field = pt.get(sSectionNum + #field) +void _load_one_section(const boost::property_tree::ptree &pt, int iSectionNum, ProcInfo &pi) +{ + string sSectionNum; + + sSectionNum = boost::lexical_cast(iSectionNum); + sSectionNum += "."; + + // fill strName field + string sName; + const int SIZE_OF_STR_NAME = 32; + sName = pt.get(sSectionNum + "strName"); + strncpy(pi.strName, sName.c_str(), SIZE_OF_STR_NAME); + pi.strName[SIZE_OF_STR_NAME-1] = '\0'; + + // fill other fields + FILL_TARGET_ULONG_FIELD(init_task_addr ); + FILL_TARGET_ULONG_FIELD(init_task_size ); + FILL_TARGET_ULONG_FIELD(ts_tasks ); + FILL_TARGET_ULONG_FIELD(ts_pid ); + FILL_TARGET_ULONG_FIELD(ts_tgid ); + FILL_TARGET_ULONG_FIELD(ts_group_leader ); + FILL_TARGET_ULONG_FIELD(ts_thread_group ); + FILL_TARGET_ULONG_FIELD(ts_real_parent ); + FILL_TARGET_ULONG_FIELD(ts_mm ); + FILL_TARGET_ULONG_FIELD(ts_stack ); + FILL_TARGET_ULONG_FIELD(ts_real_cred ); + FILL_TARGET_ULONG_FIELD(ts_cred ); + FILL_TARGET_ULONG_FIELD(ts_comm ); + FILL_TARGET_ULONG_FIELD(cred_uid ); + FILL_TARGET_ULONG_FIELD(cred_gid ); + FILL_TARGET_ULONG_FIELD(cred_euid ); + FILL_TARGET_ULONG_FIELD(cred_egid ); + FILL_TARGET_ULONG_FIELD(mm_mmap ); + FILL_TARGET_ULONG_FIELD(mm_pgd ); + FILL_TARGET_ULONG_FIELD(mm_arg_start ); + FILL_TARGET_ULONG_FIELD(mm_start_brk ); + FILL_TARGET_ULONG_FIELD(mm_brk ); + FILL_TARGET_ULONG_FIELD(mm_start_stack ); + FILL_TARGET_ULONG_FIELD(vma_vm_start ); + FILL_TARGET_ULONG_FIELD(vma_vm_end ); + FILL_TARGET_ULONG_FIELD(vma_vm_next ); + FILL_TARGET_ULONG_FIELD(vma_vm_file ); + FILL_TARGET_ULONG_FIELD(vma_vm_flags ); + FILL_TARGET_ULONG_FIELD(vma_vm_pgoff ); + FILL_TARGET_ULONG_FIELD(file_dentry ); + FILL_TARGET_ULONG_FIELD(dentry_d_name ); + FILL_TARGET_ULONG_FIELD(dentry_d_iname ); + FILL_TARGET_ULONG_FIELD(dentry_d_parent ); + FILL_TARGET_ULONG_FIELD(ti_task ); +#ifdef TARGET_MIPS + FILL_TARGET_ULONG_FIELD(mips_pgd_current); +#endif +} + +// find the corresponding section for the current os and return the section number +int find_match_section(const boost::property_tree::ptree &pt, target_ulong tulInitTaskAddr) +{ + int cntSection = pt.get("info.total", 0); + + string sSectionNum; + vector vMatchNum; + + monitor_printf(default_mon, "Total Sections: %d\n", cntSection); + + for(int i = 1; i<=cntSection; ++i) + { + sSectionNum = boost::lexical_cast(i); + target_ulong tulAddr = pt.get(sSectionNum + ".init_task_addr"); + if(tulAddr == tulInitTaskAddr) + { + vMatchNum.push_back(i); + } + } + + if(vMatchNum.size() > 1) + { + monitor_printf(default_mon, "Too many match sections in procinfo.ini\n"); + return 0; + // for(int i=0;i> iNum; + // DECAF_stop_vm(); + // scanf("%d", &iNum); + + // cout << "iNum" << iNum << endl; + // DECAF_start_vm(); + // bool bMatch = false; + // for(int i=0;i(i); + m_cur_libpath = m_pt.get(sSectionNum + "." + LIBPATH_PROPERTY_NAME); + m_cur_section = &m_pt.get_child(sSectionNum); + load_cur_section(); + } + } + + void load_cur_section() + { + monitor_printf(default_mon, "loading lib conf for %s\n", m_cur_libpath.c_str()); + // traverse the section + BOOST_FOREACH(boost::property_tree::ptree::value_type &v, *m_cur_section) + { + if(!v.first.compare(LIBPATH_PROPERTY_NAME)) + { + continue; + } + // insert function + target_ulong addr = m_cur_section->get(v.first); + funcmap_insert_function(m_cur_libpath.c_str(), v.first.c_str(), addr); + } + } + + + boost::property_tree::ptree m_pt; + string m_cur_libpath; + boost::property_tree::ptree *m_cur_section; +public: + static const string LIBPATH_PROPERTY_NAME; +}; + +const string LibraryLoader::LIBPATH_PROPERTY_NAME = "decaf_conf_libpath"; + +void load_library_info(const char *strName) +{ + LibraryLoader loader(strName); +} \ No newline at end of file diff --git a/shared/linux_procinfo.h b/shared/linux_procinfo.h index 4297368..290c880 100644 --- a/shared/linux_procinfo.h +++ b/shared/linux_procinfo.h @@ -51,19 +51,23 @@ typedef struct _ProcInfo target_ulong dentry_d_iname; target_ulong dentry_d_parent; target_ulong ti_task; +// #ifdef TARGET_MIPS + target_ulong mips_pgd_current; +// #endif } ProcInfo; -int populate_mm_struct_offsets(CPUState *env, target_ptr mm, ProcInfo* pPI); -int populate_vm_area_struct_offsets(CPUState *env, target_ptr vma, ProcInfo* pPI); -int populate_dentry_struct_offsets(CPUState * env, target_ptr dentry, ProcInfo* pPI); -int getDentryFromFile(CPUState * env, target_ptr file, ProcInfo* pPI); -//runs through the guest's memory and populates the offsets within the -// ProcInfo data structure. Returns the number of elements/offsets found -// or -1 if error -int populate_kernel_offsets(CPUState *env, target_ptr threadinfo, ProcInfo* pPI); +// int populate_mm_struct_offsets(CPUState *env, target_ptr mm, ProcInfo* pPI); +// int populate_vm_area_struct_offsets(CPUState *env, target_ptr vma, ProcInfo* pPI); +// int populate_dentry_struct_offsets(CPUState * env, target_ptr dentry, ProcInfo* pPI); +// int getDentryFromFile(CPUState * env, target_ptr file, ProcInfo* pPI); +// //runs through the guest's memory and populates the offsets within the +// // ProcInfo data structure. Returns the number of elements/offsets found +// // or -1 if error +// int populate_kernel_offsets(CPUState *env, target_ptr threadinfo, ProcInfo* pPI); int printProcInfo(ProcInfo* pPI); - +int load_proc_info(CPUState * env, gva_t threadinfo, ProcInfo &pi); +void load_library_info(const char *strName); #ifdef __cplusplus }; diff --git a/shared/linux_vmi.cpp b/shared/linux_vmi.cpp index c49e098..1367c02 100644 --- a/shared/linux_vmi.cpp +++ b/shared/linux_vmi.cpp @@ -64,6 +64,18 @@ extern "C" { using namespace std; using namespace std::tr1; +#define BREAK_IF(x) if(x) break + +#if defined(TARGET_I386) +#define get_new_modules get_new_modules_x86 +#elif defined(TARGET_ARM) +#define get_new_modules get_new_modules_arm +#elif defined(TARGET_MIPS) +#define get_new_modules get_new_modules_mips +#else +#error Unknown target +#endif + // current linux profile static ProcInfo OFFSET_PROFILE = {"VMI"}; @@ -79,6 +91,8 @@ static ProcInfo OFFSET_PROFILE = {"VMI"}; /* Timer to check for proc exits */ static QEMUTimer *recon_timer = NULL; + + // query if one vm page is resolved static inline bool is_vm_page_resolved(process *proc, uint32_t addr) { @@ -106,10 +120,10 @@ void extract_symbols_info(CPUState *env, uint32_t cr3, target_ulong start_addr, } // get new module, basically reading from mm_struct -static void get_new_modules(CPUState* env, process * proc) +static void get_new_modules_x86(CPUState* env, process * proc) { target_ulong ts_mm, mm_mmap, vma_file, vma_next, f_dentry; - const uint32_t MAX_LOOP_COUNT = 1024; // prevent infinite loop + const int MAX_LOOP_COUNT = 1024; // prevent infinite loop target_ulong vma_vm_start = 0, vma_vm_end = 0, vma_vm_flags, vma_vm_pgoff; target_ulong last_vm_start = 0, last_vm_end = 0; char name[32], key[128]; // module file path @@ -122,6 +136,7 @@ static void get_new_modules(CPUState* env, process * proc) int mod_stage = 0; bool three_sections_found = false; static int offset_populated = 0, dentry_offset_populated = 0; + const int VM_FLAGS_NONE = 0; // quit extracting modules when this proc doesn't have mm (kernel thread, etc.) if ( !proc || -1UL == proc->cr3 @@ -137,9 +152,9 @@ static void get_new_modules(CPUState* env, process * proc) 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)) - return; + // // see if vm_area is populated already + // if (populate_vm_area_struct_offsets(env, vma_next, &OFFSET_PROFILE)) + // return; for (size_t count = MAX_LOOP_COUNT; count--; ) { @@ -153,15 +168,15 @@ static void get_new_modules(CPUState* env, process * proc) if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_file, sizeof(target_ptr), &vma_file) < 0 || !vma_file) goto next; - if (!offset_populated && (offset_populated = !getDentryFromFile(env, vma_file, &OFFSET_PROFILE))) // populate dentry offset - goto next; + // if (!offset_populated && (offset_populated = !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 (!dentry_offset_populated && (dentry_offset_populated = !populate_dentry_struct_offsets(env, f_dentry, &OFFSET_PROFILE))) - goto next; // notice this time we are not going to reset mark-bit. all plugins are populated by far + // if (!dentry_offset_populated && (dentry_offset_populated = !populate_dentry_struct_offsets(env, f_dentry, &OFFSET_PROFILE))) + // goto next; // notice this time we are not going to reset mark-bit. all plugins are populated by far if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_flags, sizeof(target_ulong), &vma_vm_flags) < 0) @@ -199,7 +214,14 @@ static void get_new_modules(CPUState* env, process * proc) && vma_vm_pgoff != 0) { mod_stage = 2; mod_vm_end = vma_vm_end; - } else { + } + else if(VM_FLAGS_NONE == (vma_vm_flags & 0xf) && !mod_name.compare(name) + && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0) { + mod_stage = 1; + mod_vm_end = vma_vm_end; + } + else { mod_stage = 0; } break; @@ -230,6 +252,8 @@ static void get_new_modules(CPUState* env, process * proc) if (!three_sections_found) goto next; + three_sections_found = false; + mod = VMI_find_module_by_key(mod_name.c_str()); if (!mod) { mod = new module(); @@ -244,8 +268,8 @@ static void get_new_modules(CPUState* env, process * proc) if(VMI_find_module_by_base(proc->cr3, mod_vm_start) != mod) { VMI_insert_module(proc->pid, mod_vm_start, mod); //if (proc->pid == 1) - monitor_printf(default_mon, "Module (%s, 0x%08x->0x%08x, size %u) is loaded to proc %s (pid = %d) \n", - mod_name.c_str(), mod_vm_start, mod_vm_end, mod->size / 1024, proc->name, proc->pid); + // monitor_printf(default_mon, "Module (%s, 0x%08x->0x%08x, size %u) is loaded to proc %s (pid = %d) \n", + // mod_name.c_str(), mod_vm_start, mod_vm_end, mod->size / 1024, proc->name, proc->pid); } @@ -357,26 +381,390 @@ static void get_new_modules(CPUState* env, process * proc) } } +// get new modules for arm, remains to be improved +static void get_new_modules_arm(CPUState* env, process * proc) +{ + target_ulong ts_mm, mm_mmap, vma_file, vma_next, f_dentry; + const int MAX_LOOP_COUNT = 1024; // prevent infinite loop + target_ulong vma_vm_start = 0, vma_vm_end = 0, vma_vm_flags, vma_vm_pgoff; + target_ulong last_vm_start = 0, last_vm_end = 0; + char name[32], key[128]; // module file path + string last_mod_name, mod_name; + target_ulong mod_vm_start, mod_vm_end; + module* mod = NULL; + string _name; + set module_bases; + bool finished_traversal = false; + int mod_stage = 0; + bool two_sections_found = false; + static int offset_populated = 0, dentry_offset_populated = 0; + const int VM_FLAGS_RX = 5; + const int VM_FLAGS_NONE = 0; + const int VM_FLAGS_RWX = 7; + + // quit extracting modules when this proc doesn't have mm (kernel thread, etc.) + if ( !proc || -1UL == proc->cr3 + || DECAF_read_mem(env, proc->EPROC_base_addr + OFFSET_PROFILE.ts_mm, sizeof(target_ptr), &ts_mm) < 0 + || 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)) + // 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 (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 (!offset_populated && (offset_populated = !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 (!dentry_offset_populated && (dentry_offset_populated = !populate_dentry_struct_offsets(env, f_dentry, &OFFSET_PROFILE))) + // goto next; // notice this time we are not going to reset mark-bit. all plugins are populated by far + + + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_flags, sizeof(target_ulong), &vma_vm_flags) < 0) + goto next; + + if (DECAF_read_mem(env, vma_next + OFFSET_PROFILE.vma_vm_pgoff, sizeof(target_ulong), &vma_vm_pgoff) < 0) + 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 + + switch(mod_stage) { + case 0: + //READ + EXECUTE + if (VM_FLAGS_RX == (vma_vm_flags & 0xf) && /*vma_vm_pgoff == 0 &&*/ strlen(name)) { + mod_stage = 1; + mod_name = name; + mod_vm_start = vma_vm_start; + mod_vm_end = vma_vm_end; + } + break; + + case 1: + if (VM_FLAGS_RX == (vma_vm_flags & 0xf) && /*vma_vm_pgoff == 0 && */strlen(name)) { + mod_stage = 1; + mod_name = name; + mod_vm_start = vma_vm_start; + mod_vm_end = vma_vm_end; + } else if (VM_FLAGS_RWX == (vma_vm_flags & 0xf) && !mod_name.compare(name) + && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0 ) { + //Now we have seen all two sections in order + //We can insert the module now. + mod_vm_end = vma_vm_end; + two_sections_found = true; + mod_stage = 0; + } + else if(VM_FLAGS_NONE == (vma_vm_flags & 0xf) && !mod_name.compare(name) + && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0) { + mod_stage = 1; + mod_vm_end = vma_vm_end; + } else { + mod_stage = 0; + } + break; + + default: + assert(0); break; + } + + if (!two_sections_found) + goto next; + + two_sections_found = false; + + mod = VMI_find_module_by_key(mod_name.c_str()); + if (!mod) { + mod = new module(); + strncpy(mod->name, mod_name.c_str(), 31); + mod->name[31] = '\0'; + mod->size = mod_vm_end - mod_vm_start; + VMI_add_module(mod, mod_name.c_str()); + } + + module_bases.insert(mod_vm_start); + + if(VMI_find_module_by_base(proc->cr3, mod_vm_start) != mod) { + VMI_insert_module(proc->pid, mod_vm_start, mod); + //if (proc->pid == 1) + // monitor_printf(default_mon, "Module (%s, 0x%08x->0x%08x, size %u) is loaded to proc %s (pid = %d) \n", + // mod_name.c_str(), mod_vm_start, mod_vm_end, mod->size / 1024, proc->name, proc->pid); + } +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) { + finished_traversal = true; + break; + } + } + + if (finished_traversal) { + unordered_map::iterator iter = proc->module_list.begin(); + set bases_to_remove; + for(; iter!=proc->module_list.end(); iter++) { + if (module_bases.find(iter->first) == module_bases.end()) + bases_to_remove.insert(iter->first); + } + + set::iterator iter2; + for (iter2=bases_to_remove.begin(); iter2!=bases_to_remove.end(); iter2++) { + if (proc->pid == 1) + monitor_printf(default_mon, "removed module %08x\n", *iter2); + + VMI_remove_module(proc->pid, *iter2); + + } + + } +} + +// void get_new_modules_mips(CPUState* env, process * proc) __attribute__((optimize("O0"))); +static +void get_new_modules_mips(CPUState* env, process * proc) +{ + target_ulong ts_mm, mm_mmap, vma_file, vma_next, f_dentry; + const int MAX_LOOP_COUNT = 1024; // prevent infinite loop + target_ulong vma_vm_start = 0, vma_vm_end = 0, vma_vm_flags, vma_vm_pgoff; + target_ulong last_vm_start = 0, last_vm_end = 0; + char name[32], key[128]; // module file path + string last_mod_name, mod_name; + target_ulong mod_vm_start, mod_vm_end; + module* mod = NULL; + string _name; + set module_bases; + bool finished_traversal = false; + int mod_stage = 0; + bool three_sections_found = false; + static int offset_populated = 0, dentry_offset_populated = 0; + const int VM_FLAGS_RX = 5; + const int VM_FLAGS_NONE = 0; + const int VM_FLAGS_R = 1; + const int VM_FLAGS_RWX = 7; + const int VM_FLAGS_RW = 3; + // puts("here"); + // quit extracting modules when this proc doesn't have mm (kernel thread, etc.) + if ( !proc || -1UL == proc->cr3 + || DECAF_read_ptr(env, proc->EPROC_base_addr + OFFSET_PROFILE.ts_mm, &ts_mm) < 0 + || ts_mm < 0) + return; + // read vma from mm first, then traverse mmap + if (DECAF_read_ptr(env, ts_mm + OFFSET_PROFILE.mm_mmap, &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)) + // return; + + for (size_t count = MAX_LOOP_COUNT; count--; ) { + + // read current vma's size + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_start, &vma_vm_start) < 0) + goto next; + + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_end, &vma_vm_end) < 0) + goto next; + + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_file, &vma_file) < 0 || !vma_file) + goto next; + + // if (!offset_populated && (offset_populated = !getDentryFromFile(env, vma_file, &OFFSET_PROFILE))) // populate dentry offset + // goto next; + + + if (DECAF_read_ptr(env, vma_file + OFFSET_PROFILE.file_dentry, &f_dentry) < 0 || !f_dentry) + goto next; + + // if (!dentry_offset_populated && (dentry_offset_populated = !populate_dentry_struct_offsets(env, f_dentry, &OFFSET_PROFILE))) + // goto next; // notice this time we are not going to reset mark-bit. all plugins are populated by far + + + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_flags, &vma_vm_flags) < 0) + goto next; + + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_pgoff, &vma_vm_pgoff) < 0) + 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 + + switch(mod_stage) { + case 0: + if ((vma_vm_flags & 0xf) == VM_FLAGS_RX && /*vma_vm_pgoff == 0 &&*/ strlen(name)) { + mod_stage = 1; + mod_name = name; + mod_vm_start = vma_vm_start; + mod_vm_end = vma_vm_end; + } + break; + + case 1: + if ((vma_vm_flags & 0xf) == VM_FLAGS_RX && /*vma_vm_pgoff == 0 && */strlen(name)) { + mod_stage = 1; + mod_name = name; + mod_vm_start = vma_vm_start; + mod_vm_end = vma_vm_end; + } //READ ONLY + else if((vma_vm_flags & 0xf) == VM_FLAGS_R && !mod_name.compare(name) + // && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0) { + mod_stage = 2; + mod_vm_end = vma_vm_end; + } + else if((vma_vm_flags & 0xf) == VM_FLAGS_NONE && !mod_name.compare(name)) + { + mod_stage = 1; + mod_name = name; + mod_vm_end = vma_vm_end; + } else if ((vma_vm_flags & 0xf) == VM_FLAGS_RW && !mod_name.compare(name) + // && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0 ) { + //Now we have seen all three sections in order + //We can insert the module now. + mod_vm_end = vma_vm_end; + three_sections_found = true; + mod_stage = 0; + } + else { + mod_stage = 0; + } + break; + + case 2: + if ((vma_vm_flags & 0xf) == VM_FLAGS_RX && /*vma_vm_pgoff == 0 &&*/ strlen(name)) { + mod_stage = 1; + mod_name = name; + mod_vm_start = vma_vm_start; + mod_vm_end = vma_vm_end; + } else if ((vma_vm_flags & 0xf) == VM_FLAGS_RW && !mod_name.compare(name) + // && vma_vm_start == mod_vm_end + && vma_vm_pgoff != 0 ) { + //Now we have seen all three sections in order + //We can insert the module now. + mod_vm_end = vma_vm_end; + three_sections_found = true; + mod_stage = 0; + } else { + mod_stage = 0; + } + break; + + default: + assert(0); break; + } + + if (!three_sections_found) + goto next; + + three_sections_found = false; + + mod = VMI_find_module_by_key(mod_name.c_str()); + if (!mod) { + mod = new module(); + strncpy(mod->name, mod_name.c_str(), 31); + mod->name[31] = '\0'; + mod->size = mod_vm_end - mod_vm_start; + VMI_add_module(mod, mod_name.c_str()); + } + + module_bases.insert(mod_vm_start); + + if(VMI_find_module_by_base(proc->cr3, mod_vm_start) != mod) { + VMI_insert_module(proc->pid, mod_vm_start, mod); + //if (proc->pid == 1) + // monitor_printf(default_mon, "Module (%s, 0x%08x->0x%08x, size %u) is loaded to proc %s (pid = %d) \n", + // mod_name.c_str(), mod_vm_start, mod_vm_end, mod->size / 1024, proc->name, proc->pid); + } + +next: + if (DECAF_read_ptr(env, vma_next + OFFSET_PROFILE.vma_vm_next, &vma_next) < 0) + break; + if (!vma_next || vma_next == mm_mmap) { + finished_traversal = true; + break; + } + } + + if (finished_traversal) { + unordered_map::iterator iter = proc->module_list.begin(); + set bases_to_remove; + for(; iter!=proc->module_list.end(); iter++) { + if (module_bases.find(iter->first) == module_bases.end()) + bases_to_remove.insert(iter->first); + } + + set::iterator iter2; + for (iter2=bases_to_remove.begin(); iter2!=bases_to_remove.end(); iter2++) { + if (proc->pid == 1) + monitor_printf(default_mon, "removed module %08x\n", *iter2); + + VMI_remove_module(proc->pid, *iter2); + + } + + } +} + + + +// process * find_new_process(CPUState *env, uint32_t cr3) __attribute__((optimize("O0"))); // scan the task list and find new process -static process * find_new_process(CPUState *env, uint32_t cr3) { +static +process * find_new_process(CPUState *env, uint32_t cr3) { uint32_t task_pid = 0, ts_parent_pid = 0, proc_cr3 = -1; -#define MAX_LOOP_COUNT 1024 // maximum loop count when trying to find a new process (will there be any?) - uint32_t count = MAX_LOOP_COUNT; // avoid infinite loop + const int MAX_LOOP_COUNT = 1024; // maximum loop count when trying to find a new process (will there be any?) process *right_proc = NULL; //static target_ulong _last_next_task = 0;// another way to speed up: when the last task remain the same, return immediately //uint32_t _last_task_pid = last_task_pid; - for (target_ulong next_task = OFFSET_PROFILE.init_task_addr, ts_real_parent, - mm, task_pgd; count--;) { + target_ulong next_task, ts_real_parent, mm, task_pgd; + next_task = OFFSET_PROFILE.init_task_addr; + + // avoid infinite loop + for (int count = MAX_LOOP_COUNT; count > 0; --count) + { // NOTICE by reading next_task at the beginning, we are skipping the "swapper" task // highly likely linux add the latest process to the tail of the linked list, so we go backward here - if (DECAF_read_mem(env, - next_task + (OFFSET_PROFILE.ts_tasks + sizeof(target_ptr)), - sizeof(target_ptr), &next_task) < 0) - break; + BREAK_IF(DECAF_read_ptr(env, + next_task + (OFFSET_PROFILE.ts_tasks + sizeof(target_ptr)), + &next_task) < 0); // NOTE - tasks is a list_head, so we need to minus offset to get the base address next_task -= OFFSET_PROFILE.ts_tasks; @@ -385,53 +773,60 @@ static process * find_new_process(CPUState *env, uint32_t cr3) { break; }*/ - // read task pid, jump out directly when we fail - if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_tgid, - sizeof(target_ulong), &task_pid) < 0) - break; - - if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_mm, - sizeof(target_ptr), &mm) < 0) { + if(OFFSET_PROFILE.init_task_addr == next_task) + { break; } - // NOTICE kernel thread does not own a process address space, thus its mm is NULL. It uses active_mm instead - if (populate_mm_struct_offsets(env, mm, &OFFSET_PROFILE)) - continue; // try until we get it. + // read task pid, jump out directly when we fail + BREAK_IF(DECAF_read_ptr(env, + next_task + OFFSET_PROFILE.ts_tgid, + &task_pid) < 0); + + BREAK_IF(DECAF_read_ptr(env, + next_task + OFFSET_PROFILE.ts_mm, + &mm) < 0); - if (mm != 0) { // for user-processes + // // NOTICE kernel thread does not own a process address space, thus its mm is NULL. It uses active_mm instead + // if (populate_mm_struct_offsets(env, mm, &OFFSET_PROFILE)) + // continue; // try until we get it. + + if (mm != 0) + { // for user-processes // we read the value of active_mm into mm here - if (DECAF_read_mem(env, + BREAK_IF(DECAF_read_ptr(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) { - break; - } + &mm) < 0 + || + DECAF_read_ptr(env, + mm + OFFSET_PROFILE.mm_pgd, + &task_pgd) < 0); + proc_cr3 = DECAF_get_phys_addr(env, task_pgd); - } else { // for kernel threads + } + else + { // for kernel threads proc_cr3 = -1;// when proc_cr3 is -1UL, we cannot find the process by findProcessByCR3(), but we still can do findProcessByPid() } if (!VMI_find_process_by_pgd(proc_cr3)) { // 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 - || DECAF_read_mem(env, - ts_real_parent + OFFSET_PROFILE.ts_tgid, - sizeof(target_ulong), &ts_parent_pid) < 0) { - break; - } + BREAK_IF(DECAF_read_ptr(env, + next_task + OFFSET_PROFILE.ts_real_parent, + &ts_real_parent) < 0 + || + DECAF_read_ptr(env, + ts_real_parent + OFFSET_PROFILE.ts_tgid, + &ts_parent_pid) < 0); 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 - if (DECAF_read_mem(env, next_task + OFFSET_PROFILE.ts_comm, - SIZEOF_COMM, pe->name) < 0) { - break; - } + BREAK_IF(DECAF_read_mem(env, + next_task + OFFSET_PROFILE.ts_comm, + SIZEOF_COMM, pe->name) < 0); VMI_create_process(pe); //monitor_printf(default_mon, "new proc = %s, pid = %d, parent_pid = %d \n", pe->name, pe->pid, pe->parent_pid); @@ -460,19 +855,24 @@ static void retrive_symbols(CPUState *env, process * proc) { // for every tlb call back, we try finding new processes -static void Linux_tlb_call_back(DECAF_Callback_Params *temp) { - CPUState *env = temp->tx.env; +// static +// void Linux_tlb_call_back(DECAF_Callback_Params *temp) __attribute__((optimize("O0"))); +void Linux_tlb_call_back(DECAF_Callback_Params *temp) +{ + CPUState *ourenv = temp->tx.env; uint32_t vaddr = temp->tx.vaddr; - uint32_t cr3 = DECAF_getPGD(env); + uint32_t pgd = -1; process *proc = NULL; bool found_new = false; + pgd = DECAF_getPGD(ourenv); + //TODO: kernel modules are not retrieved in the current implementation. - if (DECAF_is_in_kernel()) { + if (DECAF_is_in_kernel(ourenv)) { //proc = kernel_proc; } - else if ( (proc = VMI_find_process_by_pgd(cr3)) == NULL) { - found_new = ((proc = find_new_process(env, cr3)) != NULL); + else if ( (proc = VMI_find_process_by_pgd(pgd)) == NULL) { + found_new = ((proc = find_new_process(ourenv, pgd)) != NULL); } if (proc) { // we are not scanning modules for kernel threads, since kernel thread's cr3 is -1UL, the proc should be null @@ -480,13 +880,13 @@ static void Linux_tlb_call_back(DECAF_Callback_Params *temp) { if ( !is_vm_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) + && !DECAF_read_mem(ourenv, proc->EPROC_base_addr + OFFSET_PROFILE.ts_comm, SIZEOF_COMM, task_comm) && strncmp(proc->name, task_comm, SIZEOF_COMM) ) { strcpy(proc->name, task_comm); //message_p(proc, '^'); } - get_new_modules(env, proc); + get_new_modules(ourenv, proc); //If this page still cannot be resolved, we give up. if (!is_vm_page_resolved(proc, vaddr)) { @@ -503,7 +903,8 @@ static void Linux_tlb_call_back(DECAF_Callback_Params *temp) { // here we scan the task list in guest OS and sync ours with it static void check_procexit(void *) { - CPUState *env = cpu_single_env ? cpu_single_env : first_cpu; + /* AWH - cpu_single_env is invalid outside of the main exec thread */ + CPUState *env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; qemu_mod_timer(recon_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * 10); @@ -512,24 +913,30 @@ static void check_procexit(void *) { set vmi_pids; set dead_pids; -#define MAX_LOOP_COUNT 1024 + const int MAX_LOOP_COUNT = 1024; - for(int i=0; i::iterator iter = process_pid_map.begin(); - for(; iter != process_pid_map.end(); iter++) { + for(; iter != process_pid_map.end(); iter++) + { vmi_pids.insert(iter->first); } @@ -537,7 +944,8 @@ static void check_procexit(void *) { inserter(dead_pids, dead_pids.end())); set::iterator iter2; - for(iter2 = dead_pids.begin(); iter2 != dead_pids.end(); iter2++) { + for(iter2 = dead_pids.begin(); iter2 != dead_pids.end(); iter2++) + { VMI_remove_process(*iter2); } @@ -580,22 +988,36 @@ int find_linux(CPUState *env, uintptr_t insn_handle) { return 0; // first time run if (_last_thread_info == 0) - memset(&OFFSET_PROFILE.init_task_addr, -1, sizeof(ProcInfo) - sizeof(OFFSET_PROFILE.strName)); + { + // memset(&OFFSET_PROFILE.init_task_addr, -1, sizeof(ProcInfo) - sizeof(OFFSET_PROFILE.strName)); + } _last_thread_info = _thread_info; - // try populate kernel offset, NOTICE we cannot get mm_struct offset yet - if (populate_kernel_offsets(env, _thread_info, &OFFSET_PROFILE) != 0) - return (0); + // ProcInfo temp_offset_profile; + // // try populate kernel offset, NOTICE we cannot get mm_struct offset yet + // if (populate_kernel_offsets(env, _thread_info, &temp_offset_profile) != 0) + // return (0); + + if(0 != load_proc_info(env, _thread_info, OFFSET_PROFILE)) + { + return 0; + } monitor_printf(default_mon, "swapper task @ [%08x] \n", OFFSET_PROFILE.init_task_addr); + // load library function offset + load_library_info(OFFSET_PROFILE.strName); + + // load_proc_info(OFFSET_PROFILE, temp_offset_profile.init_task_addr); //printProcInfo(&OFFSET_PROFILE); VMI_guest_kernel_base = 0xc0000000; return (1); } + + // when we know this is a linux void linux_vmi_init() { @@ -608,3 +1030,24 @@ void linux_vmi_init() } + +gpa_t mips_get_cur_pgd(CPUState *env) +{ + const target_ulong MIPS_KERNEL_BASE = 0x80000000; + gpa_t pgd = 0; + if(0 == OFFSET_PROFILE.mips_pgd_current) + { + monitor_printf(default_mon, "Error\nmips_get_cur_pgd: read pgd before procinfo is populated.\n"); + return 0; + } + + DECAF_read_ptr(env, + OFFSET_PROFILE.mips_pgd_current, + &pgd); + pgd &= ~MIPS_KERNEL_BASE; + return pgd; +} + + + + diff --git a/shared/linux_vmi.h b/shared/linux_vmi.h index 8c7ff30..0d78092 100644 --- a/shared/linux_vmi.h +++ b/shared/linux_vmi.h @@ -38,6 +38,7 @@ extern "C" { int find_linux(CPUState *env, uintptr_t insn_handle); void linux_vmi_init(); +gpa_t mips_get_cur_pgd(CPUState *env); #ifdef __cplusplus }; diff --git a/shared/tainting/DECAF_taint_helper.h b/shared/tainting/DECAF_taint_helper.h index 8991da0..d7e5556 100644 --- a/shared/tainting/DECAF_taint_helper.h +++ b/shared/tainting/DECAF_taint_helper.h @@ -42,6 +42,10 @@ 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). */ +#if 0 // AWH - Duplication of DECAF_callback_to_QEMU.h +DEF_HELPER_2(DECAF_invoke_log_pointer_write, void, i32, i32) +DEF_HELPER_2(DECAF_invoke_log_pointer_read, void, i32, i32) +#endif // AWH DEF_HELPER_2(taint_log_pointer, void, i32, i32) /* 5 parms: (VC, VC, VC, V, V) */ DEF_HELPER_8(taint_log_deposit_i32, void, i32, i32, i32, i32, i32, i32, i32, i32) diff --git a/shared/tainting/taint_memory.c b/shared/tainting/taint_memory.c index 0dc8c25..c854c8b 100644 --- a/shared/tainting/taint_memory.c +++ b/shared/tainting/taint_memory.c @@ -5,7 +5,7 @@ #include "taint_memory.h" #include "monitor.h" // For default_mon #include "DECAF_callback_common.h" - +#include "shared/DECAF_callback_to_QEMU.h" #ifdef CONFIG_TCG_TAINT @@ -454,7 +454,7 @@ void REGPARM __taint_stq_raw(unsigned long addr, gva_t vaddr) { } -uint32_t calc_tainted_bytes(){ +uint32_t calc_tainted_bytes(void){ uint32_t tainted_bytes, i; uint32_t leaf_index; uint32_t middle_index; @@ -573,7 +573,7 @@ int do_tainted_bytes(Monitor *mon,const QDict *qdict,QObject **ret_data){ tainted_bytes=calc_tainted_bytes(); monitor_printf(default_mon,"Tainted memory: %d bytes\n",tainted_bytes); } - + return 0; } int do_taint_mem_usage(Monitor *mon, const QDict *qdict, QObject **ret_data) { if (!taint_tracking_enabled) @@ -591,7 +591,7 @@ int do_garbage_collect_taint(Monitor *mon, const QDict *qdict, QObject **ret_dat monitor_printf(default_mon, "Ignored, taint tracking is disabled\n"); else { - int prior_middle, prior_leaf, present_middle, present_leaf; + int prior_middle, prior_leaf/*, present_middle, present_leaf*/; prior_middle = middle_nodes_in_use; prior_leaf = leaf_nodes_in_use; diff --git a/shared/tainting/taintcheck_opt.c b/shared/tainting/taintcheck_opt.c index 8f16353..efdcecb 100644 --- a/shared/tainting/taintcheck_opt.c +++ b/shared/tainting/taintcheck_opt.c @@ -172,8 +172,6 @@ int taintcheck_init(void) void taintcheck_cleanup(void) { - int i; - //clean nic buffer bzero(nic_bitmap, sizeof(nic_bitmap)); //clean disk @@ -260,6 +258,12 @@ int taintcheck_check_virtmem(uint32_t vaddr, uint32_t size, uint8_t * taint) CPUState *env; env = cpu_single_env ? cpu_single_env : first_cpu; + // AWH - If tainting is disabled, return no taint + if (!taint_tracking_enabled) { + *taint = 0; + return 1; + } + paddr = DECAF_get_phys_addr(env,vaddr); if(paddr == -1) return 0; offset = vaddr& ~TARGET_PAGE_MASK; diff --git a/shared/tainting/taintcheck_opt.h b/shared/tainting/taintcheck_opt.h index 6fae4db..4453b54 100644 --- a/shared/tainting/taintcheck_opt.h +++ b/shared/tainting/taintcheck_opt.h @@ -35,8 +35,8 @@ 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; + return (size < 4) ? (env->active_tc.taint_gpr[regid]>>off) + &size_to_mask(size):env->active_tc.taint_gpr[regid]>>off; #else return (size < 4) ? (env->taint_regs[regid]>>off)&size_to_mask(size): env->taint_regs[regid]>>off; @@ -108,7 +108,17 @@ int taintcheck_chk_hdread(const ram_addr_t paddr, const unsigned long vaddr,cons int taintcheck_chk_hdwrite(const ram_addr_t paddr, const unsigned long vaddr,const int size, const int64_t sect_num, const void *s); +int taintcheck_taint_disk(const uint64_t index, const uint32_t taint, const int offset, const int size, const void *bs); +uint32_t taintcheck_disk_check(const uint64_t index, const int offset, const int size, const void *bs); + +int taintcheck_init(void); + +void taintcheck_cleanup(void); + +int taintcheck_chk_hdin(const int size, const int64_t sect_num, const uint32_t offset, const void *s); + +int taintcheck_chk_hdout(const int size, const int64_t sect_num, const uint32_t offset, const void *s); #endif /* CONFIG_TCG_TAINT */ #ifdef __cplusplus diff --git a/shared/tainting/tainting.c b/shared/tainting/tainting.c index bc81bea..2e1afad 100644 --- a/shared/tainting/tainting.c +++ b/shared/tainting/tainting.c @@ -14,6 +14,7 @@ If you have any questions about DECAF,please post it on http://code.google.com/p/decaf-platform/ */ #include "shared/tainting/tainting.h" +#include "shared/tainting/taint_memory.h" void tainting_init(void) { diff --git a/shared/tainting/tcg_taint.c b/shared/tainting/tcg_taint.c index 959b936..eacc628 100644 --- a/shared/tainting/tcg_taint.c +++ b/shared/tainting/tcg_taint.c @@ -16,12 +16,8 @@ #include "config-target.h" #include "helper.h" // Taint helper functions, plus I386 IN/OUT helpers -//#include "tcg_taint_branch.h" #include "DECAF_callback_common.h" -//#define BLOCK_SKIP_GREATER_EQUAL 68 -//#define BLOCK_SKIP_LESS_EQUAL 66 -//#define ALLOW_BSLE 1 -//#define ALLOW_BSGE 1 +#include "DECAF_callback_to_QEMU.h" /* Target-specific metadata buffers are extern'd here so that the taint IR insertions can update them. */ @@ -50,19 +46,16 @@ typedef CPUMIPSState OurCPUState; #endif /* TARGET_I386/ARM */ // AWH - In development -//#define TCG_LOGGING_TAINT 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) +#if 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) { @@ -80,50 +73,6 @@ TCGv tempidx, tempidx2; // Extern in translate.c extern TCGv_ptr cpu_env; - -#ifdef TCG_LOGGING_TAINT -#if 0 // AWH -/* 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]; -#endif // AWH -/* 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 12 -static TCGv taint_log_temps[MAX_TAINT_LOG_TEMPS]; - -/* Used for building up lists of args for the logging helper funcs */ -static TCGArg helper_arg_array[MAX_TAINT_LOG_TEMPS]; - -static inline void set_concrete_i32(int index, TCGv arg) -{ - 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); - helper_arg_array[index] = taint_log_temps[index]; -} - -static inline void set_arg_i32(int index, TCGv arg) -{ - tcg_gen_movi_i32(taint_log_temps[index], arg); - helper_arg_array[index] = taint_log_temps[index]; -} -#endif /* TCG_LOGGING_TAINT */ - /*static*/ TCGv find_shadow_arg(TCGv arg) { if (arg < tcg_ctx.nb_globals) @@ -215,11 +164,14 @@ static inline int gen_taintcheck_insn(int search_pc) int nb_args=0; int opc_index=0, opparam_index=0; - int i=0, x=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, t4, t5, t6, t_zero; + TCGv arg0, arg1, arg2, arg3, arg4, arg5; + TCGv t0, t1, t2, t3, t4, t_zero; +#if defined(TARGET_I386) + TCGv arg6, t5, t6; +#endif /* TARGET check */ TCGv orig0, orig1, orig2, orig3, orig4, orig5; /* Copy all of the existing ops/parms into a new buffer to back them up. */ @@ -249,7 +201,7 @@ static inline int gen_taintcheck_insn(int search_pc) gen_opc_ptr = gen_old_opc_ptr; gen_opparam_ptr = gen_old_opparam_ptr; -#if defined(TCG_LOGGING_TAINT) || defined(LOG_POINTER) || defined(LOG_TAINTED_EIP) +#if 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 @@ -257,7 +209,7 @@ static inline int gen_taintcheck_insn(int search_pc) #else taint_log_temps[i] = tcg_temp_new_i64(); #endif /* TCG_TARGET_REG_BITS */ -#endif /* TCG_LOGGING_TAINT */ +#endif /* LOG_ check */ /* Copy and instrument the opcodes that need taint tracking */ while(opc_index < nb_opc) { @@ -305,20 +257,6 @@ 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; -#if 0 //defined(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. */ -#ifdef TCG_TAINT_LOGGING - gen_opc_opt_immune_metadata[opc_index-1] = 0; -#endif /* TCG_TAINT_BRANCHING */ - goto skip_instrumentation; - } -#endif /* USE_TCG_OPTIMIZATIONS */ switch(opc) { @@ -428,10 +366,6 @@ static inline int gen_taintcheck_insn(int search_pc) #endif // AWH #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 */ } #ifdef TARGET_I386 #define HELPER_SECTION_FIVE @@ -473,22 +407,6 @@ static inline int gen_taintcheck_insn(int search_pc) gen_opparam_ptr -= 5; 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, pos); - set_arg_i32(4, len); - //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, 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) @@ -526,25 +444,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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); - set_arg_i32(2, orig2); - 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); -#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(); @@ -577,11 +476,6 @@ static inline int gen_taintcheck_insn(int search_pc) tcg_gen_setcond_i32(TCG_COND_NE, t2, t0, t_zero); // Reuse t2 tcg_gen_neg_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_op6i_i32(INDEX_op_setcond2_i32, orig0, orig1, orig2, orig3, orig4, orig5); } @@ -626,15 +520,6 @@ static inline int gen_taintcheck_insn(int search_pc) gen_opparam_ptr -= 2; gen_opc_ptr--; -#ifdef TCG_LOGGING_TAINT -#ifdef LOG_MOVI_I32 - /* Insert logging */ - set_arg_i32(0, orig0); - //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); @@ -655,17 +540,6 @@ static inline int gen_taintcheck_insn(int search_pc) gen_opparam_ptr -= 2; gen_opc_ptr--; -#ifdef TCG_LOGGING_TAINT -#ifdef LOG_MOV_I32 - /* Insert logging */ - set_arg_i32(0, orig0); - set_arg_i32(1, 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 */ tcg_gen_mov_i32(arg0, arg1); @@ -693,17 +567,12 @@ static inline int gen_taintcheck_insn(int search_pc) /* 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]; + // 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(); @@ -764,10 +633,6 @@ 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; @@ -1097,21 +962,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 6, helper_arg_array); -#endif /* LOG_DEPOSIT_I32 */ -#endif /* TCG_LOGGING_TAINT */ - if (arg1 && arg2) { t0 = tcg_temp_new_i32(); tcg_gen_or_i32(t0, arg1, arg2); @@ -1158,20 +1008,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 5, helper_arg_array); -#endif /* LOG_SHL_I32 */ -#endif /* TCG_LOGGING_TAINT */ - /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); @@ -1221,20 +1057,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 5, helper_arg_array); -#endif /* LOG_SHR_I32 */ -#endif /* TCG_LOGGING_TAINT */ - /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); @@ -1284,20 +1106,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 5, helper_arg_array); -#endif /* LOG_SAR_I32 */ -#endif /* TCG_LOGGING_TAINT */ - /* Insert taint IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); @@ -1348,20 +1156,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 5, helper_arg_array); -#endif /* LOG_ROTL_I32 */ -#endif /* TCG_LOGGING_TAINT */ - /* Insert tainting IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); @@ -1411,20 +1205,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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_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, 5, helper_arg_array); -#endif /* LOG_ROTR_I32 */ -#endif /* TCG_LOGGING_TAINT */ - /* Insert tainting IR */ if (!arg1 && !arg2) { tcg_gen_movi_i32(arg0, 0); @@ -1600,19 +1380,6 @@ static inline int gen_taintcheck_insn(int search_pc) 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); /* Reinsert original opcode */ @@ -3008,9 +2775,6 @@ static inline int gen_taintcheck_insn(int search_pc) assert(1==0); break; } /* End switch */ -//#ifdef USE_TCG_OPTIMIZATIONS - skip_instrumentation:; -//#endif /* USE_TCG_OPTIMIZATIONS */ } /* End taint while loop */ return return_lj; diff --git a/shared/utils/SimpleCallback.c b/shared/utils/SimpleCallback.c index 32f62cd..92ca238 100644 --- a/shared/utils/SimpleCallback.c +++ b/shared/utils/SimpleCallback.c @@ -133,7 +133,7 @@ void SimpleCallback_dispatch(SimpleCallback_t* pList, void* params) if (pList == NULL) { - return (NULL_POINTER_ERROR); + return; // (NULL_POINTER_ERROR); } //FIXME: not thread safe diff --git a/shared/vmi.cpp b/shared/vmi.cpp index 0edb5ed..2659c3c 100644 --- a/shared/vmi.cpp +++ b/shared/vmi.cpp @@ -112,7 +112,7 @@ static void block_end_cb(DECAF_Callback_Params* temp) } -process* VMI_find_process_by_name(char *name) +process* VMI_find_process_by_name(const char *name) { unordered_map < uint32_t, process * >::iterator iter; for (iter = process_map.begin(); iter != process_map.end(); iter++) { @@ -396,7 +396,6 @@ int VMI_remove_module(uint32_t pid, uint32_t base) proc->module_list.erase(m_iter); -// delete mod; return 0; } diff --git a/shared/vmi.h b/shared/vmi.h index aa63e75..93800a5 100644 --- a/shared/vmi.h +++ b/shared/vmi.h @@ -84,7 +84,7 @@ process * VMI_find_process_by_pid(uint32_t pid); process * VMI_find_process_by_pgd(uint32_t pgd); -process* VMI_find_process_by_name(char *name); +process* VMI_find_process_by_name(const char *name); // add one module int VMI_add_module(module *mod, const char *key); diff --git a/shared/vmi_c_wrapper.cpp b/shared/vmi_c_wrapper.cpp index 7b876d0..a9e9b9a 100644 --- a/shared/vmi_c_wrapper.cpp +++ b/shared/vmi_c_wrapper.cpp @@ -62,19 +62,19 @@ using namespace std::tr1; #define PROCESS_NAME_SIZE 16 int VMI_locate_module_c(gva_t eip, gva_t cr3, char proc[],tmodinfo_t *tm) { - module * m = NULL; + module *m; + process *p; gva_t base = 0; - if(!tm) - { - DECAF_printf("tm is NULL"); + + p = VMI_find_process_by_pgd(cr3); + if (!p) return -1; - } - bzero(tm, sizeof(tmodinfo_t)); - m = VMI_find_module_by_pc(eip, cr3,&base); + + m = VMI_find_module_by_pc(eip, cr3, &base); if(!m) - return NULL; - strncpy(tm->name,m->name, MODULE_NAME_SIZE ) ; - strncpy(proc, m->name, MODULE_NAME_SIZE); + return -1; + strncpy(tm->name, m->name, MODULE_NAME_SIZE ) ; + strncpy(proc, p->name, sizeof(p->name)); tm->base = base; tm->size = m->size; return 0; @@ -124,7 +124,7 @@ int VMI_find_pid_by_cr3_c(uint32_t cr3) return p->cr3; } -int VMI_find_pid_by_name_c(char* proc_name) +int VMI_find_pid_by_name_c(const char* proc_name) { process *p = NULL; p = VMI_find_process_by_name(proc_name); @@ -276,7 +276,7 @@ int VMI_get_guest_version_c(void) return 2;//linux return 0;//unknown } -int VMI_get_current_tid_c(CPUState* env) +int VMI_get_current_tid_c(CPUState* _env) { #ifdef TARGET_I386 uint32_t val; @@ -289,12 +289,12 @@ int VMI_get_current_tid_c(CPUState* env) if (VMI_guest_kernel_base != 0x80000000) return -1; - if (!DECAF_is_in_kernel()) { // user module - if (DECAF_read_mem(env, cpu_single_env->segs[R_FS].base + 0x18, 4, &val) != -1 - && DECAF_read_mem(env, val + 0x24, 4, &tid) != -1) + if (!DECAF_is_in_kernel(_env)) { // user module + if (DECAF_read_mem(_env, /* AWH cpu_single*/_env->segs[R_FS].base + 0x18, 4, &val) != -1 + && DECAF_read_mem(_env, val + 0x24, 4, &tid) != -1) return tid; - } else if (DECAF_read_mem(env, cpu_single_env->segs[R_FS].base + 0x124, 4, &val) - != -1 && DECAF_read_mem(env, val + 0x1F0, 4, &tid) != -1) + } else if (DECAF_read_mem(_env, /* AWH cpu_single*/_env->segs[R_FS].base + 0x124, 4, &val) + != -1 && DECAF_read_mem(_env, val + 0x1F0, 4, &tid) != -1) return tid; #endif diff --git a/shared/vmi_c_wrapper.h b/shared/vmi_c_wrapper.h index d62dab7..db92d7a 100644 --- a/shared/vmi_c_wrapper.h +++ b/shared/vmi_c_wrapper.h @@ -55,7 +55,7 @@ extern int VMI_find_cr3_by_pid_c(uint32_t pid); extern int VMI_find_pid_by_cr3_c(uint32_t cr3); -extern int VMI_find_pid_by_name_c(char* proc_name); +extern int VMI_find_pid_by_name_c(const char* proc_name); /// @ingroup semantics /// find process given a memory space id diff --git a/shared/windows_vmi.cpp b/shared/windows_vmi.cpp index 5ac6265..9f9686e 100644 --- a/shared/windows_vmi.cpp +++ b/shared/windows_vmi.cpp @@ -161,16 +161,16 @@ static process * find_new_process(CPUState *env, uint32_t cr3) { } -static inline int get_IMAGE_NT_HEADERS(uint32_t cr3, uint32_t base, IMAGE_NT_HEADERS *nth) +static inline int get_IMAGE_NT_HEADERS(uint32_t cr3, uint32_t base, IMAGE_NT_HEADERS *nth, CPUState *_env) { IMAGE_DOS_HEADER DosHeader; - DECAF_read_mem(cpu_single_env, base, sizeof(IMAGE_DOS_HEADER), &DosHeader); + DECAF_read_mem(_env, base, sizeof(IMAGE_DOS_HEADER), &DosHeader); if (DosHeader.e_magic != (0x5a4d)) { return -1; } - if(DECAF_read_mem(cpu_single_env, base + DosHeader.e_lfanew, + if(DECAF_read_mem(_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); @@ -183,13 +183,13 @@ static inline int get_IMAGE_NT_HEADERS(uint32_t cr3, uint32_t base, IMAGE_NT_HEA //FIXME: this function may potentially overflow "buf" --Heng static inline int readustr_with_cr3(uint32_t addr, uint32_t cr3, void *buf, - CPUState *env) { + CPUState *_env) { uint32_t unicode_data[2]; int i, j, unicode_len = 0; uint8_t unicode_str[MAX_UNICODE_LENGTH] = { '\0' }; char *store = (char *) buf; - if (DECAF_read_mem(env, addr, sizeof(unicode_data), unicode_data) < 0) { + if (DECAF_read_mem(_env, addr, sizeof(unicode_data), unicode_data) < 0) { store[0] = '\0'; goto done; } @@ -198,7 +198,7 @@ static inline int readustr_with_cr3(uint32_t addr, uint32_t cr3, void *buf, if (unicode_len > MAX_UNICODE_LENGTH) unicode_len = MAX_UNICODE_LENGTH; - if (DECAF_read_mem(env, unicode_data[1], unicode_len, (void *) unicode_str) < 0) { + if (DECAF_read_mem(_env, unicode_data[1], unicode_len, (void *) unicode_str) < 0) { store[0] = '\0'; goto done; } @@ -262,7 +262,7 @@ static void update_kernel_modules(CPUState *env, target_ulong vaddr) { //uniquely identify a module. //We do not use full module name, because the same module can be referenced through //different full paths: e.g., c://windows/system32 and /systemroot/windows/system32. - if(get_IMAGE_NT_HEADERS(env->cr[3], base, &nth) < 0) + if(get_IMAGE_NT_HEADERS(env->cr[3], base, &nth, env) < 0) goto next; snprintf(key, sizeof(key)-1, "%s:%08x", base_name, nth.OptionalHeader.CheckSum); @@ -328,7 +328,7 @@ static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, //uniquely identify a module. //We do not use full module name, because the same module can be referenced through //different full paths: e.g., c://windows/system32 and /systemroot/windows/system32. - if(get_IMAGE_NT_HEADERS(cr3, base, &nth) < 0) + if(get_IMAGE_NT_HEADERS(cr3, base, &nth, env) < 0) goto next; snprintf(key, sizeof(key)-1, "%s:%08x", name, nth.OptionalHeader.CheckSum); @@ -355,7 +355,7 @@ static void update_loaded_user_mods_with_peb(CPUState* env, process *proc, } -static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t base, module *mod) +static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t base, module *mod, CPUState *_env) { IMAGE_EXPORT_DIRECTORY ied; DWORD edt_va, edt_size; @@ -363,11 +363,11 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b WORD *ordinals=NULL; char name[64]; DWORD i; - CPUState *env = cpu_single_env; + //CPUState *env = cpu_single_env; edt_va = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; edt_size = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - if(DECAF_read_mem(env, 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; @@ -384,17 +384,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(env, base + ied.AddressOfFunctions, + if(DECAF_read_mem(_env, base + ied.AddressOfFunctions, sizeof(DWORD) * ied.NumberOfFunctions, func_addrs) < 0) { goto done; } - if(DECAF_read_mem(env, base + ied.AddressOfNames, + if(DECAF_read_mem(_env, base + ied.AddressOfNames, sizeof(DWORD) * ied.NumberOfNames, name_addrs) < 0) { goto done; } - if(DECAF_read_mem(env, base + ied.AddressOfNameOrdinals, + if(DECAF_read_mem(_env, base + ied.AddressOfNameOrdinals, sizeof(WORD) * ied.NumberOfNames, ordinals) < 0) { goto done; } @@ -404,7 +404,7 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b if(index >= ied.NumberOfFunctions) continue; - DECAF_read_mem(env, base + name_addrs[i], sizeof(name)-1, name); + DECAF_read_mem(_env, base + name_addrs[i], sizeof(name)-1, name); name[127] = 0; funcmap_insert_function(mod->name, name, func_addrs[index]); } @@ -425,72 +425,72 @@ static void extract_export_table(IMAGE_NT_HEADERS *nth, uint32_t cr3, uint32_t b //Extract info in PE header and export table from a PE module //If everything is done successfully, mod->symbols_extracted will be set true -static void extract_PE_info(uint32_t cr3, uint32_t base, module *mod) +static void extract_PE_info(uint32_t cr3, uint32_t base, module *mod, CPUState *_env) { IMAGE_NT_HEADERS nth; - if (get_IMAGE_NT_HEADERS(cr3, base, &nth) < 0) + if (get_IMAGE_NT_HEADERS(cr3, base, &nth, _env) < 0) return; mod->checksum = nth.OptionalHeader.CheckSum; mod->codesize = nth.OptionalHeader.SizeOfCode; mod->major = nth.OptionalHeader.MajorImageVersion; mod->minor = nth.OptionalHeader.MinorImageVersion; - extract_export_table(&nth, cr3, base, mod); + extract_export_table(&nth, cr3, base, mod, _env); } -static void retrieve_missing_symbols(process *proc) +static void retrieve_missing_symbols(process *proc, CPUState *_env) { unordered_map < uint32_t,module * >::iterator iter = proc->module_list.begin(); for(; iter!=proc->module_list.end(); iter++) { module *cur_mod = iter->second; if(!cur_mod->symbols_extracted) - extract_PE_info(proc->cr3, iter->first, cur_mod); + extract_PE_info(proc->cr3, iter->first, cur_mod, _env); } } -static inline 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) { - update_kernel_modules(env, vaddr); + update_kernel_modules(_env, vaddr); } else { - base = env->segs[R_FS].base; - DECAF_read_mem(env, base + 0x18, 4, &self); + base = _env->segs[R_FS].base; + DECAF_read_mem(_env, base + 0x18, 4, &self); if (base != 0 && base == self) { //Why don't you use the offset table instead of these hard-coded offsets? uint32_t pid_addr = base + 0x20; - DECAF_read_mem(env, pid_addr, 4, &pid); + DECAF_read_mem(_env, pid_addr, 4, &pid); uint32_t peb_addr = base + 0x30; uint32_t peb; - DECAF_read_mem(env, peb_addr, 4, &peb); - update_loaded_user_mods_with_peb(env, proc, peb, vaddr); + DECAF_read_mem(_env, peb_addr, 4, &peb); + update_loaded_user_mods_with_peb(_env, proc, peb, vaddr); } } } static void tlb_call_back(DECAF_Callback_Params *temp) { - CPUState *env = temp->tx.env; + CPUState *ourenv = temp->tx.env; target_ulong vaddr = temp->tx.vaddr; - uint32_t cr3 = env->cr[3]; + uint32_t cr3 = ourenv->cr[3]; process *proc; - if(DECAF_is_in_kernel()) { + if(DECAF_is_in_kernel(ourenv)) { proc = kernel_proc; kernel_proc->cr3 = cr3; } else { proc = VMI_find_process_by_pgd(cr3); if (proc == NULL) - proc = find_new_process(env, cr3); + proc = find_new_process(ourenv, cr3); } if (proc ) { if (!is_page_resolved(proc, vaddr)) { - get_new_modules(env, proc, vaddr); + get_new_modules(ourenv, proc, vaddr); if (!is_page_resolved(proc, vaddr)) { int attempts = unresolved_attempt(proc, vaddr); @@ -499,7 +499,7 @@ static void tlb_call_back(DECAF_Callback_Params *temp) } } - retrieve_missing_symbols(proc); + retrieve_missing_symbols(proc, ourenv); } } @@ -568,13 +568,13 @@ static uint32_t get_ntoskrnl_internal(uint32_t curr_page, CPUState *env) { return 0; } -uint32_t get_ntoskrnl(CPUState *env) { +uint32_t get_ntoskrnl(CPUState *_env) { uint32_t ntoskrnl_base = 0; - ntoskrnl_base = get_ntoskrnl_internal(env->sysenter_eip & 0xfffff000, env); + ntoskrnl_base = get_ntoskrnl_internal(_env->sysenter_eip & 0xfffff000, _env); if (ntoskrnl_base) goto found; - ntoskrnl_base = get_ntoskrnl_internal(env->eip & 0xfffff000, env); + ntoskrnl_base = get_ntoskrnl_internal(_env->eip & 0xfffff000, _env); if (ntoskrnl_base) goto found; return 0; @@ -584,18 +584,18 @@ uint32_t get_ntoskrnl(CPUState *env) { } /*FIXME: Supports only 32bit guest. */ -static uint32_t probe_windows(CPUState *env) +static uint32_t probe_windows(CPUState *_env) { uint32_t base; - if (env->eip > 0x80000000 && env->segs[R_FS].base > 0x80000000) { + if (_env->eip > 0x80000000 && _env->segs[R_FS].base > 0x80000000) { gkpcr = get_kpcr(); if (gkpcr != 0) { //DECAF_unregister_callback(DECAF_INSN_END_CB, insn_handle); rtflag = 1; - get_os_version(env); - base = get_ntoskrnl(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) { @@ -613,30 +613,30 @@ static uint32_t probe_windows(CPUState *env) return 0; } -int find_win7sp0(CPUState *env, uintptr_t insn_handle) { - probe_windows(env); +int find_win7sp0(CPUState *_env, uintptr_t insn_handle) { + probe_windows(_env); if (GuestOS_index == 2 && rtflag == 1) return 1; else return 0; } -int find_win7sp1(CPUState *env, uintptr_t insn_handle) { - probe_windows(env); +int find_win7sp1(CPUState *_env, uintptr_t insn_handle) { + probe_windows(_env); if (GuestOS_index == 2 && rtflag == 1) return 1; else return 0; } -int find_winxpsp2(CPUState *env, uintptr_t insn_handle) { +int find_winxpsp2(CPUState *_env, uintptr_t insn_handle) { - probe_windows(env); + probe_windows(_env); if (GuestOS_index == 0 && rtflag == 1) return 1; else return 0; } -int find_winxpsp3(CPUState *env, uintptr_t insn_handle) { - probe_windows(env); +int find_winxpsp3(CPUState *_env, uintptr_t insn_handle) { + probe_windows(_env); if (GuestOS_index == 1 && rtflag == 1) return 1; else @@ -647,7 +647,8 @@ int find_winxpsp3(CPUState *env, uintptr_t insn_handle) { void check_procexit(void *) { - CPUState *env = cpu_single_env ? cpu_single_env : first_cpu; + /* AWH - cpu_single_env is invalid outside of the main exec thread */ + CPUState *env = /* AWH cpu_single_env ? cpu_single_env :*/ first_cpu; qemu_mod_timer(recon_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() * 10); //monitor_printf(default_mon, "Checking for proc exits...\n"); diff --git a/softmmu_header.h b/softmmu_header.h index 818d7b6..747a10a 100644 --- a/softmmu_header.h +++ b/softmmu_header.h @@ -47,6 +47,9 @@ #error unsupported data size #endif +/* AWH - Assume that we are adding a memory callback */ +#define ADD_MEM_CB 1 + #if ACCESS_TYPE < (NB_MMU_MODES) #define CPU_MMU_INDEX ACCESS_TYPE @@ -61,7 +64,8 @@ #define CPU_MMU_INDEX (cpu_mmu_index(env)) #define MMUSUFFIX _cmmu - +/* AWH - No memory callback for this one */ +#undef ADD_MEM_CB #else #error invalid ACCESS_TYPE #endif diff --git a/softmmu_taint_template.h b/softmmu_taint_template.h index a4928ee..1e0727c 100644 --- a/softmmu_taint_template.h +++ b/softmmu_taint_template.h @@ -58,11 +58,12 @@ static inline DATA_TYPE glue(taint_io_read, SUFFIX)(target_phys_addr_t physaddr, #endif #endif /* SHIFT > 2 */ //res.taint = cpu_single_env->tempidx; - +#if 0 // AWH if (cpu_single_env->tempidx/*res.taint*/) { fprintf(stderr, "MMAP IO %s() -> physaddr: 0x%08x, taint: %u\n", "__taint_io_read", physaddr, cpu_single_env->tempidx); //__asm__ ("int $3"); } +#endif // AWH return res; } @@ -120,11 +121,11 @@ fprintf(stderr, "Entry %s() -> addr: 0x%08x mmu_idx: 0x%08x\n", "__taint_ldb", a #endif addend = env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); - glue(glue(__taint_ld, SUFFIX), _raw)((uint8_t *)(long)(addr+addend),addr); + glue(glue(__taint_ld, SUFFIX), _raw)((unsigned long)(addr+addend),addr); //Hu-Mem read callback #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_READ_CB))// host vitual addr+addend - helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end @@ -184,14 +185,20 @@ static DATA_TYPE glue(glue(taint_slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, mmu_idx, retaddr); /* Special case for 32-bit host/guest and a 64-bit load */ #if ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) - taint1 = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); + taint1 = cpu_single_env->tempidx2; + taint1 = taint1 << 32; + taint1 |= cpu_single_env->tempidx; + //taint1 = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); #else taint1 = cpu_single_env->tempidx; #endif /* ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) */ res2 = glue(glue(taint_slow_ld, SUFFIX), MMUSUFFIX)(addr2, mmu_idx, retaddr); #if ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) - taint2 = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); + taint2 = cpu_single_env->tempidx2; + taint2 = taint2 << 32; + taint2 |= cpu_single_env->tempidx; + //taint2 = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); #else taint2 = cpu_single_env->tempidx; #endif /* ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) */ @@ -219,11 +226,11 @@ static DATA_TYPE glue(glue(taint_slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, /* unaligned/aligned access in the same page */ addend = env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); - glue(glue(__taint_ld, SUFFIX), _raw)((uint8_t *)(long)(addr+addend),addr); + glue(glue(__taint_ld, SUFFIX), _raw)((unsigned long)(addr+addend),addr); //Hu-Mem read callback #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_READ_CB)) - helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end @@ -373,11 +380,11 @@ fprintf(stderr, "Start %s() -> addr: 0x%08x, data: 0x%08x, mmu_idx: %d, taint: #endif addend = env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); - glue(glue(__taint_st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend),addr); + glue(glue(__taint_st, SUFFIX), _raw)((unsigned long)(addr+addend),addr); //Hu-Mem write callback #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_WRITE_CB)) - helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end } @@ -421,7 +428,10 @@ static void glue(glue(taint_slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, setup tempidx for each of these single-byte stores */ /* Special case for 32-bit host/guest and a 64-bit load */ #if ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) - backup_taint = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); + backup_taint = cpu_single_env->tempidx2; + backup_taint = backup_taint << 32; + backup_taint |= cpu_single_env->tempidx; + //backup_taint = cpu_single_env->tempidx | (cpu_single_env->tempidx2 << 32); #else backup_taint = cpu_single_env->tempidx; #endif /* ((TCG_TARGET_REG_BITS == 32) && (DATA_SIZE == 8)) */ @@ -443,11 +453,11 @@ static void glue(glue(taint_slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, /* aligned/unaligned access in the same page */ addend = env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); - glue(glue(__taint_st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend),addr); + glue(glue(__taint_st, SUFFIX), _raw)((unsigned long)(addr+addend),addr); //Hu-Mem read callback -#if SUFFIX != _cmmu +#if defined(ADD_MEM_CB) if(DECAF_is_callback_needed(DECAF_MEM_WRITE_CB)) - helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail((void*)(addr+addend)),DATA_SIZE); #endif //end diff --git a/softmmu_template.h b/softmmu_template.h index 249aa30..513bf7a 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -134,7 +134,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, //Hu-Mem read callback #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_READ_CB))// host vitual addr+addend - helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end @@ -197,7 +197,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_READ_CB)) - helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_read_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end @@ -328,7 +328,7 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, //Hu-Mem write callback #ifndef SOFTMMU_CODE_ACCESS if(DECAF_is_callback_needed(DECAF_MEM_WRITE_CB)) - helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end } @@ -384,9 +384,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, addend = env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); //Hu-Mem read callback -#if SUFFIX != _cmmu +#if defined(ADD_MEM_CB) if(DECAF_is_callback_needed(DECAF_MEM_WRITE_CB)) - helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail(addr+addend),DATA_SIZE); + helper_DECAF_invoke_mem_write_callback(addr,qemu_ram_addr_from_host_nofail((void *)(addr+addend)),DATA_SIZE); #endif //end diff --git a/target-arm/DECAF_target.h b/target-arm/DECAF_target.h index 5aa09b9..d482882 100644 --- a/target-arm/DECAF_target.h +++ b/target-arm/DECAF_target.h @@ -36,7 +36,7 @@ If you have any questions about DECAF,please post it on #include "targphys.h" #include "compiler.h" #include "monitor.h" -#include "shared/disasm.h" +// #include "shared/disasm.h" #include "shared/DECAF_callback.h" #define MAX_REGS (CPU_NUM_REGS + 8) //we assume up to 8 temporary registers @@ -46,9 +46,9 @@ extern "C" { #endif // __cplusplus /// Check if the current execution of guest system is in kernel mode (i.e., ring-0) -static inline int DECAF_is_in_kernel(void) +static inline int DECAF_is_in_kernel(CPUState *env) { - return (cpu_single_env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR; + return (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR; } @@ -68,9 +68,6 @@ static inline gva_t DECAF_getESP(CPUState* env) return (env->regs[13]); } - -gpa_t DECAF_get_phys_addr_with_pgd(CPUState* env, gpa_t pgd, gva_t addr); - #if 0 // AWH - Comment in as needed extern void DECAF_update_cpustate(void); diff --git a/target-arm/helper.h b/target-arm/helper.h index 7817c2e..19c2f1a 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -1,7 +1,4 @@ #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 diff --git a/target-arm/translate.c b/target-arm/translate.c index 5d9e474..f4e492d 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -33,7 +33,6 @@ #define GEN_HELPER 1 #include "helper.h" #include "shared/DECAF_callback_to_QEMU.h" -//#include "DECAF_callback.h" // AWH #ifdef CONFIG_TCG_TAINT #include "shared/tainting/taint_memory.h" @@ -10122,6 +10121,10 @@ static inline void gen_intermediate_code_internal(CPUState *env, if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); + /* Mimic x86 INSN_BEGIN callbacks */ + if (DECAF_is_callback_needed(DECAF_INSN_BEGIN_CB)) + gen_helper_DECAF_invoke_insn_begin_callback(cpu_env); + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { tcg_gen_debug_insn_start(dc->pc); } diff --git a/target-i386/DECAF_target.h b/target-i386/DECAF_target.h index 9fc61ee..3ddd176 100644 --- a/target-i386/DECAF_target.h +++ b/target-i386/DECAF_target.h @@ -36,7 +36,7 @@ If you have any questions about DECAF,please post it on #include "targphys.h" #include "compiler.h" #include "monitor.h" -#include "shared/disasm.h" +// AWH #include "shared/disasm.h" #include "shared/DECAF_callback.h" #define MAX_REGS (CPU_NUM_REGS + 8) //we assume up to 8 temporary registers @@ -209,11 +209,11 @@ extern void DECAF_register_insn_cb_range(uint32_t start_opcode, uint32_t end_opc extern int DECAF_get_page_access(CPUState* env, gva_t addr); /// Check if the current execution of guest system is in kernel mode (i.e., ring-0) -static inline int DECAF_is_in_kernel(void) +static inline int DECAF_is_in_kernel(CPUState *_env) { - return ((cpu_single_env->hflags & HF_CPL_MASK) == 0); + return ((_env->hflags & HF_CPL_MASK) == 0); } - +#if 0 // AWH /// \brief Read from a register. /// /// Note that reg_id is register ID, which is different from register index. @@ -359,7 +359,7 @@ static inline void DECAF_write_register(int reg_id, void *buf) assert(0); } } - +#endif // AWH /* @} */ //end of group static inline gva_t DECAF_getPC(CPUState* env) @@ -377,9 +377,6 @@ static inline gva_t DECAF_getESP(CPUState* env) return (env->regs[R_ESP]); } - -gpa_t DECAF_get_phys_addr_with_pgd(CPUState* env, gpa_t pgd, gva_t addr); - #ifdef __cplusplus } #endif // __cplusplus diff --git a/target-i386/helper.h b/target-i386/helper.h index 1e4d87c..5a5cb8f 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -1,7 +1,4 @@ #include "def-helper.h" -#ifdef CONFIG_TCG_TAINT -#include "tainting/DECAF_taint_helper.h" -#endif /* CONFIG_TCG_TAINT */ DEF_HELPER_FLAGS_1(cc_compute_all, TCG_CALL_PURE, i32, int) DEF_HELPER_FLAGS_1(cc_compute_c, TCG_CALL_PURE, i32, int) @@ -26,7 +23,7 @@ DEF_HELPER_1(DECAF_invoke_insn_end_callback, void, ptr) DEF_HELPER_0(DECAF_update_fpu, void); #ifdef CONFIG_TCG_TAINT -DEF_HELPER_2(DECAF_invoke_eip_check_callback,void,i32,i32) +DEF_HELPER_3(DECAF_invoke_eip_check_callback,void,tl,tl,tl) DEF_HELPER_0(DECAF_taint_patch,void) DEF_HELPER_0(DECAF_taint_cmpxchg, void) #endif /* CONFIG_TCG_TAINT */ diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 2a97237..52a2a23 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -34,6 +34,8 @@ #include "softmmu_exec.h" #endif /* !defined(CONFIG_USER_ONLY) */ +#include "../shared/DECAF_main.h" + //#define DEBUG_PCALL #ifdef DEBUG_PCALL @@ -5903,7 +5905,7 @@ extern void (*insn_cbl2[16*16]) (uint32_t eip, uint32_t next_eip, uint32_t op); //uint32_t KiUserApcDispatcher_addr_l = 0xE430 + 0x7c900000; //uint32_t KiRaiseUserExceptionDispatcher_addr_l = 0xE4A8 + 0x7c900000; //uint32_t KiUserCallbackDispatcher_addr_l = 0xE440 + 0x7c900000; - +#if 0 // AWH void helper_insn_cb_dispatch(uint32_t eip, uint32_t next_eip, uint32_t op2) { @@ -5925,7 +5927,7 @@ void helper_insn_cb_dispatch(uint32_t eip, uint32_t next_eip, uint32_t op2) if(op > 0xf00 && op <= 0xfff) { if(insn_cbl2[op-0xf00]) insn_cbl2[op-0xf00](eip, next_eip, op2); - } else if(op >= 0x0 && op <= 0xff){ + } else if(/* AWH op >= 0x0 &&*/ op <= 0xff){ if(insn_cbl1[op]) insn_cbl1[op](eip, next_eip, op2); } else { @@ -5939,7 +5941,7 @@ void helper_insn_cb_dispatch(uint32_t eip, uint32_t next_eip, uint32_t op2) } } //end - Aravind - +#endif // AWH #ifdef CONFIG_TCG_TAINT void helper_DECAF_taint_cmpxchg(void) {} diff --git a/target-i386/translate.c b/target-i386/translate.c index 9a8fcb9..42e971c 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -107,7 +107,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; +//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]; @@ -8010,7 +8010,7 @@ void optimize_flags_init(void) } #ifdef CONFIG_TCG_IR_LOG -inline void log_tcg_ir(TranslationBlock *tb) +static inline void log_tcg_ir(TranslationBlock *tb) { int i; @@ -8146,6 +8146,12 @@ 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_LLVM + if (DECAF_is_callback_needed(DECAF_BLOCK_TRANS_CB)) { + tb->icount = num_insns; + helper_DECAF_invoke_block_trans_callback(tb, &tcg_ctx); + } +#endif /* CONFIG_TCG_LLVM */ #ifdef CONFIG_TCG_IR_LOG log_tcg_ir(tb); #endif /* CONFIG_TCG_IR_LOG */ @@ -8181,6 +8187,12 @@ static inline void gen_intermediate_code_internal(CPUState *env, /* stop translation if indicated */ if (dc->is_jmp) { +#ifdef CONFIG_TCG_LLVM + if(DECAF_is_callback_needed(DECAF_BLOCK_TRANS_CB)) { + tb->icount = num_insns; + helper_DECAF_invoke_block_trans_callback(tb, &tcg_ctx); + } +#endif /* CONFIG_TCG_LLVM */ #ifdef CONFIG_TCG_IR_LOG log_tcg_ir(tb); #endif /* CONFIG_TCG_IR_LOG */ @@ -8197,6 +8209,13 @@ 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_LLVM + if(DECAF_is_callback_needed(DECAF_BLOCK_TRANS_CB)) + { + tb->icount = num_insns; + helper_DECAF_invoke_block_trans_callback(tb, &tcg_ctx); + } +#endif /* CONFIG_TCG_LLVM */ #ifdef CONFIG_TCG_IR_LOG log_tcg_ir(tb); #endif /* CONFIG_TCG_IR_LOG */ @@ -8212,6 +8231,13 @@ 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_LLVM + if(DECAF_is_callback_needed(DECAF_BLOCK_TRANS_CB)) + { + tb->icount = num_insns; + helper_DECAF_invoke_block_trans_callback(tb, &tcg_ctx); + } +#endif /* CONFIG_TCG_LLVM */ #ifdef CONFIG_TCG_IR_LOG log_tcg_ir(tb); #endif /* CONFIG_TCG_IR_LOG */ @@ -8224,6 +8250,13 @@ static inline void gen_intermediate_code_internal(CPUState *env, break; } if (singlestep) { +#ifdef CONFIG_TCG_LLVM + if(DECAF_is_callback_needed(DECAF_BLOCK_TRANS_CB)) + { + tb->icount = num_insns; + helper_DECAF_invoke_block_trans_callback(tb, &tcg_ctx); + } +#endif /* CONFIG_TCG_LLVM */ #ifdef CONFIG_TCG_IR_LOG log_tcg_ir(tb); #endif /* CONFIG_TCG_IR_LOG */ diff --git a/target-mips/DECAF_target.c b/target-mips/DECAF_target.c index a0c7e32..fb006d3 100644 --- a/target-mips/DECAF_target.c +++ b/target-mips/DECAF_target.c @@ -22,38 +22,44 @@ If you have any questions about DECAF,please post it on #include "blockdev.h" // AWH #include "shared/DECAF_main.h" // AWH #include "shared/DECAF_callback.h" -#include "shared/procmod.h" #include "shared/hookapi.h" // AWH #include "DECAF_target.h" - +#include "shared/linux_vmi.h" gpa_t DECAF_get_phys_addr_with_pgd(CPUState* env, gpa_t pgd, gva_t addr) { - if (env == NULL) - { -#ifdef DECAF_NO_FAIL_SAFE - return (INV_ADDR); -#else - env = cpu_single_env ? cpu_single_env : first_cpu; -#endif - } + monitor_printf(default_mon, "ERROR: DECAF_get_phys_addr_with_pgd doesn't work for MIPS.\n"); + return -1; +// if (env == NULL) +// { +// #ifdef DECAF_NO_FAIL_SAFE +// return (INV_ADDR); +// #else +// env = cpu_single_env ? cpu_single_env : first_cpu; +// #endif +// } - gpa_t old = env->CP0_EntryLo0; - gpa_t old1 = env->CP0_EntryLo1; - gpa_t phys_addr; - env->CP0_EntryLo0 = pgd; - env->CP0_EntryLo1 = pgd; +// gpa_t old = env->CP0_EntryLo0; +// gpa_t old1 = env->CP0_EntryLo1; +// gpa_t phys_addr; - phys_addr = cpu_get_phys_page_debug(env, addr & TARGET_PAGE_MASK); +// env->CP0_EntryLo0 = pgd; +// env->CP0_EntryLo1 = pgd; - env->CP0_EntryLo0 = old; - env->CP0_EntryLo1 = old1; +// phys_addr = cpu_get_phys_page_debug(env, addr & TARGET_PAGE_MASK); - return (phys_addr | (addr & (~TARGET_PAGE_MASK))); -} +// env->CP0_EntryLo0 = old; +// env->CP0_EntryLo1 = old1; +// return (phys_addr | (addr & (~TARGET_PAGE_MASK))); +} +// FIXME: assume only one processor +gpa_t DECAF_getPGD(CPUState* env) +{ + return mips_get_cur_pgd(env); +} diff --git a/target-mips/DECAF_target.h b/target-mips/DECAF_target.h index 6a60d1b..5183cd6 100644 --- a/target-mips/DECAF_target.h +++ b/target-mips/DECAF_target.h @@ -36,7 +36,7 @@ If you have any questions about DECAF,please post it on #include "targphys.h" #include "compiler.h" #include "monitor.h" -#include "shared/disasm.h" +// #include "shared/disasm.h" #include "shared/DECAF_callback.h" #define MAX_REGS (CPU_NUM_REGS + 8) //we assume up to 8 temporary registers @@ -46,9 +46,9 @@ extern "C" { #endif // __cplusplus /// Check if the current execution of guest system is in kernel mode (i.e., ring-0) -static inline int DECAF_is_in_kernel(void) +static inline int DECAF_is_in_kernel(CPUState *env) { - return ((cpu_single_env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_KM); + return ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_KM); } @@ -57,20 +57,22 @@ static inline gva_t DECAF_getPC(CPUState* env) return (env->active_tc.PC); } +gpa_t DECAF_getPGD(CPUState* env); + //Based this off of op_helper.c in r4k_fill_tlb() -static inline gpa_t DECAF_getPGD(CPUState* env) -{ - return (env->CP0_EntryHi); -} +// static inline gpa_t DECAF_getPGD(CPUState* env) +// { +// return (env->CP0_EntryHi); +// } static inline gva_t DECAF_getESP(CPUState* env) { /* AWH - General-purpose register 29 (of 32) is the stack pointer */ - return (env->active_tc.gpr[28]); + return (env->active_tc.gpr[29]); } - -gpa_t DECAF_get_phys_addr_with_pgd(CPUState* env, gpa_t pgd, gva_t addr); +/* AWH - In shared/DECAF_main.h */ +//gpa_t DECAF_get_phys_addr_with_pgd(CPUState* env, gpa_t pgd, gva_t addr); #ifdef __cplusplus } diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 3c79332..3463fa3 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -145,10 +145,11 @@ typedef struct mips_def_t mips_def_t; typedef struct TCState TCState; struct TCState { target_ulong gpr[32]; + target_ulong PC; #ifdef CONFIG_TCG_TAINT - target_ulong taint_regs[32]; + target_ulong taint_gpr[32]; + target_ulong taint_PC; #endif /* CONFIG_TCG_TAINT */ - target_ulong PC; target_ulong HI[MIPS_DSP_ACC]; target_ulong LO[MIPS_DSP_ACC]; target_ulong ACX[MIPS_DSP_ACC]; diff --git a/target-mips/helper.h b/target-mips/helper.h index f5fac6c..d5f334c 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -1,7 +1,4 @@ #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 diff --git a/target-mips/translate.c b/target-mips/translate.c index e369b0d..9943e1b 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -34,6 +34,33 @@ #include "helper.h" #define GEN_HELPER 1 #include "helper.h" +#include "shared/DECAF_callback_to_QEMU.h" + +#ifdef CONFIG_TCG_TAINT +#include "shared/tainting/taint_memory.h" +#include "shared/tainting/tcg_taint.h" +#endif /* CONFIG_TCG_TAINT */ + +#ifdef CONFIG_TCG_IR_LOG +inline void log_tcg_ir(TranslationBlock *tb) +{ + int i; + + /* AWH - Store the IRs for logging to disk later by plugin, if needed. */ + tb->DECAF_num_opc = (gen_opc_ptr - gen_opc_buf); + tb->DECAF_num_opparam = (gen_opparam_ptr - gen_opparam_buf); + 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)); + + /* Store information about the temps as to whether they are temp or local */ + tb->DECAF_num_temps = tcg_ctx.nb_temps; + for (i=tcg_ctx.nb_globals; i < (tcg_ctx.nb_globals + tcg_ctx.nb_temps); i++) + { + if (tcg_ctx.temps[i].temp_local) + tb->DECAF_temp_type[i>>3] |= (1 << (i % 8)); + } +} +#endif /* CONFIG_TCG_IR_LOG */ //#define MIPS_DEBUG_DISAS //#define MIPS_DEBUG_SIGN_EXTENSIONS @@ -485,8 +512,19 @@ static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC]; static TCGv cpu_dspctrl, btarget, bcond; static TCGv_i32 hflags; static TCGv_i32 fpu_fcr0, fpu_fcr31; - +#ifdef CONFIG_TCG_TAINT +/* 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. */ +uint32_t gen_opc_hflags[OPC_BUF_SIZE]; +static TCGv taint_cpu_gpr[32], taint_cpu_PC; +/* AWH - See if we need these later +static TCGv taint_cpu_HI[MIPS_DSP_ACC], taint_cpu_LO[MIPS_DSP_ACC], taint_cpu_ACX[MIPS_DSP_ACC]; +static TCGv taint_cpu_dspctrl, taint_btarget, taint_bcond; +static TCGv_i32 taint_hflags; +static TCGv_i32 taint_fpu_fcr0, taint_fpu_fcr31; */ +#else static uint32_t gen_opc_hflags[OPC_BUF_SIZE]; +#endif /* CONFIG_TCG_TAINT */ #include "gen-icount.h" @@ -514,6 +552,30 @@ static uint32_t gen_opc_hflags[OPC_BUF_SIZE]; tcg_temp_free_i32(helper_tmp); \ } while(0) +#if 1 /* AWH - For callbacks */ +#define INSERT_INSN_END_CB() if(DECAF_is_callback_needed(DECAF_INSN_END_CB)) { gen_helper_DECAF_invoke_insn_end_callback(cpu_env); } + +//LOK: I need a temporary global to hold the jump target for basic block end +// This is used for checking to see if the block end callback is needed +// Note that this is only known for direct jumps - for indirect jumps +// we use the 0xFFFFFFFF (-1) default value +//NOTE: There is an inherent assumption that gen_eob is called immediately +// after gen_jump_im since I update next_pc in gen_jmp_im and then use it +// in gen_eob. +//next_pc is initialized to the default -1 value at the beginning of disas_insn +// an alternative is to set it up in gen_intermediate_code_internal (which calls +// disas_insn and is at the basic block level.) +//I don't think we need to reset it to -1 after disas_insn, but it might be +// safer to do so +static target_ulong next_pc; + +//LOK: Similarly, we also need one to keep track of the current pc just because +// gen_eob is called after gen_jmp_im - which updates the pc. So for block ends +// that are generated at gen_eob, it is impossible to know where the branch +// source was. +static target_ulong cur_pc; +#endif /* AWH */ + typedef struct DisasContext { struct TranslationBlock *tb; target_ulong pc, saved_pc; @@ -554,6 +616,37 @@ static const char *fregnames[] = "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; +#ifdef CONFIG_TCG_TAINT +static const char *taint_regnames[] = + { "taint_r0", "taint_at", "taint_v0", "taint_v1", + "taint_a0", "taint_a1", "taint_a2", "taint_a3", + "taint_t0", "taint_t1", "taint_t2", "taint_t3", + "taint_t4", "taint_t5", "taint_t6", "taint_t7", + "taint_s0", "taint_s1", "taint_s2", "taint_s3", + "taint_s4", "taint_s5", "taint_s6", "taint_s7", + "taint_t8", "taint_t9", "taint_k0", "taint_k1", + "taint_gp", "taint_sp", "taint_s8", "taint_ra", }; +/* AWH - See if we need these later +static const char *taint_regnames_HI[] = + { "taint_HI0", "taint_HI1", "taint_HI2", "taint_HI3", }; + +static const char *taint_regnames_LO[] = + { "taint_LO0", "taint_LO1", "taint_LO2", "taint_LO3", }; + +static const char *taint_regnames_ACX[] = + { "taint_ACX0", "taint_ACX1", "taint_ACX2", "taint_ACX3", }; + +static const char *taint_fregnames[] = + { "taint_f0", "taint_f1", "taint_f2", "taint_f3", + "taint_f4", "taint_f5", "taint_f6", "taint_f7", + "taint_f8", "taint_f9", "taint_f10", "taint_f11", + "taint_f12", "taint_f13", "taint_f14", "taint_f15", + "taint_f16", "taint_f17", "taint_f18", "taint_f19", + "taint_f20", "taint_f21", "taint_f22", "taint_f23", + "taint_f24", "taint_f25", "taint_f26", "taint_f27", + "taint_f28", "taint_f29", "taint_f30", "taint_f31", }; +*/ +#endif /* CONFIG_TCG_TAINT */ #ifdef MIPS_DEBUG_DISAS #define MIPS_DEBUG(fmt, ...) \ @@ -2683,6 +2776,17 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) tb = ctx->tb; if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && likely(!ctx->singlestep_enabled)) { +#if 1 /* AWH - callback */ + if(DECAF_is_BlockEndCallback_needed(tb->pc, dest)) + { + TCGv_ptr tmpTb = tcg_const_ptr((tcg_target_ulong)tb); + TCGv tmpFrom = tcg_temp_new(); + tcg_gen_movi_tl(tmpFrom, cur_pc); + gen_helper_DECAF_invoke_block_end_callback(cpu_env, tmpTb, tmpFrom); + tcg_temp_free(tmpFrom); + tcg_temp_free_ptr(tmpTb); + } +#endif /* AWH */ tcg_gen_goto_tb(n); gen_save_pc(dest); tcg_gen_exit_tb((tcg_target_long)tb + n); @@ -12386,6 +12490,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, int j, lj = -1; int num_insns; int max_insns; +#ifdef CONFIG_TCG_TAINT + int not_tainted = 1; +#endif /* CONFIG_TCG_TAINT */ int insn_bytes; int is_branch; @@ -12413,12 +12520,47 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, max_insns = CF_COUNT_MASK; LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); gen_icount_start(); +#if 1 /* AWH - based off of the I386 target approach */ + if(DECAF_is_BlockBeginCallback_needed(tb->pc)) + { + //LOK: While we can define a new TCG operation for tcg_gen_movi_ptr in tcg/tcg-op.h we will just use tcg_const_ptr macro instead + //tcg_target_ulong is defined in tcg.h and + // according to the definition, it is defined as 64 bits if UINTPTR_MAX is UINT64_MAX + // which implies that the TCG target is the HOST + TCGv_ptr tmpTb = tcg_const_ptr((tcg_target_ulong)tb); + gen_helper_DECAF_invoke_block_begin_callback(cpu_env, tmpTb); + tcg_temp_free_ptr(tmpTb); + //LOK: I wonder if I really have to call tcg_temp_free_ptr + // since all of the other calls to tcg_const... don't have it + } +#else + if(DECAF_is_callback_needed(DECAF_BLOCK_BEGIN_CB)) + gen_helper_DECAF_invoke_callback(tcg_const_i32(DECAF_BLOCK_BEGIN_CB)); +#endif /* AWH */ +#ifdef CONFIG_TCG_TAINT + if (taint_tracking_enabled) { + gen_old_opc_ptr = gen_opc_ptr; + gen_old_opparam_ptr = gen_opparam_ptr; + memset(gen_opc_instr_start, 0, sizeof(uint8_t) * (OPC_BUF_SIZE)); + } +#endif /* CONFIG_TCG_TAINT */ while (ctx.bstate == BS_NONE) { + // update pc for instruction begin callback + gen_save_pc(ctx.pc); // rundong if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == ctx.pc) { save_cpu_state(&ctx, 1); ctx.bstate = BS_BRANCH; +#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); + not_tainted = 0; + } +#endif /* CONFIG_TCG_TAINT */ gen_helper_0i(raise_exception, EXCP_DEBUG); /* Include the breakpoint location or the tb won't * be flushed when it must be. */ @@ -12442,7 +12584,16 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, } if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); - +#if 1 /* AWH */ + if (DECAF_is_callback_needed(DECAF_INSN_BEGIN_CB)) + gen_helper_DECAF_invoke_insn_begin_callback(cpu_env); + + //if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { + // tcg_gen_debug_insn_start(ctx.pc); + //} + next_pc = (-1); // Needed? + cur_pc = pc_start; // Needed? +#endif /* AWH */ is_branch = 0; if (!(ctx.hflags & MIPS_HFLAG_M16)) { ctx.opcode = ldl_code(ctx.pc); @@ -12459,6 +12610,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, ctx.bstate = BS_STOP; break; } +#if 1 /* AWH */ + INSERT_INSN_END_CB() +#endif /* AWH */ if (!is_branch) { handle_delay_slot(env, &ctx, insn_bytes); } @@ -12485,6 +12639,13 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if (singlestep) break; } +#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); +#endif /* CONFIG_TCG_TAINT */ if (tb->cflags & CF_LAST_IO) gen_io_end(); if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) { @@ -12686,6 +12847,43 @@ static void mips_tcg_init(void) fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, active_fpu.fcr31), "fcr31"); +#ifdef CONFIG_TCG_TAINT + for (i = 1; i < 32; i++) { + taint_cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_gpr[i]), taint_regnames[i]); + shadow_arg[(int)cpu_gpr[i]] = taint_cpu_gpr[i]; + } + taint_cpu_PC = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_PC), "taint_PC"); + shadow_arg[(int)cpu_PC] = taint_cpu_PC; +/* AWH - See if we need these later + for (i = 0; i < MIPS_DSP_ACC; i++) { + taint_cpu_HI[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_HI[i]), taint_regnames_HI[i]); + taint_cpu_LO[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_LO[i]), taint_regnames_LO[i]); + taint_cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_ACX[i]), taint_regnames_ACX[i]); + } + taint_cpu_dspctrl = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, active_tc.taint_DSPControl), "taint_DSPControl"); + taint_bcond = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, taint_bcond), "taint_bcond"); + taint_btarget = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, taint_btarget), "taint_btarget"); + taint_hflags = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, taint_hflags), "taint_hflags"); + + taint_fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, active_fpu.taint_fcr0), "taint_fcr0"); + taint_fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, active_fpu.taint_fcr31), "taint_fcr31"); +*/ + tempidx = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, tempidx), "tempidx"); + tempidx2 = tcg_global_mem_new_i32(TCG_AREG0, + offsetof(CPUState, tempidx), "tempidx2"); +#endif /* CONFIG_TCG_TAINT */ /* register helpers */ #define GEN_HELPER 2 diff --git a/translate-all.c b/translate-all.c index 0dfd32d..24707ae 100644 --- a/translate-all.c +++ b/translate-all.c @@ -30,6 +30,7 @@ #ifdef CONFIG_TCG_TAINT #include "tcg-op.h" #include "tainting/taint_memory.h" +#include "tainting/tcg_taint.h" #else #include "tcg.h" #endif /* CONFIG_TCG_TAINT */ @@ -50,13 +51,6 @@ void cpu_gen_init(void) tcg_context_init(&tcg_ctx); } - -void gen_taintcheck_intermediate_code() -{ - static uint16_t gen_new_opc_buf[OPC_BUF_SIZE]; - int nc_opc = gen_opc_ptr - gen_opc_buf; -} - /* return non zero if the very first instruction is invalid so that the virtual CPU can trigger an exception. diff --git a/vl.c b/vl.c index 7ec8e73..9bb5be1 100644 --- a/vl.c +++ b/vl.c @@ -166,7 +166,7 @@ int main(int argc, char **argv) #include "arch_init.h" #include "ui/qemu-spice.h" - +#include "shared/DECAF_main_internal.h" // AWH //#define DEBUG_NET //#define DEBUG_SLIRP