static void add_read_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;
    const xed_inst_t* xi =  0;
    xed_bool_t found = 0;
    xi = xed_decoded_inst_inst(xedd);
    noperands = xed_inst_noperands(xi);
    
    for( i=0; i < noperands ; i++) {
        int memop = -1;
        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_read(op)) {
                 /* add edge to n */
                 r = xed_decoded_inst_get_reg(xedd, opname);
                 found |= add_edge(gg, n, r);
             }
             continue;
        }
        if (opname == XED_OPERAND_MEM0) 
            memop = 0;
        else if (opname == XED_OPERAND_MEM1 ) 
            memop = 1;

        if (memop != -1) {
            /* get reads of base/index regs,  if any */
            xed_reg_enum_t base, indx;
            
            base = xed_decoded_inst_get_base_reg(xedd,memop);
            indx = xed_decoded_inst_get_index_reg(xedd,memop);
            if (base != XED_REG_INVALID) 
                found |= add_edge(gg, n, base);

            indx = xed_decoded_inst_get_index_reg(xedd,memop);
            if (indx != XED_REG_INVALID) 
                found |= add_edge(gg, n, indx);
        }
    } /* for */
    if (!found) {
        /* add an edge from start */
        xed_dot_edge(gg->g, gg->start, n);
    }
}
Esempio n. 2
0
static void Instrument_LEA(const xed_inst_t* xi)
{
	xed_reg_enum_t reg_id;
	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_1, &mem_addr, 1)){
		if (operand_is_reg(op_name_0, &reg_id)){
			int mem_idx = 0;
			if (op_name_1 == XED_OPERAND_MEM1)
				mem_idx = 1;

			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(index_regid == XED_REG_INVALID && mem_taint == 0)
            //   t_set_reg_taint(reg_id, t_get_reg_taint(base_regid));
			if(index_regid == XED_REG_INVALID) {
				if(find_min_dist(mem_addr, g_base, g_index, g_disp) != 3) {
					t_set_reg_taint(reg_id, t_get_reg_taint(base_regid));
				}
			}
            else {
                unsigned int a=0, b=0;
                if(base_regid != XED_REG_INVALID)
                    a = PEMU_get_reg(base_regid);
                b = PEMU_get_reg(index_regid);
                if( a < b)
                    t_set_reg_taint(reg_id, t_get_reg_taint(index_regid));
                else
                    t_set_reg_taint(reg_id, t_get_reg_taint(base_regid));
            }
		}else{
			fprintf(stderr, "error in Instrument_LEA\n");
			exit(0);
		}
	}else{
		fprintf(stderr, "error in Instrument_LEA\n");
		exit(0);
	}	
}
Esempio n. 3
0
static PyObject *get_index_reg(instruction_t *self, PyObject *args)
{
    unsigned int i;
    xed_decoded_inst_t *decoded_inst;
    xed_reg_enum_t reg;

    PyObject *r = NULL;

    if(PyArg_ParseTuple(args, "I", &i) == 0)
        goto _err;

    decoded_inst = self->decoded_inst;
    if(i >= xed_decoded_inst_number_of_memory_operands(decoded_inst))
    {
        PyErr_SetString(PyExc_IndexError, "Invalid operand index");
        goto _err;
    }

    reg = xed_decoded_inst_get_index_reg(decoded_inst, i);
    r = PyInt_FromLong(reg);

_err:
    return r;
}
Esempio n. 4
0
/*****************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, &reg_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);
}
Esempio n. 5
0
File: disas.c Progetto: JaonLin/pemu
static int operand_is_mem(const xed_operand_enum_t op_name, uint32_t* mem_addr, 
		   int operand_i)
{

//	xed_reg_enum_t basereg;	

	switch (op_name) {
		/* 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;
//			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(&PEMU_xedd_g, operand_i);

			/* Initialization */
			base = 0;
			index = 0;
			scale = 0;
			segbase = 0;
			segsel = 0;
			displacement = 0;

			xed_reg_enum_t seg_regid =
			    xed_decoded_inst_get_seg_reg(&xedd_g, mem_idx);

			if (seg_regid != XED_REG_INVALID)
				segbase =PEMU_get_seg(seg_regid);

			// Get Base register
			xed_reg_enum_t base_regid =
			    xed_decoded_inst_get_base_reg(&xedd_g, mem_idx);
			
			if (base_regid != XED_REG_INVALID) {
				base = PEMU_get_reg(base_regid);
			}
			// Get Index register and Scale
			xed_reg_enum_t index_regid =
			    xed_decoded_inst_get_index_reg(&xedd_g, mem_idx);
			if (mem_idx == 0 && index_regid != XED_REG_INVALID) {
				index = PEMU_get_reg(index_regid);

				if (xed_decoded_inst_get_scale
				    (&xedd_g, operand_i) != 0) {
					scale =
					    (unsigned long)
					    xed_decoded_inst_get_scale(&xedd_g,
								       mem_idx);
				}
			}
			displacement =
			    (unsigned long)
			    xed_decoded_inst_get_memory_displacement(&xedd_g,
								     mem_idx);
			*mem_addr =
			    segbase + base + index * scale + displacement;

			return 1;
		}

	default:
		return 0;
	}

}
Esempio n. 6
0
File: trace.c Progetto: anhkgg/temu
/* 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;
     }
  }
Esempio n. 7
0
/*****************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);
}