static target_ulong Instrument_CALL_NEAR(target_ulong pc) { uint32_t mem_addr; xed_reg_enum_t reg_id; target_ulong target; PEMU_read_mem(pc, 15, pemu_inst.PEMU_inst_buf); xed_decoded_inst_zero_set_mode(&pemu_inst.PEMU_xedd_g, &pemu_inst.PEMU_dstate); xed_error_enum_t xed_error = xed_decode(&pemu_inst.PEMU_xedd_g, XED_STATIC_CAST(const xed_uint8_t *, pemu_inst.PEMU_inst_buf), 15); const xed_inst_t * ins = xed_decoded_inst_inst(&pemu_inst.PEMU_xedd_g); const xed_operand_t *op = xed_inst_operand(ins, 0); xed_operand_enum_t op_name = xed_operand_name(op); if (operand_is_mem(op_name, &mem_addr, 0)) { PEMU_read_mem(mem_addr,sizeof(target) , &target); } else if (operand_is_reg(op_name, ®_id)){ target = PEMU_get_reg(reg_id); } else{ int len = xed_decoded_inst_get_length(&pemu_inst.PEMU_xedd_g); target = xed_decoded_inst_get_branch_displacement(&pemu_inst.PEMU_xedd_g) + pc + len; } return target; }
unsigned int disas_get_target(unsigned int start_pc, struct PEMU_INST *inst) { PEMU_read_mem(start_pc, 15, inst->PEMU_inst_buf); xed_decoded_inst_zero_set_mode(&inst->PEMU_xedd_g, &inst->PEMU_dstate); xed_error_enum_t xed_error = xed_decode(&inst->PEMU_xedd_g, XED_STATIC_CAST(const xed_uint8_t *, inst->PEMU_inst_buf), 15); if (xed_error != XED_ERROR_NONE) { fprintf(stderr, "error in disas_get_target\n"); exit(0); } const xed_inst_t *xi = xed_decoded_inst_inst(&inst->PEMU_xedd_g); if(xed_decoded_inst_get_iclass(&inst->PEMU_xedd_g) != XED_ICLASS_CALL_NEAR) { return 0; } const xed_operand_t *op = xed_inst_operand(xi, 0); xed_reg_enum_t reg_id; xed_operand_enum_t op_name = xed_operand_name(op); unsigned int dest, tmp; if(operand_is_relbr(op_name, &dest)){ dest += (start_pc + xed_decoded_inst_get_length(&inst->PEMU_xedd_g)); }else if(operand_is_reg(op_name, ®_id)){ dest = PEMU_get_reg(reg_id); }else if(operand_is_mem4(op_name, &dest,0)){ PEMU_read_mem(dest, 4, &tmp); dest = tmp; } return dest; }
static void get_mod_name(uint32_t addr, char *name, int size) { uint32_t vmfile, dentry; if(PEMU_read_mem(addr + pemu_guest_os.vmfileoffset, sizeof(vmfile), &vmfile) != 0 || PEMU_read_mem(vmfile + pemu_guest_os.dentryoffset, sizeof(dentry), &dentry) != 0 || PEMU_read_mem(dentry + pemu_guest_os.dinameoffset, size < 36 ? size : 36, name) != 0) name[0] = 0; }
static void Instrument_ADD(const xed_inst_t* xi) { xed_reg_enum_t reg_id_0, reg_id_1; unsigned int imm = 0; unsigned int mem_addr, taint_s = 0, taint_d = 0; const xed_operand_t *op_0 = xed_inst_operand(xi, 0); const xed_operand_t *op_1 = xed_inst_operand(xi, 1); xed_operand_enum_t op_name_0 = xed_operand_name(op_0); xed_operand_enum_t op_name_1 = xed_operand_name(op_1); if(operand_is_mem4(op_name_0, &mem_addr, 0)){ if(operand_is_imm(op_name_1, &imm)) return; taint_d = t_get_mem_taint(mem_addr); //yang int a, b; PEMU_read_mem(mem_addr, 4, &a); if (operand_is_reg(op_name_1, ®_id_1)){ taint_s = t_get_reg_taint(reg_id_1); b = PEMU_get_reg(reg_id_1); } if(b<a) // if((int)get_pc_imm(taint_s) < (int)get_pc_imm(taint_d)) taint_s = taint_d; t_set_mem_taint_bysize(mem_addr, taint_s, xed_decoded_inst_operand_length(&xedd_g, 0)); }else if(operand_is_reg(op_name_0, ®_id_0)){ if(operand_is_imm(op_name_1, &imm)) return; //yang int a, b; a = PEMU_get_reg(reg_id_0); taint_d = t_get_reg_taint(reg_id_0); if(operand_is_mem4(op_name_1, &mem_addr, 1)){ taint_s = t_get_mem_taint(mem_addr); PEMU_read_mem(mem_addr, 4, &b); }else if(operand_is_reg(op_name_1, ®_id_1)){ taint_s = t_get_reg_taint(reg_id_1); b = PEMU_get_reg(reg_id_1); } // if((int)get_pc_imm(taint_s) < (int)get_pc_imm(taint_d)) if(b<a) taint_s = taint_d; t_set_reg_taint(reg_id_0, taint_s); } }
static uint32_t get_first_mmap(uint32_t addr) { uint32_t mmaddr, mmap; PEMU_read_mem(addr + pemu_guest_os.mmoffset, sizeof(mmaddr), &mmaddr); if (0 == mmaddr) PEMU_read_mem(addr + pemu_guest_os.mmoffset + sizeof(mmaddr), sizeof(mmaddr), &mmaddr); if (0 != mmaddr) PEMU_read_mem(mmaddr, sizeof(mmap), &mmap); else memset(&mmap, 0, sizeof(mmap)); return mmap; }
static uint32_t get_pgd(uint32_t addr) { uint32_t mmaddr, pgd; PEMU_read_mem(addr + pemu_guest_os.mmoffset, sizeof(mmaddr), &mmaddr); if (0 == mmaddr) PEMU_read_mem(addr + pemu_guest_os.mmoffset + sizeof(mmaddr), sizeof(mmaddr), &mmaddr); if (0 != mmaddr) PEMU_read_mem(mmaddr + pemu_guest_os.pgdoffset, sizeof(pgd), &pgd); else memset(&pgd, 0, sizeof(pgd)); return pgd; }
void insert_dependence_data(unsigned int addr, int size) { if(addr < PEMU_img_start || addr > PEMU_img_end) return; for(uint32_t i = 0; i < size; i++){ if(g_map_d_data.count(addr+i) == 0){ char byte; if(PEMU_read_mem(addr+i, 1, &byte)==0){ g_map_d_data[addr+i] = byte; #ifdef DEBUG // fprintf(stderr, "----global %x(size:%d): %x\n", addr+i,size, byte); #endif } //Hush.b //Hush.TODO else {//Reading mem fail, insert_mem_to_be_read(addr,size); //Temporarily set value as ZERO g_map_d_data[addr+i]=0; break; } //Hush.e } } }
xed_error_enum_t disas_one_inst_ex(target_ulong pc, struct PEMU_INST *inst) { PEMU_read_mem(pc, 15, inst->PEMU_inst_buf); xed_decoded_inst_zero_set_mode(&inst->PEMU_xedd_g, &inst->PEMU_dstate); xed_error_enum_t xed_error = xed_decode(&inst->PEMU_xedd_g, XED_STATIC_CAST(const xed_uint8_t *, inst->PEMU_inst_buf), 15); return xed_error; }
static xed_error_enum_t disas_one_inst(target_ulong pc) { char buf[15]; if(PEMU_read_mem(pc, 15, buf)!=0) tlb_fill(cpu_single_env, pc+14, 0, 0, 0); xed_decoded_inst_zero_set_mode(&xedd_g, &dstate); xed_error_enum_t xed_error = xed_decode(&xedd_g, XED_STATIC_CAST(const xed_uint8_t *, buf), 15); return xed_error; }
xed_error_enum_t disas_one_inst_ex(target_ulong pc, struct PEMU_INST *inst) { PEMU_read_mem(pc, 15, inst->PEMU_inst_buf); xed_decoded_inst_zero_set_mode(&inst->PEMU_xedd_g, &inst->PEMU_dstate); xed_error_enum_t xed_error = xed_decode(&inst->PEMU_xedd_g, XED_STATIC_CAST(const xed_uint8_t *, inst->PEMU_inst_buf), 15); xed_decoded_inst_dump_att_format(&inst->PEMU_xedd_g, inst->PEMU_inst_str, sizeof(inst->PEMU_inst_str), 0); //printf("%x\t%s\n", pc, inst->PEMU_inst_str); return xed_error; }
int disas_is_call(target_ulong pc) { char buf[15]; PEMU_read_mem(pc, 15, buf); if(buf[0] == (char)0xe8 || buf[0] == (char)0xff) { return 1; } else { return 0; } }
static uint32_t next_task_struct(uint32_t addr) { uint32_t retval; uint32_t next; PEMU_read_mem(addr + pemu_guest_os.listoffset + sizeof(uint32_t), sizeof(uint32_t), &next); retval = next - pemu_guest_os.listoffset; return retval; }
xed_error_enum_t disas_callnear_ex(target_ulong pc, struct PEMU_INST *inst) { PEMU_read_mem(pc, 15, inst->PEMU_inst_buf); if(pemu_inst.PEMU_inst_buf[0] != (char)0xe8 && pemu_inst.PEMU_inst_buf[0] != (char)0xff) { return XED_ERROR_LAST; } xed_decoded_inst_zero_set_mode(&inst->PEMU_xedd_g, &inst->PEMU_dstate); xed_error_enum_t xed_error = xed_decode(&inst->PEMU_xedd_g, XED_STATIC_CAST(const xed_uint8_t *, inst->PEMU_inst_buf), 15); //xed_decoded_inst_dump_att_format(&inst->PEMU_xedd_g, inst->PEMU_inst_str, sizeof(inst->PEMU_inst_str), 0); return xed_error; }
void update_mem_to_be_read(){ for(map<unsigned int, unsigned int>::iterator it=mem_to_be_read.begin();it!=mem_to_be_read.end();it++){ for(int j=0;j<it->second;j++){ if(g_map_d_data.count(it->first+j)==0){ char fix; if(PEMU_read_mem(it->first+j,1,&fix)==0){ g_map_d_data[it->first+j]=fix; }else{ break; } } } } mem_to_be_read.clear(); }
void helper_store1(target_ulong src, target_ulong addr, int size) { { NodeType *s, *d; if(src < 0xc0000000 || size != 4) { return; } target_ulong dst; PEMU_read_mem(addr, 4, &dst); if((s = ds_code_rbtFind2(src)) && (d = ds_code_rbtFind2(dst))) { add_pointTo(g_pc, d->type, dst-d->key, s->type, src-s->key); } } }
void helper_load1(target_ulong src, int size) { { NodeType *s, *d; if(src < 0xc0000000 || size != 4) { return; } target_ulong dst; PEMU_read_mem(src, 4, &dst); if((s = ds_code_rbtFind2(src)) && (d = ds_code_rbtFind2(dst))) { add_traverse(g_pc, s->type, src-s->key, d->type, dst-d->key); } } }
static target_ulong Instrument_CALL_NEAR( const xed_inst_t * ins, target_ulong pc) { uint32_t mem_addr; xed_reg_enum_t reg_id; target_ulong target; const xed_operand_t *op = xed_inst_operand(ins, 0); xed_operand_enum_t op_name = xed_operand_name(op); if (operand_is_mem(op_name, &mem_addr, 0)) { PEMU_read_mem(mem_addr,sizeof(target) , &target); } else if (operand_is_reg(op_name, ®_id)){ target = PEMU_get_reg(reg_id); } else{ int len = xed_decoded_inst_get_length(&xedd_g); target = xed_decoded_inst_get_branch_displacement(&xedd_g) + pc + len; } return target; }
static target_ulong Instrument_RET(const xed_inst_t * ins) { target_ulong esp = PEMU_get_reg(XED_REG_ESP); target_ulong target; PEMU_read_mem(esp, sizeof(target), &target); return target; }
static uint32_t get_vmflags(uint32_t addr) { uint32_t vmflags; PEMU_read_mem(addr + pemu_guest_os.vmflagsoffset, sizeof(vmflags), &vmflags); return vmflags; }
static void get_name(uint32_t addr, int size, char *buf) { PEMU_read_mem(addr + pemu_guest_os.commoffset, 16, buf); }
static void Instrument_CALL(const xed_inst_t* xi) { #ifdef DEBUG fprintf(stdout, "txt:instrument_call\n"); #endif xed_reg_enum_t reg_id; unsigned int dest = 0, taint = 0; uint32_t buf; char *fname; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); API_TYPE type; INST *inst; if(operand_is_mem4(op_name, &dest, 0)){ int mem_idx = op_name == XED_OPERAND_MEM1 ? 1 : 0; xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd_g, mem_idx); PEMU_read_mem(dest, 4, &buf); dest = buf; if(taint = t_get_reg_taint(base_regid)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call1\n"); #endif if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } }else if(taint = t_get_mem_taint(dest)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call2\n"); #endif if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } } return; }else if(operand_is_reg(op_name, ®_id)){ #ifdef DEBUG fprintf(stdout, "txt: indirect call3\n"); #endif if(taint = t_get_reg_taint(reg_id)){ insert_pc_addr(taint, 2); dest = PEMU_get_reg(reg_id); if(type = is_api_call(dest, &fname)){ goto API_CALL; }else{ insert_pc_addr(taint, 2); } } return; }else if(operand_is_relbr(op_name, &dest)){ dest += (g_pc + xed_decoded_inst_get_length(&xedd_g)); if(type = is_api_call(dest, &fname)){ #ifdef DEBUG fprintf(stdout, "is_api_call\t%x\t%x\n", dest, type); #endif goto REST; } return; } API_CALL: inst = get_inst(taint); // api_copy(&inst->api_call, get_api_call(dest)); REST: #ifdef DEBUG fprintf(stdout, "taint:\t%x\t%x\n", taint, dest); #endif t_set_reg_taint(XED_REG_EAX, 0); handle_api_issues(get_api_call(dest), 0); }
static uint32_t get_vmend(uint32_t addr) { uint32_t vmend; PEMU_read_mem(addr + pemu_guest_os.vmendoffset, sizeof(vmend), &vmend); return vmend; }
static void Instrument_CALL(const xed_inst_t* xi) { #ifdef DEBUG fprintf(stdout, "data:instrument_call\n"); #endif xed_reg_enum_t reg_id; uint32_t buf; unsigned int value = 0, dest = 0; const xed_operand_t *op = xed_inst_operand(xi, 0); xed_operand_enum_t op_name = xed_operand_name(op); char *fname = 0; unsigned int taint = 0; API_TYPE type; //TODO: value may be plt call if(operand_is_mem4(op_name, &dest, 0)){ int mem_idx = op_name == XED_OPERAND_MEM1 ? 1 : 0; xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd_g, mem_idx); PEMU_read_mem(dest, 4, &buf); dest = buf; if(taint = d_get_reg_taint(base_regid)){ if(type = is_api_call(dest, &fname)){ // update_mem_val_type(taint, 2, type, fname); goto API_CALL; }else{ update_mem_val_type(taint, 2, API_NONE, 0); } }else if(taint = d_get_mem_taint(dest)){ if(type = is_api_call(dest, &fname)){ // update_mem_val_type(taint, 2, type, fname); goto API_CALL; }else{ update_mem_val_type(taint, 2, API_NONE, 0); } } /* else if(taint = t_get_reg_taint(base_regid)) { uint32_t mem_addr=dest; PEMU_read_mem(dest, 4, buf); dest = *(unsigned int*)buf; insert_mem_val(mem_addr, dest); if(type = is_api_call(dest, &fname)){ update_mem_val_type(mem_addr, 2, type, fname); }else{ update_mem_val_type(mem_addr, 2, API_NONE, 0); } }else if(base_regid==XED_REG_INVALID) { uint32_t mem_addr=dest; PEMU_read_mem(dest, 4, buf); dest = *(unsigned int*)buf; insert_mem_val(mem_addr, dest); if(type = is_api_call(dest, &fname)){ update_mem_val_type(mem_addr, 2, type, fname); }else{ update_mem_val_type(mem_addr, 2, API_NONE, 0); } }*/ return; }else if(operand_is_reg(op_name, ®_id)){ if(taint = d_get_reg_taint(reg_id)){ dest = PEMU_get_reg(reg_id); if(type = is_api_call(dest, &fname)){ // update_mem_val_type(taint, 2, type, fname); goto API_CALL; }else{ update_mem_val_type(taint, 2, API_NONE, 0); } } return; }else if(operand_is_relbr(op_name, &dest)){ dest += (g_pc + xed_decoded_inst_get_length(&xedd_g)); if(type = is_api_call(dest, &fname)){ #ifdef DEBUG fprintf(stdout, "is_api_call\t%x\t%x\n", dest, type); #endif goto REST; } return; } API_CALL: update_mem_val_type(taint, 2, type, fname); //api_copy(&inst->api_call, get_api_call(dest)); REST: handle_api_issues(get_api_call(dest), 1); }
static uint32_t get_vmstart(uint32_t addr) { uint32_t vmstart; PEMU_read_mem(addr + pemu_guest_os.vmstartoffset, sizeof(vmstart), &vmstart); return vmstart; }
/*****************interface functions********************/ void handle_data_rewrite(const xed_inst_t* xi) { unsigned int value = 0, mem_addr = 0, begin = 0, end = 0; xed_reg_enum_t reg_id_0; if(data_func[0] == 0){ setup_data_taint(); } xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g); const xed_operand_t *op1 = xed_inst_operand(xi, 1); xed_operand_enum_t op_name1 = xed_operand_name(op1); const xed_operand_t *op0 = xed_inst_operand(xi, 0); xed_operand_enum_t op_name0 = xed_operand_name(op0); //dependence data store data addresses unsigned int taint = 0; int mem_idx; if(opcode != XED_ICLASS_LEA){ if(operand_is_mem4(op_name0, &mem_addr, 0)){ mem_idx = op_name0 == XED_OPERAND_MEM1 ? 1 : 0; xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd_g, mem_idx); if((base_regid != XED_REG_INVALID)){ if(taint = d_get_reg_taint(base_regid)){ update_mem_val_type(taint, 1, API_NONE, 0); value = get_mem_val(taint)->val; insert_dependence_data(mem_addr,xed_decoded_inst_operand_length(&xedd_g, 0)); /* if(value < mem_addr)//value is root insert_dependence_data(value, mem_addr + xed_decoded_inst_operand_length(&xedd_g, 0) - value); else{ insert_dependence_data(mem_addr, value > mem_addr + xed_decoded_inst_operand_length(&xedd_g, 0) ? value : mem_addr + xed_decoded_inst_operand_length(&xedd_g, 0) - mem_addr); }*/ } } }else if(operand_is_mem4(op_name1, &mem_addr, 1)){ mem_idx = op_name1 == XED_OPERAND_MEM1 ? 1 : 0; xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd_g, mem_idx); xed_reg_enum_t index_regid = xed_decoded_inst_get_index_reg(&xedd_g, mem_idx); if((base_regid != XED_REG_INVALID)){ int a = 0,b = 0; a = PEMU_get_reg(base_regid); b = PEMU_get_reg(index_regid); if(index_regid!=XED_REG_INVALID && b>a){ if((taint = d_get_reg_taint(index_regid))&&mem_taint==0) { update_mem_val_type(taint, 1, API_NONE, 0); value = get_mem_val(taint)->val; insert_dependence_data(mem_addr,xed_decoded_inst_operand_length(&xedd_g, 0)); } }else if((taint = d_get_reg_taint(base_regid))&&mem_taint==0){ update_mem_val_type(taint, 1, API_NONE, 0); value = get_mem_val(taint)->val; insert_dependence_data(mem_addr,xed_decoded_inst_operand_length(&xedd_g, 0)); } } } } //taint source: if(opcode == XED_ICLASS_PUSH ){ if(operand_is_mem4(op_name0, &mem_addr, 0)){ if(is_dependence_addr(mem_addr) && !is_d_written(mem_addr)){ unsigned int esp = PEMU_get_reg(XED_REG_ESP) - 4; #ifdef DEBUG fprintf(stdout, "taint source:\t%x\n", mem_addr); #endif d_set_mem_taint_bysize(esp, mem_addr, 4); PEMU_read_mem(mem_addr, 4, &value); insert_mem_val(mem_addr, value); } } }else if(opcode == XED_ICLASS_JMP || opcode == XED_ICLASS_CALL_NEAR) { if(operand_is_mem4(op_name0, &mem_addr, 0)){ if(is_dependence_addr(mem_addr) && !is_d_written(mem_addr)){ #ifdef DEBUG fprintf(stdout, "taint source:\t%x\n", mem_addr); #endif d_set_mem_taint_bysize(mem_addr, mem_addr, 4); PEMU_read_mem(mem_addr, 4, &value); insert_mem_val(mem_addr, value); } } }else{ if(opcode != XED_ICLASS_LEA && operand_is_mem4(op_name1, &mem_addr, 1)){ if(is_dependence_addr(mem_addr) && !is_d_written(mem_addr)){ if(operand_is_reg(op_name0, ®_id_0)){ #ifdef DEBUG fprintf(stdout, "taint source:\t%x\n", mem_addr); #endif d_set_reg_taint(reg_id_0, mem_addr); PEMU_read_mem(mem_addr, 4, &value); insert_mem_val(mem_addr, value); }else{ fprintf(stderr, "error in handle_data_rewrite\n"); exit(0); } return; } } } //propagation data_func[opcode](xi); }
static uint32_t get_next_mmap(uint32_t addr) { uint32_t mmap; PEMU_read_mem(addr + pemu_guest_os.vmnextoffset, sizeof(mmap), &mmap); return mmap; }