static void add_write_operands(xed_dot_graph_supp_t* gg, xed_decoded_inst_t* xedd, xed_dot_node_t* n) { xed_uint_t i, noperands; xed_reg_enum_t r, r_enclosing; const xed_inst_t* xi = 0; xi = xed_decoded_inst_inst(xedd); noperands = xed_inst_noperands(xi); for( i=0; i < noperands ; i++) { const xed_operand_t* op = xed_inst_operand(xi,i); xed_operand_enum_t opname = xed_operand_name(op); if (xed_operand_is_register(opname) || xed_operand_is_memory_addressing_register(opname)) { if (xed_operand_written(op)) { /* set n as the source of the value. */ /* ignoring partial writes */ r = xed_decoded_inst_get_reg(xedd, opname); r_enclosing = xed_get_largest_enclosing_register(r); gg->xed_reg_to_node[r_enclosing] = n; } } } /* for */ }
/*****************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); }