void check_call(DECAF_Callback_Params *param) { uint32_t eip, cr3, insn_buf; CPUState *env = NULL; //If we've gotten this far, params is not null if(calls<MAXCALLS) { env = param->be.env; if(env!=NULL) { eip=DECAF_getPC(env); cr3=DECAF_getPGD(env); } else { eip=0x0; cr3=0x0; } DECAF_printf("sysenter_eip: (0x%x)\n", env->sysenter_eip); fprintf(tracefile, "sysenter_eip: (0x%x)\n", env->sysenter_eip); fprintf(tracefile, "sysenter_esp: (0x%x)\n", env->sysenter_esp); fprintf(tracefile, "current esp: (0x%x)\n", env->regs[R_ESP]-env->sysenter_eip); //fprintf(tracefile, "idt base: (0x%x) \n", env->idt.base); //Read 32bits worth of code... will be used to identify this later DECAF_read_mem(env,param->be.cur_pc,sizeof(uint32_t),&insn_buf); DECAF_printf("call: (0x%x@0x%x) 0x%x\n", eip-env->sysenter_eip, cr3, insn_buf); fprintf(tracefile, "call: (0x%x@0x%x) 0x%x\n", eip-env->sysenter_eip, cr3, insn_buf); fprintf(tracefile, "call (-esp): (0x%x@0x%x) 0x%x\n", eip-env->sysenter_esp, cr3, insn_buf); calls++; } }
void tracing_insn_begin(DECAF_Callback_Params* params) { CPUState* env = NULL; #if 0 // AWH if (params != NULL) { env = params->ib.env; } #else if (!params) return; env = params->ib.env; #endif // AWH if (DECAF_is_in_kernel(env) && should_trace_all_kernel) goto TRACE_KERNEL; /* If tracing start condition not satisified, or not tracing return */ if ((!tracing_start_condition) || (tracepid == 0)) return; /* If not tracing kernel and kernel instruction , return */ if (DECAF_is_in_kernel(env) && !tracing_kernel()) return; if(DECAF_getPGD(env) != tracecr3 && (!DECAF_is_in_kernel(env))) return; TRACE_KERNEL: cpu_disable_ticks(); /* Get thread id */ current_tid = VMI_get_current_tid_c(env); /* Clear flags before processing instruction */ // Flag to be set if the instruction is written insn_already_written = 0; // Flag to be set if instruction encounters a page fault // NOTE: currently not being used. Tracing uses it to avoid logging twice // these instructions, but was missing some has_page_fault = 0; // Flag to be set if instruction accesses user memory access_user_mem = 0; /* Disassemble the instruction */ insn_tainted = 0; if (skip_decode_address == 0) { decode_address(/* AWH cpu_single_*/ env->eip, &eh); } cpu_enable_ticks(); }
//Cheap copy+paste: do the same as calls, but don't print void check_ret(DECAF_Callback_Params *param) { uint32_t eip, cr3; CPUState *env = NULL; //If we've gotten this far, params is not null if(calls<MAXCALLS) { env = param->be.env; if(env!=NULL) { eip=DECAF_getPC(env); cr3=DECAF_getPGD(env); } else { eip=0x0; cr3=0x0; } DECAF_printf("ret: (0x%x@0x%x)\n", eip-env->sysenter_eip, cr3); fprintf(tracefile, "ret: (0x%x@0x%x)\n", eip-env->sysenter_eip, cr3); } }
void block_begin_callback(DECAF_Callback_Params *param) { //uint32_t address; uint32_t cr3; int i, found_cr3=0; if(param==NULL) { DECAF_printf("Null params!\n"); return; } pthread_mutex_lock(&mutex); /* if(was_int) { address = param->bb.env->eip; if(use_sysenter) address -= param->bb.env->sysenter_eip; //fprintf(tracefile, "eip: %x:\n", address); was_int--; } */ cr3 = DECAF_getPGD(param->be.env); if(cr3_changes < CR3_TO_TRACK && cr3 != last_cr3) { for(i=0;i<CR3_TO_TRACK;i++) { if(cr3s_this_keystroke[i]==cr3) { found_cr3=1; break; } } //Only increment our global list if this change is unique to the keystroke //We are trying to correlate how many CR3s consistently show up if(!found_cr3) { cr3s_this_keystroke[cr3_changes]=cr3; cr3s[cr3>>12]++; } cr3_changes++; last_cr3 = cr3; }
void tracing_insn_end(DECAF_Callback_Params* params) { CPUState * env; /* If not decoding, return */ if (skip_decode_address || !params) return; env = params->ie.env; if (DECAF_is_in_kernel(env) && should_trace_all_kernel) goto TRACE_KERNEL; /* If tracing start condition not satisified, or not tracing return */ if ((!tracing_start_condition) || (tracepid == 0)) return; /* If not tracing kernel and kernel instruction , return */ if (DECAF_is_in_kernel(env) && !tracing_kernel()) return; /* If partially tracing kernel but did not access user memory, return */ if (DECAF_is_in_kernel(env)) { if (tracing_kernel_partial() && (!access_user_mem)) return; #ifdef CONFIG_TCG_TAINT if (tracing_kernel_tainted() && (!insn_tainted)) return; #endif } if(DECAF_getPGD(/* AWH cpu_single_*/ env) != tracecr3 && (!DECAF_is_in_kernel(env))) return; TRACE_KERNEL: /* Update the eflags */ // eh.eflags = *DECAF_cpu_eflags; #if 0 // AWH eh.eflags = compute_eflag(); #else #define DF_MASK 0x00000400 eh.eflags = env->eflags | helper_cc_compute_all(env->cc_op) | (env->df & DF_MASK); #endif // AWH //for test //check taint value after insn is executed int k, j; for (k = 0; k < eh.num_operands; k++) { if (eh.operand[k].length) set_operand_data(&(eh.operand[k]), 0); for (j = 0; j < MAX_NUM_MEMREGS; j++) { if (eh.memregs[k][j].length) set_operand_data(&(eh.memregs[k][j]), 0); } } eh.df = (/* AWH cpu_single_*/ env->df == 1) ? 0x1 : 0xff; //TODO:fix this -hu /* Clear eh.tp if inside a function hook */ // if (get_st(current_tid) > 0) eh.tp = TP_NONE; // else { /* Update eh.tp if rep instruction */ if ((eh.operand[2].usage == counter) && (eh.operand[2].tainted_begin != 0)) eh.tp = TP_REP_COUNTER; /* Updated eh.tp if sysenter */ else if ((eh.rawbytes[0] == 0x0f) && (eh.rawbytes[1] == 0x34)) eh.tp = TP_SYSENTER; //} /* Split written operands if requested */ if (conf_write_ops_at_insn_end) { update_written_operands(&eh); } /* If not writing to trace, or instruction already written, return */ if (skip_trace_write || (insn_already_written == 1)) return; /* Write the disassembled instruction to the trace */ if (tracing_tainted_only()) { #ifdef CONFIG_TCG_TAINT if (insn_tainted) write_insn(tracelog,&eh); #endif } else { if (conf_trace_only_after_first_taint) { if ((received_tainted_data == 1) && (has_page_fault == 0)) { write_insn(tracelog, &eh); } } else { if (has_page_fault == 0) write_insn(tracelog, &eh); } } /* If first trace instruction, save state if requested */ if ((tstats.insn_counter_traced == 1) && conf_save_state_at_trace_start) { char prestatename[128]; snprintf(prestatename, 128, "%s.pre", tracename_p); //TODO: fix this -hu // int err = save_state_by_cr3(tracecr3, prestatename); // if (err) { // DECAF_printf( "Could not save state"); // } } /* Record the thread ID of the first instruction in the trace, if needed */ if (tracing_single_thread_only()) { if (tid_to_trace == -1 && insn_already_written == 1) { // If tid_to_trace is not -1, we record trace only the given thread id. tid_to_trace = current_tid; } } }