Esempio n. 1
0
File: disas.c Progetto: JaonLin/pemu
int helper_pemu_trace(target_ulong pc)
{
		
		target_ulong target;
		xed_error_enum_t xed_error = disas_one_inst(pc);

		if(xed_error != XED_ERROR_NONE){
			return -1;
		}

		const xed_inst_t * xi = xed_decoded_inst_inst(&xedd_g);
		xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g);

	//	char inst_str[512];
	//	xed_decoded_inst_dump_intel_format(&xedd_g, inst_str, 
	//		   sizeof(inst_str), 0);	
		switch(opcode){
			case XED_ICLASS_JMP:
				target = Instrument_JMP(xi, pc);
				break;
			case XED_ICLASS_CALL_NEAR:
				target = Instrument_CALL_NEAR(xi,pc);
				break;
			case XED_ICLASS_RET_NEAR:
				target = Instrument_RET(xi);
				break;
			default:
				break;
		}
		PEMU_add_trace(target);
		return 0;
}
Esempio n. 2
0
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, &reg_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;
}
Esempio n. 3
0
void check_for_mov_to_cr3(xed_decoded_inst_t* xedd)
{
    if (xed_decoded_inst_get_iclass(xedd) == XED_ICLASS_MOV_CR)
    {
        // we know mov_cr has 2 operands so we do not check
        // xed_inst_noperands.


        // get the skeleton (static info)
        const xed_inst_t* xi = xed_decoded_inst_inst(xedd);

        // get the dest operand (operand 0)
        const xed_operand_t* op = xed_inst_operand(xi,0);
        
        xed_operand_enum_t op_name = xed_operand_name(op);
        if (op_name == XED_OPERAND_REG0)
        {
            xed_reg_enum_t r = xed_decoded_inst_get_reg(xedd, op_name);
            if (r == XED_REG_CR3)
            {
                printf("Found a mov to CR3\n");
            }
        }
    }
}
static xed_ast_input_enum_t classify_avx_sse(xed_decoded_inst_t* xedd)
{
    xed_extension_enum_t ext = xed_decoded_inst_get_extension(xedd);
    xed_iclass_enum_t iclass  = xed_decoded_inst_get_iclass(xedd);
    if(iclass == XED_ICLASS_VZEROALL)
    {
        return XED_AST_INPUT_VZEROALL;
    }
    else if(iclass == XED_ICLASS_VZEROUPPER)
    {
        return XED_AST_INPUT_VZEROUPPER;
    }
    else if(is_interesting_avx(ext))
    {
        if(is_avx128(xedd))
            return XED_AST_INPUT_AVX128;
        return XED_AST_INPUT_AVX256;
    }
    else if(is_sse(xedd))
    {
        return XED_AST_INPUT_SSE;
    }
    else if(iclass == XED_ICLASS_XRSTOR)
    {
        return XED_AST_INPUT_XRSTOR;
    }
    return XED_AST_INPUT_NOTHING;
}
xed_uint_t disas_decode_binary(const xed_state_t* dstate,
                               const xed_uint8_t* hex_decode_text,
                               const unsigned int bytes,
                               xed_decoded_inst_t* xedd,
                               xed_uint64_t runtime_address) {
    xed_uint64_t t1,t2;
    xed_error_enum_t xed_error;
    xed_bool_t okay;

    if (CLIENT_VERBOSE) {
        print_hex_line(hex_decode_text, bytes);
    }
    t1 = xed_get_time();
    xed_error = xed_decode(xedd, hex_decode_text, bytes);
    t2 = xed_get_time();
    okay = (xed_error == XED_ERROR_NONE);
    if (CLIENT_VERBOSE3) {
        xed_uint64_t delta = t2-t1;
        printf("Decode time = " XED_FMT_LU "\n", delta);
    }
    if (okay)     {

        if (CLIENT_VERBOSE1) {
            char tbuf[XED_TMP_BUF_LEN];
            xed_decoded_inst_dump(xedd,tbuf,XED_TMP_BUF_LEN);
            printf("%s\n",tbuf);
        }
        if (CLIENT_VERBOSE) {
            char buf[XED_TMP_BUF_LEN];
            if (xed_decoded_inst_valid(xedd)) 
            {
                printf( "ICLASS: %s   CATEGORY: %s   EXTENSION: %s  IFORM: %s"
                        "   ISA_SET: %s\n", 
                xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(xedd)),
                xed_category_enum_t2str(xed_decoded_inst_get_category(xedd)),
                xed_extension_enum_t2str(xed_decoded_inst_get_extension(xedd)),
                xed_iform_enum_t2str(xed_decoded_inst_get_iform_enum(xedd)),
                xed_isa_set_enum_t2str(xed_decoded_inst_get_isa_set(xedd)));
            }
            memset(buf,0,XED_TMP_BUF_LEN);
            disassemble(buf,XED_TMP_BUF_LEN, xedd, runtime_address,0);
            printf("SHORT: %s\n", buf);
        }
        return 1;
    }
    else {
        xed_decode_error(0, 0, hex_decode_text, xed_error);
        return 0;
    }
    (void) dstate; // pacify compiler
}
xed_iclass_enum_t
xed_iclass(char* ins)
{
  xed_decoded_inst_t xedd;
  xed_decoded_inst_t *xptr = &xedd;

  xed_decoded_inst_zero_set_mode(xptr, &dbg_xed_machine_state);

  xed_error_enum_t xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
  if (xed_error != XED_ERROR_NONE) {
    fprintf(stderr, "!! XED decode failure of insruction @ %p", ins);
    return XED_ICLASS_INVALID;
  }
  return xed_decoded_inst_get_iclass(xptr);
}
Esempio n. 7
0
static int format_jcc(const xed_inst_t *xi)
{
	uint32_t dest, next;
	char opcode[20], jmp_dst[20];
	const xed_operand_t *op = xed_inst_operand(xi, 0);
	
	xed_operand_enum_t op_name = xed_operand_name(op);
	xed_reg_enum_t reg_id;
	strcpy(opcode, xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(&xedd_g)));

	INST* inst = get_inst(g_pc);

	if(operand_is_relbr(op_name, &dest)){
		next = g_pc + xed_decoded_inst_get_length(&xedd_g);
		dest += next;//TODO: handle two branch
#ifdef DEBUG
	fprintf(stdout, "format:%x\t%s\n", g_pc, g_inst_str);
#endif

#ifdef STATISTICS
		g_symbol_nums++;
		g_jcc_num++;
#endif
		if(get_inst(dest))
			sprintf(inst_buffer, "%s L_0x%x", opcode, dest);
		else{
			sprintf(inst_buffer, "%s L_ERROR_0x%x", opcode, g_current_func->begin()->first);
#ifdef STATISTICS
			g_check_nums += 1;
			fprintf(stderr, "check at pc\t%x\n", g_pc);
#endif
		}

		if(get_inst(next))
			memset(safety_guard, 0, sizeof(safety_guard));
		else{
			sprintf(safety_guard, "jmp L_ERROR_0x%x", g_current_func->begin()->first);
#ifdef STATISTICS
			fprintf(stderr, "check at pc\t%x\n", g_pc);
			g_check_nums += 1;
#endif
		}
	}else{
		fprintf(stderr, "error in format_jcc\n");
	}
}
Esempio n. 8
0
void 
VariableHunter::findAbsoluteVariable(xed_decoded_inst_t &xedd)
{
    const xed_operand_values_t* operandPtr = xed_decoded_inst_operands_const(&xedd);

    // we need to extract the variable from memory. 
    xed_bool_t mark = xed_operand_values_accesses_memory(operandPtr);
    if(!mark){
        return;
    }

    // we ignore the push or pop instruction
    xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xedd);

    if( iclass == XED_ICLASS_PUSH    || iclass  == XED_ICLASS_POP     || 
        iclass == XED_ICLASS_ENTER   || iclass == XED_ICLASS_LEAVE    ||
        iclass == XED_ICLASS_RET_FAR || iclass == XED_ICLASS_RET_NEAR )
    {
        return;
    }

    xed_int32_t          disp = (xed_int32_t)xed_operand_values_get_memory_displacement_int64(operandPtr);
    xed_reg_enum_t   base_reg = xed_operand_values_get_base_reg(operandPtr, 0);
    xed_reg_enum_t  index_reg = xed_operand_values_get_index_reg(operandPtr, 0);

    
    if(base_reg == XED_REG_INVALID && index_reg == XED_REG_INVALID)
    {
        if(absolute_variable.find(disp) == absolute_variable.end())
        {
            AbstractVariable *var = new AbstractVariable();

            var -> region = Absolute;
            var -> offset = disp;

            // we can assign a size here, if the later calculation change this size, everything is OK
            // if this variable happen to be a boundary variable, the size of instruction will be the size of variable.
            var -> size = xed_operand_values_get_memory_operand_length(operandPtr, 0);   

            absolute_variable.insert(std::make_pair<int, AbstractVariable*>(disp, var));

        }
    }

    return;
}
Esempio n. 9
0
File: disas.c Progetto: JaonLin/pemu
int PEMU_disas_handle_branch(target_ulong pc)
{
		
		xed_error_enum_t xed_error = disas_one_inst(pc);

		if(xed_error != XED_ERROR_NONE){
			return 0;
		}

		xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g);

		switch(opcode){
			case XED_ICLASS_JMP:
			case XED_ICLASS_CALL_NEAR:
				{
					const xed_inst_t * ins = xed_decoded_inst_inst(&xedd_g);
					const xed_operand_t *op = xed_inst_operand(ins, 0);
					xed_operand_enum_t op_name = xed_operand_name(op);
					int len = xed_decoded_inst_get_length(&xedd_g);
					unsigned int rel;
					if(operand_is_relbr(op_name, &rel))
					{	
						unsigned long target = pc + len + rel;
						PEMU_add_trace(target);
						return 0;
					}
					return 1;
				}

				break;
			case XED_ICLASS_RET_NEAR:
				return 1;
			default:
				break;
		}
		return 0;
}
Esempio n. 10
0
File: disas.c Progetto: JaonLin/pemu
/*for userspace now*/
int disas_basic_block_ex(target_ulong pc_start, struct PEMU_BBL *bbl)
{
	target_ulong pc;

	//if(pc_start > 0xc0000000) {
	//	return -1;
	//}

	bbl->PEMU_bbl_pc = bbl->bbl->start_pc = pc_start;
	bbl->bbl->size = 0;
	bbl->bbl->inst_count = 0;
	pc = pc_start;

	while(1){
		xed_error_enum_t xed_error = disas_one_inst(pc);

		if(xed_error != XED_ERROR_NONE){
			return -1;
		}
		//xed_decoded_inst_dump_intel_format(&xedd_g, inst_str, 
		//	   sizeof(inst_str), 0);	

		xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g);
		int len = xed_decoded_inst_get_length(&xedd_g);
		switch(opcode){
			//case XED_ICLASS_CALL_FAR:
			case XED_ICLASS_CALL_NEAR:
			//case XED_ICLASS_SYSCALL:
			//case XED_ICLASS_INT:
			//case XED_ICLASS_INT1:
			//case XED_ICLASS_INT3:
			case XED_ICLASS_RET_FAR:
			case XED_ICLASS_RET_NEAR:
			//case XED_ICLASS_IRET:
			//case XED_ICLASS_IRETD:
			//case XED_ICLASS_IRETQ:
			case XED_ICLASS_JB:
			case XED_ICLASS_JBE:
			case XED_ICLASS_JL:
			case XED_ICLASS_JLE:
			case XED_ICLASS_JMP:
			case XED_ICLASS_JMP_FAR:
			case XED_ICLASS_JNB:
			case XED_ICLASS_JNBE:
			case XED_ICLASS_JNL: 
			case XED_ICLASS_JNLE:
			case XED_ICLASS_JNO:
			case XED_ICLASS_JNP:
			case XED_ICLASS_JNS:
			case XED_ICLASS_JNZ:
			case XED_ICLASS_JO:
			case XED_ICLASS_JP:
			case XED_ICLASS_JRCXZ:
			case XED_ICLASS_JS:
			case XED_ICLASS_JZ:
				return pc + len;
			default:
				//TODO:
				return;
				//set_code_cache(pc, TAINTED);
				//printf("pc=%lu\tlen=%x\n", pc, len);

		}
		pc += len;
		bbl->bbl->size += len;
		bbl->bbl->inst_count++;
	}
	return 0;
}
Esempio n. 11
0
File: disas.c Progetto: JaonLin/pemu
int disas_trace_ex(target_ulong pc_start, TRACE trace)
{

//#define PEMU_DEBUG
#ifdef PEMU_DEBUG
	printf("New trace %x\n", pc_start);
#endif 
	target_ulong pc;
	char inst_str[256];
	int newtrace = 0;

	pc = pc_start;
	trace->trace_start = pc_start;
	BBL bbl= get_BBL(pc);
	trace->head = bbl;
	INS ins = NULL;
#ifdef PEMU_DEBUG
	printf("New BBL %x\n", pc_start);
#endif

	while(!newtrace){
		xed_error_enum_t xed_error = disas_one_inst(pc);

		if(xed_error != XED_ERROR_NONE){
			return -1;
		}
		xed_decoded_inst_dump_intel_format(&xedd_g, inst_str, 
			   sizeof(inst_str), 0);	

		xed_iclass_enum_t opcode = xed_decoded_inst_get_iclass(&xedd_g);
		int len = xed_decoded_inst_get_length(&xedd_g);
#ifdef PEMU_DEBUG
		printf("New INS %x %s\n", pc, inst_str);
#endif
		if(!ins){
			ins  = get_INS(pc);
			bbl->head = ins;
		}else{
			ins->next = get_INS(pc);
			ins = ins->next;
		}
		if(pemu_hook_funcs.inst_hook != 0) {
			pemu_inst.PEMU_inst_pc = pc;
			pemu_hook_funcs.inst_hook(ins, 0);
		 }

		bbl->inst_count ++;
		bbl-> size += len;
		switch(opcode){
			//case XED_ICLASS_CALL_FAR:
			case XED_ICLASS_CALL_NEAR:
			case XED_ICLASS_SYSENTER:
			case XED_ICLASS_INT:
			case XED_ICLASS_INT1:
			case XED_ICLASS_INT3:
			case XED_ICLASS_HLT:
			case XED_ICLASS_RET_FAR:
			case XED_ICLASS_RET_NEAR:
			case XED_ICLASS_JMP:
			case XED_ICLASS_JMP_FAR:
				newtrace = 1;
				break;
			//case XED_ICLASS_IRET:
			//case XED_ICLASS_IRETD:
			//case XED_ICLASS_IRETQ:
			case XED_ICLASS_JB:
			case XED_ICLASS_JBE:
			case XED_ICLASS_JL:
			case XED_ICLASS_JLE:
			case XED_ICLASS_JNB:
			case XED_ICLASS_JNBE:
			case XED_ICLASS_JNL: 
			case XED_ICLASS_JNLE:
			case XED_ICLASS_JNO:
			case XED_ICLASS_JNP:
			case XED_ICLASS_JNS:
			case XED_ICLASS_JNZ:
			case XED_ICLASS_JO:
			case XED_ICLASS_JP:
			case XED_ICLASS_JRCXZ:
			case XED_ICLASS_JS:
			case XED_ICLASS_JZ:
				{
				//add new trace target
				const xed_inst_t * xi = xed_decoded_inst_inst(&xedd_g);
				const xed_operand_t *op = xed_inst_operand(xi,0);
				xed_operand_enum_t opname = xed_operand_name(op);
				target_ulong rel;
				target_ulong target;
				rel = xed_decoded_inst_get_branch_displacement(&xedd_g);
				target  = pc + rel + len;
				PEMU_add_trace(target);
#ifdef PEMU_DEBUG
				printf("New target %x %d\n", target, bbl->inst_count);
#endif

				bbl->next = get_BBL(pc+len);
				bbl = bbl->next;
				ins = NULL;

#ifdef PEMU_DEBUG
				printf("New BBL %x\n", pc + len);
#endif
				break;
				}
			default:
				//TODO:
				break;
				//set_code_cache(pc, TAINTED);
				//printf("pc=%lu\tlen=%x\n", pc, len);

		}
		pc = pc + len;
	}
	
	if(pemu_hook_funcs.trace_hook != 0) 
		pemu_hook_funcs.trace_hook(trace, 0);
	
	BBL bblnext = trace->head;
    do{
	    bbl = bblnext;
		bblnext = bbl->next;

		INS ins;
		INS insnext = bbl->head;
		do{
			ins = insnext;
			insnext = ins->next;
			free(ins);
		}while(insnext!=NULL);
		free(bbl);
	}while(bblnext!=NULL);
	free(trace);
}
Esempio n. 12
0
void OfflineX86Code::disasm(FILE* file,
                            TCA   fileStartAddr,
                            TCA   codeStartAddr,
                            uint64_t codeLen,
                            const PerfEventsMap<TCA>& perfEvents,
                            BCMappingInfo bcMappingInfo,
                            bool printAddr /* =true */,
                            bool printBinary /* =false */) {

  char codeStr[MAX_INSTR_ASM_LEN];
  xed_uint8_t* code = (xed_uint8_t*) alloca(codeLen);
  xed_uint8_t* frontier;
  TCA          ip;
  TCA          r10val = 0;
  size_t       currBC = 0;

  if (codeLen == 0) return;

  auto const offset = codeStartAddr - fileStartAddr;
  if (fseek(file, offset, SEEK_SET)) {
    error("disasm error: seeking file");
  }

  size_t readLen = fread(code, codeLen, 1, file);
  if (readLen != 1) {
    error("Failed to read {} bytes at offset {} from code file due to {}",
          codeLen, offset, feof(file) ? "EOF" : "read error");
  }

  xed_decoded_inst_t xedd;

  // Decode and print each instruction
  for (frontier = code, ip = codeStartAddr; frontier < code + codeLen; ) {

    xed_decoded_inst_zero_set_mode(&xedd, &xed_state);
    xed_decoded_inst_set_input_chip(&xedd, XED_CHIP_INVALID);
    xed_error_enum_t xed_error = xed_decode(&xedd, frontier, 15);

    if (xed_error != XED_ERROR_NONE) break;

    // Get disassembled instruction in codeStr
    if (!xed_format_context(xed_syntax, &xedd, codeStr,
                            MAX_INSTR_ASM_LEN, (uint64_t)ip, nullptr
#if XED_ENCODE_ORDER_MAX_ENTRIES != 28 // Newer version of XED library
                            , 0
#endif
                           )) {
      error("disasm error: xed_format_context failed");
    }

    // Annotate the x86 with its bytecode.
    currBC = printBCMapping(bcMappingInfo, currBC, (TCA)ip);

    if (printAddr) printf("%14p: ", ip);

    uint32_t instrLen = xed_decoded_inst_get_length(&xedd);

    if (printBinary) {
      uint32_t i;
      for (i=0; i < instrLen; i++) {
        printf("%02X", frontier[i]);
      }
      for (; i < 16; i++) {
        printf("  ");
      }
    }

    // For calls, we try to figure out the destination symbol name.
    // We look both at relative branches and the pattern:
    //    move r10, IMMEDIATE
    //    call r10
    xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xedd);
    string callDest = "";

    if (iclass == XED_ICLASS_CALL_NEAR || iclass == XED_ICLASS_CALL_FAR) {
      const xed_inst_t    *xi       = xed_decoded_inst_inst(&xedd);
      always_assert(xed_inst_noperands(xi) >= 1);
      const xed_operand_t *opnd     = xed_inst_operand(xi, 0);
      xed_operand_enum_t   opndName = xed_operand_name(opnd);

      if (opndName == XED_OPERAND_RELBR) {
        if (xed_decoded_inst_get_branch_displacement_width(&xedd)) {
          xed_int32_t disp = xed_decoded_inst_get_branch_displacement(&xedd);
          TCA         addr = ip + instrLen + disp;
          callDest = getSymbolName(addr);
        }
      } else if (opndName == XED_OPERAND_REG0) {
        if (xed_decoded_inst_get_reg(&xedd, opndName) == XED_REG_R10) {
          callDest = getSymbolName(r10val);
        }
      }
    } else if (iclass == XED_ICLASS_MOV) {
      // Look for moves into r10 and keep r10val updated
      const xed_inst_t* xi = xed_decoded_inst_inst(&xedd);

      always_assert(xed_inst_noperands(xi) >= 2);

      const xed_operand_t *destOpnd     = xed_inst_operand(xi, 0);
      xed_operand_enum_t   destOpndName = xed_operand_name(destOpnd);

      if (destOpndName == XED_OPERAND_REG0 &&
          xed_decoded_inst_get_reg(&xedd, destOpndName) == XED_REG_R10) {
        const xed_operand_t *srcOpnd     = xed_inst_operand(xi, 1);
        xed_operand_enum_t   srcOpndName = xed_operand_name(srcOpnd);
        if (srcOpndName == XED_OPERAND_IMM0) {
          TCA addr = (TCA)xed_decoded_inst_get_unsigned_immediate(&xedd);
          r10val = addr;
        }
      }
    }

    if (!perfEvents.empty()) {
      printEventStats((TCA)ip, instrLen, perfEvents);
    } else {
      printf("%48s", "");
    }
    printf("%s%s\n", codeStr, callDest.c_str());

    frontier += instrLen;
    ip       += instrLen;
  }
}
Esempio n. 13
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. 14
0
static PyObject *get_iclass(instruction_t *self)
{
    return PyInt_FromLong(xed_decoded_inst_get_iclass(self->decoded_inst));
}
Esempio n. 15
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);
}
Esempio n. 16
0
void
VariableHunter::findStackVariable(xed_decoded_inst_t &xedd)
{

    //unsigned int operandNum = xed_decoded_inst_noperands(&xedd);
    const xed_operand_values_t* operandPtr = xed_decoded_inst_operands_const(&xedd);

    bool trackanswer;
    trackanswer = TrackState -> trackESP(xedd);
    ASSERT(trackanswer);

    // we need to extract the variable from memory. 
    xed_bool_t mark = xed_operand_values_accesses_memory(operandPtr);
    if(!mark){
        return;
    }


    // we ignore the push or pop instruction
    xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xedd);

    if( iclass == XED_ICLASS_PUSH    || iclass  == XED_ICLASS_POP     || 
        iclass == XED_ICLASS_ENTER   || iclass == XED_ICLASS_LEAVE    ||
        iclass == XED_ICLASS_RET_FAR || iclass == XED_ICLASS_RET_NEAR )
    {
        return;
    }


    xed_int32_t          disp = (xed_int32_t)xed_operand_values_get_memory_displacement_int64(operandPtr);
    xed_reg_enum_t   base_reg = xed_operand_values_get_base_reg(operandPtr, 0);
    //xed_reg_enum_t  index_reg = xed_operand_values_get_index_reg(operandPtr, 0);
    //unsigned int       length = xed_operand_values_get_memory_operand_length(operandPtr, 0);
    //unsigned int        scale = xed_operand_values_get_scale(operandPtr);
    //xed_reg_enum_t    seg_reg = xed_operand_values_get_seg_reg(operandPtr, 0); //segment reg
    

    //EBP based memory access 
    if(base_reg == XED_REG_EBP)//&& index_reg == XED_REG_INVALID)
    {
    	if(stack_variable.find(disp) == stack_variable.end())
    	{
    		AbstractVariable *var = new AbstractVariable();

    		var -> region = Stack;
    		var -> offset = disp;

    		stack_variable.insert(std::make_pair<int, AbstractVariable*>(disp, var));

    	}
    }


    //ESP based memory access 
    if(base_reg == XED_REG_ESP)// && index_reg == XED_REG_INVALID)
    {
    	int distance = TrackState -> getESP();
    	disp = disp - distance;
    	// compute the ebp based offset

    	if(stack_variable.find(disp) == stack_variable.end())
    	{
    		AbstractVariable *var = new AbstractVariable();

    		var -> region = Stack;
    		var -> offset = disp;

            // we can assign a size here, if the later calculation change this size, everything is OK
            // if this variable happen to be a boundary variable, the size of this instruction will be the size of the variable
            var -> size = xed_operand_values_get_memory_operand_length(operandPtr, 0); 
            // the unit is byte. 

    		stack_variable.insert(std::make_pair<int, AbstractVariable*>(disp, var));
    	}
    }

    return;
}
Esempio n. 17
0
OPCODE INS_Opcode (INS ins)
{
	//return pemu_xed.PEMU_opcode;
	return xed_decoded_inst_get_iclass(ins);
}
Esempio n. 18
0
BOOL INS_IsSyscall (INS ins)
{
    return xed_decoded_inst_get_iclass(ins) == XED_ICLASS_SYSENTER;
}
Esempio n. 19
0
TCA OfflineX86Code::collectJmpTargets(FILE  *file,
                                      TCA    fileStartAddr,
                                      TCA    codeStartAddr,
                                      uint64_t codeLen,
                                      vector<TCA> *jmpTargets) {

  xed_uint8_t* code = (xed_uint8_t*) alloca(codeLen);
  xed_uint8_t* frontier;
  TCA          ip;

  if (codeLen == 0) return 0;

  if (fseek(file, codeStartAddr - fileStartAddr, SEEK_SET)) {
    error("collectJmpTargets error: seeking file");
  }

  size_t readLen = fread(code, codeLen, 1, file);
  if (readLen != 1) error("collectJmpTargets error: reading file");

  xed_decoded_inst_t xedd;
  xed_iclass_enum_t iclass = XED_ICLASS_NOP;

  // Decode each instruction
  for (frontier = code, ip = codeStartAddr; frontier < code + codeLen; ) {

    xed_decoded_inst_zero_set_mode(&xedd, &xed_state);
    xed_decoded_inst_set_input_chip(&xedd, XED_CHIP_INVALID);
    xed_error_enum_t xed_error = xed_decode(&xedd, frontier, 15);

    if (xed_error != XED_ERROR_NONE) break;

    uint32_t instrLen = xed_decoded_inst_get_length(&xedd);

    iclass = xed_decoded_inst_get_iclass(&xedd);

    if (iclass >= XED_ICLASS_JB && iclass <= XED_ICLASS_JZ) {
      const xed_inst_t    *xi       = xed_decoded_inst_inst(&xedd);
      always_assert(xed_inst_noperands(xi) >= 1);
      const xed_operand_t *opnd     = xed_inst_operand(xi, 0);
      xed_operand_enum_t   opndName = xed_operand_name(opnd);

      if (opndName == XED_OPERAND_RELBR) {
        always_assert(xed_decoded_inst_get_branch_displacement_width(&xedd));
        xed_int32_t disp = xed_decoded_inst_get_branch_displacement(&xedd);
        TCA         addr = ip + instrLen + disp;
        jmpTargets->push_back(addr);
      }
    }

    frontier += instrLen;
    ip       += instrLen;
  }

  // If the code sequence falls thru, then add the next instruction as a
  // possible target
  bool fallsThru = (iclass != XED_ICLASS_JMP      &&
                    iclass != XED_ICLASS_JMP_FAR  &&
                    iclass != XED_ICLASS_RET_NEAR &&
                    iclass != XED_ICLASS_RET_FAR);
  if (fallsThru) {
    jmpTargets->push_back(ip);
    return ip;
  }
  return 0;
}