예제 #1
0
static print_base_disp_for_lea(file_t file, opnd_t opnd){

	/* [base + index * scale + disp] */
	dr_fprintf(file, " base - %d %s\n", opnd_get_base(opnd), get_register_name(opnd_get_base(opnd)));
	dr_fprintf(file, " index - %d %s\n", opnd_get_index(opnd), get_register_name(opnd_get_index(opnd)));
	dr_fprintf(file, "reg - %d\n", opnd_is_reg(opnd_create_reg(opnd_get_index(opnd))));
	dr_fprintf(file, " scale - %d\n", opnd_get_scale(opnd));
	dr_fprintf(file, " disp - %d\n", opnd_get_disp(opnd));

}
예제 #2
0
/* prints the trace and empties the instruction buffer */
static void ins_trace(void *drcontext)
{
    per_thread_t *data;
    int num_refs;
	instr_trace_t *instr_trace;
	instr_t * instr;
	int i;
	int j;
#ifdef READABLE_TRACE
	char disassembly[SHORT_STRING_LENGTH];
#else
	output_t * output;
#endif

    data      = drmgr_get_tls_field(drcontext, tls_index);
    instr_trace   = (instr_trace_t *)data->buf_base;
    num_refs  = (int)((instr_trace_t *)data->buf_ptr - instr_trace);

	uint mem_type;
	uint64 mem_addr;

	opnd_t opnd;

	
#ifdef READABLE_TRACE
	//TODO
    for (i = 0; i < num_refs; i++) {

		instr = instr_trace->static_info_instr;
		instr_disassemble_to_buffer(drcontext,instr,disassembly,SHORT_STRING_LENGTH);

		dr_fprintf(data->outfile,"%u",instr_get_opcode(instr));

		dr_fprintf(data->outfile,",%u",calculate_operands(instr,DST_TYPE));
		for(j=0; j<instr_num_dsts(instr); j++){
			get_address(instr_trace, j, DST_TYPE, &mem_type, &mem_addr);
			output_populator_printer(drcontext,instr_get_dst(instr,j),instr,mem_addr,mem_type,NULL);
		}

		dr_fprintf(data->outfile,",%u",calculate_operands(instr,SRC_TYPE));
		for(j=0; j<instr_num_srcs(instr); j++){
			get_address(instr_trace, j, SRC_TYPE, &mem_type, &mem_addr);
			opnd = instr_get_src(instr, j);
			if (instr_get_opcode(instr) == OP_lea && opnd_is_base_disp(opnd)){
				/* four operands here for [base + index * scale + disp] */
				output_populator_printer(drcontext, opnd_create_reg(opnd_get_base(opnd)), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_reg(opnd_get_index(opnd)), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_immed_int(opnd_get_scale(opnd),OPSZ_PTR), instr, mem_addr, mem_type, NULL);
				output_populator_printer(drcontext, opnd_create_immed_int(opnd_get_disp(opnd), OPSZ_PTR), instr, mem_addr, mem_type, NULL);
			}
			else{
				output_populator_printer(drcontext, opnd, instr, mem_addr, mem_type, NULL);
			}
		}
		dr_fprintf(data->outfile,",%u,%u\n",instr_trace->eflags,instr_trace->pc);
        ++instr_trace;
    }
#else

	/* we need to fill up the output array here */

	for(i = 0; i< num_refs; i++){
		instr = instr_trace->static_info_instr;
		output = &data->output_array[i];
		
		//opcode 
		output->opcode = instr_get_opcode(instr);
		output->num_dsts = 0;
		output->num_srcs = 0;

		for(j=0; j<instr_num_dsts(instr); j++){

			output_populator_printer(drcontext,instr_get_dst(instr,j),instr,get_address(instr_trace,j,DST_TYPE),&output->dsts[output->num_dsts]);
			output->num_dsts++;
		}

		for(j=0; j<instr_num_srcs(instr); j++){
			output_populator_printer(drcontext,instr_get_src(instr,j),instr,get_address(instr_trace,j,SRC_TYPE),&output->srcs[output->num_srcs]);
			output->num_srcs++;
		}
		
		output->eflags = instr_trace->eflags;

		++instr_trace;

	}

	dr_write_file(data->outfile,data->output_array,num_refs * sizeof(output_t));
#endif

	
    memset(data->buf_base, 0, INSTR_BUF_SIZE);
    data->num_refs += num_refs;
    data->buf_ptr   = data->buf_base;
	
}
예제 #3
0
void
watchpoint_indirect_call_event(dcontext_t *drcontext, instrlist_t *ilist, instr_t *instr,
                     instr_t *next_instr, bool mangle_calls, uint flags)
{
    opnd_t instr_opnd;
    reg_id_t base_reg;
    unsigned long used_registers = 0;
    app_pc pc;
    struct memory_operand_modifier ops = {0};

    instr_t *begin_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *done_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *nop = INSTR_CREATE_nop(drcontext);
    instr_t *emulated;


    memset(&ops, 0, sizeof(struct memory_operand_modifier));

    if(instr_reads_memory(instr)) {
        instr_opnd = instr_get_src(instr, 0);
        if (opnd_is_rel_addr(instr_opnd) || opnd_is_abs_addr(instr_opnd)) {

        }else if (opnd_is_base_disp(instr_opnd)) {

            for_each_src_operand(instr, &ops, (opnd_callback_t *) memory_src_operand_finder);
           // base_reg = opnd_get_reg(instr_opnd);

            switch(ops.found_operand.value.base_disp.base_reg) {
                case DR_REG_RSP: case DR_REG_ESP: case DR_REG_SP:
                case DR_REG_RBP: case DR_REG_EBP: case DR_REG_BP:
                    return;
                default:
                  break;
            }

            collect_regs(&used_registers, instr, instr_num_srcs, instr_get_src );
            collect_regs(&used_registers, instr, instr_num_dsts, instr_get_dst );

            reg_id_t reg_watched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_watched_addr = opnd_create_reg(reg_watched_addr);

            reg_id_t reg_unwatched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_unwatched_addr = opnd_create_reg(reg_unwatched_addr);

            PRE(ilist, instr, begin_instrumenting);
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_watched_addr));
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pushf(drcontext));
            PRE(ilist, instr, INSTR_CREATE_lea(drcontext, opnd_watched_addr, opnd_create_base_disp(opnd_get_base(ops.found_operand),
                                                        opnd_get_index(ops.found_operand), opnd_get_scale(ops.found_operand),
                                                        opnd_get_disp(ops.found_operand), OPSZ_lea)));

            PRE(ilist, instr, INSTR_CREATE_mov_imm(drcontext, opnd_unwatched_addr,
                                            OPND_CREATE_INT64(WATCHPOINT_INDEX_MASK)));
            PRE(ilist, instr, INSTR_CREATE_or(drcontext, opnd_unwatched_addr, opnd_watched_addr));

            emulated = instr_clone(drcontext, instr);
            emulated->translation = 0;

            ops.replacement_operand = opnd_create_base_disp(
                    reg_unwatched_addr, DR_REG_NULL,1, 0 , ops.found_operand.size);

            for_each_operand(emulated, &ops, (opnd_callback_t *) memory_operand_replacer);

            PRE(ilist, instr, INSTR_CREATE_popf(drcontext));
            PRE(ilist, instr, emulated);
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_watched_addr));

            PRE(ilist, instr, INSTR_CREATE_jmp_short(drcontext,
                    opnd_create_instr(done_instrumenting)));

            pc = instr->translation;
            instr->translation = 0; // hack!
            instr_being_modified(instr, false);
            instr_set_ok_to_mangle(instr, false);

            if(NULL != pc){
                nop->translation = pc + instr->length;
            }
            POST(ilist, instr, nop);
            POST(ilist, instr, done_instrumenting);

        }
    }
}
예제 #4
0
void
modify_instr_for_relocations(void *drcontext, instr_t *inst,
                             ptr_uint_t *immed, ptr_uint_t *disp)
{
    int i;
    ptr_uint_t limmed = 0, ldisp = 0;
    for (i = instr_num_srcs(inst) - 1; i >= 0; i--) {
        opnd_t opnd = instr_get_src(inst, i);
        if (opnd_is_immed_int(opnd) && opnd_get_immed_int(opnd) > 0x10000) {
            if (limmed != 0) {
                ASSERT(false);
            } else {
                limmed = opnd_get_immed_int(opnd);
            }
            instr_set_src(inst, i, opnd_create_immed_int(0, opnd_get_size(opnd)));
        }
        if (opnd_is_base_disp(opnd) && opnd_get_disp(opnd) > 0x10000) {
            if (ldisp != 0 && ldisp != opnd_get_disp(opnd)) {
                ASSERT(false);
            } else {
                ldisp = opnd_get_disp(opnd);
            }
            instr_set_src(inst, i, opnd_create_base_disp(opnd_get_base(opnd), opnd_get_index(opnd), opnd_get_scale(opnd), 0, opnd_get_size(opnd)));
        }
    }
    for (i = instr_num_dsts(inst) - 1; i >= 0; i--) {
        opnd_t opnd = instr_get_dst(inst, i);
        ASSERT(!opnd_is_immed(opnd));
        if (opnd_is_base_disp(opnd) && opnd_get_disp(opnd) > 0x10000) {
            if (ldisp != 0 && ldisp != opnd_get_disp(opnd)) {
                ASSERT(false);
            } else {
                ldisp = opnd_get_disp(opnd);
            }
            instr_set_dst(inst, i, opnd_create_base_disp(opnd_get_base(opnd), opnd_get_index(opnd), opnd_get_scale(opnd), 0, opnd_get_size(opnd)));
        }
    }
    if (limmed != 0)
        *immed = limmed;
    if (ldisp != 0)
        *disp = ldisp; 
}