static void Instrument_MOV(const xed_inst_t* xi) { xed_reg_enum_t reg_id_0, reg_id_1; unsigned int mem_addr, imm; 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_reg(op_name_1, ®_id_1)){ d_set_mem_taint_bysize(mem_addr, d_get_reg_taint(reg_id_1), xed_decoded_inst_operand_length(&xedd_g, 0)); }else if(operand_is_imm(op_name_1, &imm)){ d_set_mem_taint_bysize(mem_addr, xed_decoded_inst_operand_length(&xedd_g, 0), 0); } }else if(operand_is_reg(op_name_0, ®_id_0)){ if(operand_is_mem4(op_name_1, &mem_addr, 1)){ d_set_reg_taint(reg_id_0, d_get_mem_taint(mem_addr)); }else if(operand_is_reg(op_name_1, ®_id_1)){ d_set_reg_taint(reg_id_0, d_get_reg_taint(reg_id_1)); }else if(operand_is_imm(op_name_1, &imm)){ d_set_reg_taint(reg_id_0, 0); } } }
/* * A routine to query the immediate operand per instruction. May be called at * instrumentation or analysis time. */ VOID GetOperLenAndSigned(INS ins, INT32 i, INT32& length_bits, bool& is_signed) { xed_decoded_inst_t* xedd = INS_XedDec(ins); // To print out the gory details uncomment this: // char buf[2048]; // xed_decoded_inst_dump(xedd, buf, 2048); // *outFile << buf << endl; length_bits = 8*xed_decoded_inst_operand_length(xedd, i); is_signed = xed_decoded_inst_get_immediate_is_signed(xedd); }
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 PyObject *get_operand_length(instruction_t *self, PyObject *args) { unsigned int i, length; xed_decoded_inst_t *decoded_inst; PyObject *r = NULL; if(PyArg_ParseTuple(args, "I", &i) == 0) goto _err; decoded_inst = self->decoded_inst; if(i >= xed_decoded_inst_noperands(decoded_inst)) { PyErr_SetString(PyExc_IndexError, "Invalid operand index"); goto _err; } length = xed_decoded_inst_operand_length(decoded_inst, i); r = PyLong_FromUnsignedLong(length); _err: return r; }
/*****************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); }
/* This is the central function Given a memory address, reads a bunch of memory bytes and calls the disassembler to obtain the information Then it stores the information into the eh EntryHeader */ void decode_address(uint32_t address, EntryHeader *eh, int ignore_taint) { unsigned char insn_buf[MAX_INSN_BYTES]; unsigned int is_stackpush = 0, is_stackpop = 0; unsigned int stackpushpop_acc = 0; if (xed2chris_regmapping[XED_REG_EAX][0] == 0) { init_xed2chris(); assert(xed2chris_regmapping[XED_REG_EAX][0] != 0); } /* Read memory from TEMU */ TEMU_read_mem(address, MAX_INSN_BYTES, insn_buf); /* Disassemble instruction buffer */ xed_decoded_inst_zero_set_mode(&xedd, &dstate); xed_error_enum_t xed_error = xed_decode(&xedd, STATIC_CAST(const xed_uint8_t*,insn_buf), MAX_INSN_BYTES); xed_bool_t okay = (xed_error == XED_ERROR_NONE); if (!okay) return; // Increase counters tstats.insn_counter_decoded++; int i; /* Clear out Entry header */ memset(eh, 0, sizeof(EntryHeader)); /* Copy the address and instruction size */ eh->address = address; eh->inst_size = xed_decoded_inst_get_length(&xedd); if (eh->inst_size > MAX_INSN_BYTES) eh->inst_size = MAX_INSN_BYTES; /* Copy instruction rawbytes */ memcpy(eh->rawbytes, insn_buf, eh->inst_size); /* Get the number of XED operands */ const xed_inst_t* xi = xed_decoded_inst_inst(&xedd); int xed_ops = xed_inst_noperands(xi); int op_idx = -1; /* Get the category of the instruction */ xed_category_enum_t category = xed_decoded_inst_get_category(&xedd); /* Iterate over the XED operands */ for(i = 0; i < xed_ops; i++) { if(op_idx >= MAX_NUM_OPERANDS) break; //assert(op_idx < MAX_NUM_OPERANDS); /* Get operand */ const xed_operand_t* op = xed_inst_operand(xi,i); xed_operand_enum_t op_name = xed_operand_name(op); switch(op_name) { /* Register */ case XED_OPERAND_REG0: case XED_OPERAND_REG1: case XED_OPERAND_REG2: case XED_OPERAND_REG3: case XED_OPERAND_REG4: case XED_OPERAND_REG5: case XED_OPERAND_REG6: case XED_OPERAND_REG7: case XED_OPERAND_REG8: case XED_OPERAND_REG9: case XED_OPERAND_REG10: case XED_OPERAND_REG11: case XED_OPERAND_REG12: case XED_OPERAND_REG13: case XED_OPERAND_REG14: case XED_OPERAND_REG15: { xed_reg_enum_t reg_id = xed_decoded_inst_get_reg(&xedd, op_name); int regnum = xed2chris_regmapping[reg_id][1]; // Special handling for Push if (reg_id == XED_REG_STACKPUSH) is_stackpush = 1; else if (reg_id == XED_REG_STACKPOP) is_stackpop = 1; if (-1 == regnum) break; else { op_idx++; eh->num_operands++; eh->operand[op_idx].type = TRegister; eh->operand[op_idx].addr = xed2chris_regmapping[reg_id][0]; eh->operand[op_idx].length = (uint8_t) xed_decoded_inst_operand_length (&xedd, i); eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); eh->operand[op_idx].value = TEMU_cpu_regs[regnum]; switch (eh->operand[op_idx].addr) { case ax_reg: case bx_reg: case cx_reg: case dx_reg: case bp_reg: case sp_reg: case si_reg: case di_reg: eh->operand[op_idx].value &= 0xFFFF; break; case al_reg: case bl_reg: case cl_reg: case dl_reg: eh->operand[op_idx].value &= 0xFF; break; case ah_reg: case bh_reg: case ch_reg: case dh_reg: eh->operand[op_idx].value = (eh->operand[i].value & 0xFF00) >> 8; break; default: break; } } if (ignore_taint == 0) set_operand_data(&(eh->operand[op_idx])); break; } /* Immediate */ case XED_OPERAND_IMM0: { op_idx++; eh->num_operands++; eh->operand[op_idx].type = TImmediate; eh->operand[op_idx].length = (uint8_t) xed_decoded_inst_operand_length (&xedd, i); eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); //xed_uint_t width = xed_decoded_inst_get_immediate_width(&xedd); if (xed_decoded_inst_get_immediate_is_signed(&xedd)) { xed_int32_t signed_imm_val = xed_decoded_inst_get_signed_immediate(&xedd); eh->operand[op_idx].value = (uint32_t) signed_imm_val; } else { xed_uint64_t unsigned_imm_val = xed_decoded_inst_get_unsigned_immediate(&xedd); eh->operand[op_idx].value = (uint32_t) unsigned_imm_val; } break; break; } /* Special immediate only used in ENTER instruction */ case XED_OPERAND_IMM1: { op_idx++; eh->num_operands++; eh->operand[op_idx].type = TImmediate; eh->operand[op_idx].length = (uint8_t) xed_decoded_inst_operand_length (&xedd, i); eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); xed_uint8_t unsigned_imm_val = xed_decoded_inst_get_second_immediate(&xedd); eh->operand[op_idx].value = (uint32_t) unsigned_imm_val; break; } /* Memory */ case XED_OPERAND_AGEN: case XED_OPERAND_MEM0: case XED_OPERAND_MEM1: { unsigned long base = 0; unsigned long index = 0; unsigned long scale = 1; unsigned long segbase = 0; unsigned short segsel = 0; unsigned long displacement = 0; unsigned int j; size_t remaining = 0; /* Set memory index */ int mem_idx = 0; if (op_name == XED_OPERAND_MEM1) mem_idx = 1; unsigned int memlen = xed_decoded_inst_operand_length (&xedd, i); for (j = 0; j < memlen; j+=4) { /* Initialization */ base = 0; index = 0; scale = 1; segbase = 0; segsel = 0; displacement = 0; remaining = memlen - j; op_idx++; if(op_idx >= MAX_NUM_OPERANDS) break; //assert(op_idx < MAX_NUM_OPERANDS); eh->num_operands++; eh->operand[op_idx].type = TMemLoc; eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); eh->operand[op_idx].length = remaining > 4 ? 4 : (uint8_t) remaining; // Get Segment register xed_reg_enum_t seg_regid = xed_decoded_inst_get_seg_reg(&xedd,mem_idx); if (seg_regid != XED_REG_INVALID) { const xed_operand_values_t *xopv = xed_decoded_inst_operands_const(&xedd); xed_bool_t default_segment = xed_operand_values_using_default_segment (xopv,mem_idx); if (!default_segment) { eh->num_operands++; int segmentreg = xed2chris_regmapping[seg_regid][0] - 100; segbase = TEMU_cpu_segs[segmentreg].base; segsel = TEMU_cpu_segs[segmentreg].selector; eh->memregs[op_idx][0].type = TRegister; eh->memregs[op_idx][0].length = 2; eh->memregs[op_idx][0].addr = xed2chris_regmapping[seg_regid][0]; eh->memregs[op_idx][0].access = (uint8_t) XED_OPERAND_ACTION_R; eh->memregs[op_idx][0].value = segsel; eh->memregs[op_idx][0].usage = memsegment; if (ignore_taint == 0) set_operand_data(&(eh->memregs[op_idx][0])); int dt; if (segsel & 0x4) // ldt dt = TEMU_cpu_ldt->base; else //gdt dt = TEMU_cpu_gdt->base; segsel = segsel >> 3; unsigned long segent = dt + 8 * segsel; unsigned char segdes[8]; TEMU_read_mem(segent, 8, segdes); #if 0 // debugging code to double check segbase value unsigned long segbasenew = segdes[2] + segdes[3] * 256 + segdes[4] * 256 * 256 + segdes[7] * 256 * 256 * 256; if (segbase != segbasenew) { term_printf("segbase unexpected: 0x%08lX v.s 0x%08lX\n", segbase, segbasenew); } #endif /* Segment descriptor is stored as a memory operand */ eh->num_operands+=2; eh->memregs[op_idx][3].type = TMemLoc; eh->memregs[op_idx][3].length = 4; eh->memregs[op_idx][3].addr = segent; eh->memregs[op_idx][3].access = (uint8_t) XED_OPERAND_ACTION_INVALID; eh->memregs[op_idx][3].value = *(uint32_t *) segdes; eh->memregs[op_idx][3].tainted = 0; eh->memregs[op_idx][3].usage = memsegent0; eh->memregs[op_idx][4].type = TMemLoc; eh->memregs[op_idx][4].length = 4; eh->memregs[op_idx][4].addr = segent + 4; eh->memregs[op_idx][4].access = (uint8_t) XED_OPERAND_ACTION_INVALID; eh->memregs[op_idx][4].value = *(uint32_t *) (segdes + 4); eh->memregs[op_idx][4].tainted = 0; eh->memregs[op_idx][4].usage = memsegent1; } } // Get Base register xed_reg_enum_t base_regid = xed_decoded_inst_get_base_reg(&xedd,mem_idx); if (base_regid != XED_REG_INVALID) { eh->num_operands++; int basereg = xed2chris_regmapping[base_regid][1]; base = TEMU_cpu_regs[basereg]; eh->memregs[op_idx][1].type = TRegister; eh->memregs[op_idx][1].addr = xed2chris_regmapping[base_regid][0]; eh->memregs[op_idx][1].length = 4; eh->memregs[op_idx][1].access = (uint8_t) XED_OPERAND_ACTION_R; eh->memregs[op_idx][1].value = base; eh->memregs[op_idx][1].usage = membase; if (ignore_taint == 0) set_operand_data(&(eh->memregs[op_idx][1])); } // Get Index register and Scale xed_reg_enum_t index_regid = xed_decoded_inst_get_index_reg(&xedd,mem_idx); if (mem_idx == 0 && index_regid != XED_REG_INVALID) { eh->num_operands++; int indexreg = xed2chris_regmapping[index_regid][1]; index = TEMU_cpu_regs[indexreg]; eh->memregs[op_idx][2].type = TRegister; eh->memregs[op_idx][2].addr = xed2chris_regmapping[index_regid][0]; eh->memregs[op_idx][2].length = 4; eh->memregs[op_idx][2].access = (uint8_t) XED_OPERAND_ACTION_R; eh->memregs[op_idx][2].value = index; eh->memregs[op_idx][2].usage = memindex; if (ignore_taint == 0) set_operand_data(&(eh->memregs[op_idx][2])); // Get Scale (AKA width) (only have a scale if the index exists) if (xed_decoded_inst_get_scale(&xedd,i) != 0) { scale = (unsigned long) xed_decoded_inst_get_scale(&xedd,mem_idx); } } // Get displacement (AKA offset) displacement = (unsigned long) xed_decoded_inst_get_memory_displacement (&xedd,mem_idx); // Fix displacement for: // 1) Any instruction that pushes into the stack, since ESP is // decremented before memory operand is written using ESP. // Affects: ENTER,PUSH,PUSHA,PUSHF,CALL if (is_stackpush) { stackpushpop_acc += eh->operand[op_idx].length; displacement = displacement - stackpushpop_acc -j; } // 2) Pop instructions where the // destination operand is a memory location that uses ESP // as base or index register. // The pop operations increments ESP and the written memory // location address needs to be adjusted. // Affects: pop (%esp) else if ((category == XED_CATEGORY_POP) && (!is_stackpop)) { if ((eh->memregs[op_idx][1].addr == esp_reg) || (eh->memregs[op_idx][2].addr == esp_reg)) { displacement = displacement + eh->operand[op_idx].length; } } // Calculate memory address accessed eh->operand[op_idx].addr = j + segbase + base + index * scale + displacement; // Special handling for LEA instructions if (op_name == XED_OPERAND_AGEN) { eh->operand[op_idx].type = TMemAddress; eh->operand[op_idx].length = 4; has_page_fault = 0; // LEA won't trigger page fault } else { has_page_fault = TEMU_read_mem(eh->operand[op_idx].addr, (int)(eh->operand[op_idx].length), (uint8_t *)&(eh->operand[op_idx].value)); } // Check if instruction accesses user memory // kernel_mem_start defined in shared/read_linux.c if ((eh->operand[op_idx].addr < kernel_mem_start) && (op_name != XED_OPERAND_AGEN)) { access_user_mem = 1; } if (ignore_taint == 0) set_operand_data(&(eh->operand[op_idx])); } break; } /* Jumps */ case XED_OPERAND_PTR: // pointer (always in conjunction with a IMM0) case XED_OPERAND_RELBR: { // branch displacements xed_uint_t disp = xed_decoded_inst_get_branch_displacement(&xedd); /* Displacement is from instruction end */ /* Adjust displacement with instruction size */ disp = disp + eh->inst_size; op_idx++; eh->num_operands++; eh->operand[op_idx].type = TJump; eh->operand[op_idx].length = 4; eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); eh->operand[op_idx].value = disp; break; } /* Floating point registers */ case XED_REG_X87CONTROL: case XED_REG_X87STATUS: case XED_REG_X87TOP: case XED_REG_X87TAG: case XED_REG_X87PUSH: case XED_REG_X87POP: case XED_REG_X87POP2: op_idx++; eh->num_operands++; eh->operand[op_idx].type = TFloatRegister; eh->operand[op_idx].length = 4; eh->operand[op_idx].access = (uint8_t) xed_operand_rw (op); default: break; } }
/*****************interface functions********************/ void handle_txt_rewrite(const xed_inst_t* xi) { uint32_t value = 0, taint = 0; int i = 0; const xed_operand_t *op; xed_operand_enum_t op_name; unsigned int mem_addr; if(txt_func[0] == 0){ setup_txt_taint(); } int noperands = xed_inst_noperands(xi); xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g); noperands = noperands > 2 ? 2 : noperands; for( i = 0; i < noperands ; i++){ /* Immediate */ op = xed_inst_operand(xi, i); op_name = xed_operand_name(op); if(opcode == XED_ICLASS_LEA)//hardcode continue; if(operand_is_imm(op_name, &value)) insert_pc_imm(g_pc, value); if(operand_is_mem4(op_name, &mem_addr, i)){ unsigned int taint; unsigned int displacement = 0; int mem_idx = op_name == XED_OPERAND_MEM1 ? 1 : 0; if(xed_operand_written(op)) insert_d_written(mem_addr); 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); displacement = (unsigned int) xed_decoded_inst_get_memory_displacement(&xedd_g, mem_idx); #if 0 if((base_regid != XED_REG_INVALID)) {//indirect mem access if((taint = t_get_reg_taint(base_regid)) && (mem_taint == 0)) {//base reg unsigned int imm = get_pc_imm(taint); //yang insert_pc_addr(taint, 1); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } else if(mem_taint != 0) { //displacement insert_pc_addr(g_pc, 3); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } } else if(index_regid != XED_REG_INVALID) { if((taint = t_get_reg_taint(index_regid)) && (mem_taint ==0)) { insert_pc_addr(taint, 1); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } else if(mem_taint != 0) { insert_pc_addr(g_pc, 3); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } } else if(displacement > 0) {//displacement insert_dependence_data(displacement, mem_addr + xed_decoded_inst_operand_length(&xedd_g, i) - displacement); insert_pc_addr(g_pc, 3); } #endif switch(find_min_dist(mem_addr, g_base, g_index, g_disp)) { case 1: if(taint = t_get_reg_taint(base_regid)) { insert_pc_addr(taint, 1); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } break; case 2: if(taint = t_get_reg_taint(index_regid)) { insert_pc_addr(taint, 1); insert_dependence_data(mem_addr, xed_decoded_inst_operand_length(&xedd_g, i)); } break; case 3: insert_dependence_data(displacement, mem_addr + xed_decoded_inst_operand_length(&xedd_g, i) - displacement); insert_pc_addr(g_pc, 3); break; default: break; } } } unsigned int esp; xed_reg_enum_t dest_r; op_name = xed_operand_name(xed_inst_operand(xi, 0)); if(value != 0){//taint source switch(opcode){ case XED_ICLASS_PUSH: esp = PEMU_get_reg(XED_REG_ESP) - 4; t_set_mem_taint_bysize(esp, g_pc, 4); break; case XED_ICLASS_MOV: if(operand_is_mem4(op_name, &mem_addr, 0)){ t_set_mem_taint_bysize(mem_addr, g_pc, xed_decoded_inst_operand_length(&xedd_g, 0)); }else if(operand_is_reg(op_name, &dest_r)){ t_set_reg_taint(dest_r, g_pc); } break; defalut: break; } return; } //propagation txt_func[opcode](xi); }