Exemple #1
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;
}
Exemple #2
0
static void format_jmp(const xed_inst_t *xi)
{
	uint32_t dest;
	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;

#ifdef STATISTICS
	g_symbol_nums++;
	fprintf(stderr, "jmp at pc\t%x\n", g_pc);
	g_jmp_num++;
#endif

	INST* inst = get_inst(g_pc);

	if(inst->type == TAIL){//jmp to plt
#ifdef DEBUG
		fprintf(stdout, "TAIL:\t%p\n", inst);
#endif
		sprintf(inst_buffer, "%s %s", "jmp", inst->api_call.fname);
		return;
	}
	if(operand_is_relbr(op_name, &dest)){
		dest += g_pc + xed_decoded_inst_get_length(&xedd_g);
		sprintf(inst_buffer, "%s L_0x%x", "jmp", dest);
	}else{
		fprintf(stderr, "error in format_jmp\n");
	}
}
Exemple #3
0
static void format_direct_call(const xed_inst_t *xi)
{
	uint32_t dest;
	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;

#ifdef STATISTICS
	fprintf(stderr, "call at pc\t%x\n", g_pc);
	g_symbol_nums++;
	g_call_num++;
#endif

	INST* inst = get_inst(g_pc);
	if(operand_is_relbr(op_name, &dest)){
		if(inst->api_call.fname){
			if(inst->api_call.type == API_IMP)
				sprintf(inst_buffer, "call %s", inst->api_call.fname);
			else 
				sprintf(inst_buffer, "call dword ptr %s", inst->api_call.fname);
			return;
		}
		dest += g_pc + xed_decoded_inst_get_length(&xedd_g);
		sprintf(inst_buffer, "call func_0x%x", dest);
	}else{
		fprintf(stderr, "error in format_jmp\n");
	}
}
Exemple #4
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");
	}
}
Exemple #5
0
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;
}
Exemple #6
0
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, &reg_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);
}
Exemple #7
0
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, &reg_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);
}