Example #1
0
/* If has_instr_jmp_targets is true, this routine trashes the note field
 * of each instr_t to store the offset in order to properly encode
 * the relative pc for an instr_t jump target
 */
byte *
instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc,
                         byte *final_pc, byte *max_pc, bool has_instr_jmp_targets)
{
    instr_t *inst;
    int len = 0;
#ifdef ARM
    /* XXX i#1734: reset encode state to avoid any stale encode state
     * or dangling pointer.
     */
    if (instr_get_isa_mode(instrlist_first(ilist)) == DR_ISA_ARM_THUMB)
        encode_reset_it_block(dcontext);
#endif
    /* Do an extra pass over the instrlist so we can determine if an instr opnd
     * was erroneously used with has_instr_jmp_targets = false.
     */
    DOCHECK(2, {
        if (!has_instr_jmp_targets) {
            for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) {
                if (TEST(INSTR_OPERANDS_VALID, (inst)->flags)) {
                    int i;
                    for (i = 0; i < instr_num_srcs(inst); ++i) {
                        CLIENT_ASSERT(!opnd_is_instr(instr_get_src(inst, i)),
                                      "has_instr_jmp_targets was unset "
                                      "but an instr opnd was found");
                    }
                }
            }
        }
    });
Example #2
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr;
    uint num_instrs;
    
#ifdef VERBOSE
    dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag);
# ifdef VERBOSE_VERBOSE
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif

    for (instr  = instrlist_first(bb), num_instrs = 0;
         instr != NULL;
         instr = instr_get_next(instr)) {
        num_instrs++;
    }

    dr_insert_clean_call(drcontext, bb, instrlist_first(bb), 
                         (void *)inscount, false /* save fpstate */, 1,
                         OPND_CREATE_INT32(num_instrs));

#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
    dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag);
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
    return DR_EMIT_DEFAULT;
}
Example #3
0
/* If has_instr_jmp_targets is true, this routine trashes the note field
 * of each instr_t to store the offset in order to properly encode
 * the relative pc for an instr_t jump target
 */
byte *
instrlist_encode_to_copy(dcontext_t *dcontext, instrlist_t *ilist, byte *copy_pc,
                         byte *final_pc, byte *max_pc, bool has_instr_jmp_targets)
{
    instr_t *inst;
    int len = 0;
    if (has_instr_jmp_targets || max_pc != NULL) {
        /* must set note fields first with offset, or compute length */
        for (inst = instrlist_first(ilist); inst; inst = instr_get_next(inst)) {
            if (has_instr_jmp_targets)
                instr_set_note(inst, (void *)(ptr_int_t)len);
            len += instr_length(dcontext, inst);
        }
    }
    if (max_pc != NULL &&
            (copy_pc + len > max_pc || POINTER_OVERFLOW_ON_ADD(copy_pc, len)))
        return NULL;
    for (inst = instrlist_first(ilist); inst != NULL; inst = instr_get_next(inst)) {
        byte *pc = instr_encode_to_copy(dcontext, inst, copy_pc, final_pc);
        if (pc == NULL)
            return NULL;
        final_pc += pc - copy_pc;
        copy_pc = pc;
    }
    return copy_pc;
}
Example #4
0
dr_emit_flags_t
inscount_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
				instr_t *instr, bool for_trace, bool translating,
				void *user_data)
{

	instr_t *first = instrlist_first(bb);
	uint num_instrs = 0;

	if(instr != first)
		return DR_EMIT_DEFAULT;

	if(filter_from_list(head,instr,client_arg->filter_mode)){
		for(instr = first ; instr!=NULL ; instr = instr_get_next(instr)){
			num_instrs++;
		}
		bbcount++;
	}


	if(num_instrs > 0){
		dr_insert_clean_call(drcontext, bb, instrlist_first(bb),
							(void *)inscount, false /* save fpstate */, 1,
							OPND_CREATE_INT32(num_instrs));
	}







	return DR_EMIT_DEFAULT;
}
Example #5
0
instrlist_t*
instrlist_clone(dcontext_t *dcontext, instrlist_t *old)
{
    instr_t *inst, *copy;
    instrlist_t *newlist = instrlist_create(dcontext);

    inst = instrlist_first(old);
    while (inst != NULL) {
        copy = instr_clone(dcontext, inst);
        /* to copy instr targets we temporarily clobber note field */
        instr_set_note(inst, (void *)copy);
        instrlist_append(newlist, copy);
        inst = instr_get_next(inst);
    }

    /* Fix up instr src if it is an instr and restore note field */
    /* Note: we do not allows instruction update code cache,
     * which is very dangerous.
     * So we do not support instr as dst opnd and won't fix up here if any.
     */
    for (inst = instrlist_first(old), copy = instrlist_first(newlist);
            inst != NULL && copy != NULL;
            inst = instr_get_next(inst), copy = instr_get_next(copy)) {
        int i;
        for (i = 0; i < inst->num_srcs; i++) {
            instr_t *tgt;
            opnd_t   op = instr_get_src(copy, i);
            if (!opnd_is_instr(op))
                continue;
            CLIENT_ASSERT(opnd_get_instr(op) != NULL,
                          "instrlist_clone: NULL instr operand");
            tgt = (instr_t *) instr_get_note(opnd_get_instr(op));
            CLIENT_ASSERT(tgt != NULL,
                          "instrlist_clone: operand instr not in instrlist");
            if (opnd_is_far_instr(op)) {
                instr_set_src(copy, i,
                              opnd_create_far_instr
                              (opnd_get_segment_selector(op), tgt));
            } else
                instr_set_src(copy, i,
                              opnd_create_instr(tgt));
        }
    }
    for (inst = instrlist_first(old), copy = instrlist_first(newlist);
            inst != NULL && copy != NULL;
            inst = instr_get_next(inst), copy = instr_get_next(copy)) {
        /* restore note field */
        instr_set_note(inst, instr_get_note(copy));
    }
#ifdef CLIENT_INTERFACE
    newlist->fall_through_bb = old->fall_through_bb;
#endif
    return newlist;
}
Example #6
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr, *mbr = NULL;
    uint num_instrs;
    bool bb_in_app;

#ifdef VERBOSE
    dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag);
# ifdef VERBOSE_VERBOSE
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif

    for (instr  = instrlist_first(bb), num_instrs = 0;
         instr != NULL;
         instr = instr_get_next(instr)) {
        /* only care about app instr */
        if (!instr_ok_to_mangle(instr))
            continue;
        num_instrs++;
        /* Assuming most of the transfers between app and lib are paired, we
         * instrument indirect branches but not returns for better performance.
         */
        if (instr_is_mbr(instr) && !instr_is_return(instr))
            mbr = instr;
    }

    if (dr_fragment_app_pc(tag) >= app_base &&
        dr_fragment_app_pc(tag) <  app_end)
        bb_in_app = true;
    else
        bb_in_app = false;
    dr_insert_clean_call(drcontext, bb, instrlist_first(bb),
                         (void *)(bb_in_app ? app_update : lib_update),
                         false /* save fpstate */, 1,
                         OPND_CREATE_INT32(num_instrs));
    if (mbr != NULL) {
        dr_insert_mbr_instrumentation(drcontext, bb, mbr,
                                      (void *)(bb_in_app ? app_mbr : lib_mbr),
                                      SPILL_SLOT_1);
    }

#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
    dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag);
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
    return DR_EMIT_DEFAULT;
}
Example #7
0
static dr_emit_flags_t
bb_event(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    static int64 bb_count;
    if (++bb_count % 10 == 0) {
        for (instr_t *inst = instrlist_first(bb); inst != NULL;
             inst = instr_get_next(inst)) {
            if (instr_is_exclusive_store(inst))
                return DR_EMIT_DEFAULT;
        }
        dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)cleancallee,
                             false, 1, OPND_CREATE_INTPTR(tag));
    }
    return DR_EMIT_DEFAULT;
}
Example #8
0
static dr_emit_flags_t
bb_event(void* drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    app_pc pc = dr_fragment_app_pc(tag);

    if (pc == start_pc) {
        dr_fprintf(STDERR, "starting syscall monitoring\n");
        monitoring = true;
    }
    else if (pc == stop_pc) {
        dr_fprintf(STDERR, "stopping syscall monitoring\n");
        monitoring = false;
    }
    else {
        instr_t* instr;
        instr_t* next_instr;

        for (instr = instrlist_first(bb);
             instr != NULL;
             instr = next_instr) {

            next_instr = instr_get_next(instr);

            /* Insert a callback to at_syscall before every system call */
            if (instr_is_syscall(instr)) {
                dr_insert_clean_call(drcontext, bb, instr, at_syscall, false, 0);
            }
        }
    }
    return DR_EMIT_DEFAULT;
}
Example #9
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
	int i;
    instr_t *instr, *first = instrlist_first(bb);
    
    for (instr = first; instr != NULL; instr = instr_get_next(instr)) {
		if (instr_reads_memory(instr)) {
			for (i = 0; i < instr_num_srcs(instr); i++) {
				if (opnd_is_memory_reference(instr_get_src(instr, i))) {
					instrument_mem(drcontext, bb, instr, i, false);
				}
			}
		}
		if (instr_writes_memory(instr)) {
			for (i = 0; i < instr_num_dsts(instr); i++) {
				if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
					instrument_mem(drcontext, bb, instr, i, true);
				}
			}
		}
    }
//	dr_printf("count %d\n",count);
    return DR_EMIT_DEFAULT;
}
Example #10
0
File: fubar.c Project: texane/prof
static dr_emit_flags_t event_bb
(
 void* drcontext,
 void* tag,
 instrlist_t* bb,
 bool for_trace,
 bool translating
)
{
  /* refer to dr_ir_instr.h */

  instr_t* insn = instrlist_first(bb);

  for (; insn != NULL; insn = instr_get_next(insn))
  {
    ++insn_count;

    if (instr_reads_memory(insn))
    {
      ++read_count;
      read_size += instr_memory_reference_size(insn);
      dr_printf("read_size:%u\n", instr_memory_reference_size(insn));
    }

    if (instr_writes_memory(insn))
    {
      ++writ_count;
      writ_size += instr_memory_reference_size(insn);
    }
  }

  return DR_EMIT_DEFAULT;
}
Example #11
0
/* replaces all inc with add 1, dec with sub 1
 * if cannot replace (eflags constraints), leaves original instruction alone
 */
static dr_emit_flags_t
event_trace(void *drcontext, void *tag, instrlist_t *trace, bool translating)
{
    instr_t *instr, *next_instr;
    int opcode;

    if (!enable)
	return DR_EMIT_DEFAULT;

#ifdef VERBOSE
    dr_printf("in dynamorio_trace(tag="PFX")\n", tag);
    instrlist_disassemble(drcontext, tag, trace, STDOUT);
#endif

    for (instr = instrlist_first(trace); instr != NULL; instr = next_instr) {
	/* grab next now so we don't go over instructions we insert */
	next_instr = instr_get_next(instr);
	opcode = instr_get_opcode(instr);
	if (opcode == OP_inc || opcode == OP_dec) {
            if (!translating)
                ATOMIC_INC(num_examined);
	    if (replace_inc_with_add(drcontext, instr, trace)) {
                if (!translating)
                    ATOMIC_INC(num_converted);
            }
	}
    }

#ifdef VERBOSE
    dr_printf("after dynamorio_trace(tag="PFX"):\n", tag);
    instrlist_disassemble(drcontext, tag, trace, STDOUT);
#endif

    return DR_EMIT_DEFAULT;
}
Example #12
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    instr_t *instr;
    trace_head_entry_t *e = NULL;
    if (translating)
        return DR_EMIT_DEFAULT;
    for (instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr)) {
        /* blocks containing calls are trace heads */
        if (instr_is_call(instr)) {
            dr_mark_trace_head(drcontext, tag);
            dr_mutex_lock(htable_mutex);
            e = add_trace_head_entry(NULL, tag);
            e->is_trace_head = true;
            dr_mutex_unlock(htable_mutex);
#ifdef VERBOSE
            dr_log(drcontext, LOG_ALL, 3,
                   "inline: marking bb "PFX" as trace head\n", tag);
#endif
            /* doesn't matter what's in rest of bb */
            return DR_EMIT_DEFAULT;
        } else if (instr_is_return(instr)) {
            dr_mutex_lock(htable_mutex);
            e = add_trace_head_entry(NULL, tag);
            e->has_ret = true;
            dr_mutex_unlock(htable_mutex);
        }
    }
    return DR_EMIT_DEFAULT;
}
Example #13
0
static
dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t* bb,
                         bool for_trace, bool translating)
{
    instr_t *instr;
    instr_t *next_instr;
    reg_t in_eax = -1;

    for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);
        if (instr_get_opcode(instr) == OP_mov_imm &&
            opnd_get_reg(instr_get_dst(instr, 0)) == REG_EAX)
            in_eax = opnd_get_immed_int(instr_get_src(instr, 0));
        if (instr_is_syscall(instr) &&
            in_eax == SYS_getpid) {
            instr_t *myval = INSTR_CREATE_mov_imm
                (drcontext, opnd_create_reg(REG_EAX), OPND_CREATE_INT32(-7));
            instr_set_translation(myval, instr_get_app_pc(instr));
            instrlist_preinsert(bb, instr, myval);
            instrlist_remove(bb, instr);
            instr_destroy(drcontext, instr);
        }
    }
    return DR_EMIT_DEFAULT;
}
Example #14
0
/* iterate basic block to find a dead register */
static reg_id_t
bb_find_dead_reg(instrlist_t *ilist)
{
    instr_t *instr;
    int i;
    bool reg_is_read[DR_NUM_GPR_REGS] = { false,};

    for (instr  = instrlist_first(ilist);
         instr != NULL;
         instr  = instr_get_next(instr)) {
        if (instr_is_syscall(instr) || instr_is_interrupt(instr))
            return DR_REG_NULL;
        for (i = 0; i < DR_NUM_GPR_REGS; i++) {
            if (!reg_is_read[i] &&
                instr_reads_from_reg(instr, (reg_id_t)(DR_REG_START_GPR + i))) {
                reg_is_read[i] = true;
            }
            if (!reg_is_read[i] &&
                instr_writes_to_exact_reg(instr,
                                          (reg_id_t)(DR_REG_START_GPR + i))) {
                return (reg_id_t)(DR_REG_START_GPR + i);
            }
#ifdef X64
            /* in x64, update on 32-bit register kills the whole register */
            if (!reg_is_read[i] &&
                instr_writes_to_exact_reg(instr,
                                          reg_64_to_32
                                          ((reg_id_t)(DR_REG_START_GPR + i)))) {
                return (reg_id_t)(DR_REG_START_GPR + i);
            }
#endif
        }
    }
    return DR_REG_NULL;
}
Example #15
0
/** Selects registers that should be used for instrumenting given fragment.
 *  Returns a place where instrumentation should be inserted. */
instr_t* configure_instr(struct instr_info_t* instr_info, instrlist_t* frag) {
  // TODO: find dead registers
  instr_info->tls_reg = DR_REG_XAX;
  instr_info->restore_tls_reg = true;
  instr_info->current_reg = DR_REG_XDX;
  instr_info->restore_current_reg = true;
  return instrlist_first(frag);
}
static
dr_emit_flags_t bb_event(void* drcontext, void* tag, instrlist_t* bb, bool for_trace, bool translating)
{
    dr_fprintf(STDERR, "got BB event\n");
    dr_insert_clean_call(drcontext, bb, instrlist_first(bb),
                         (void *)unregister, false, 0);
    return DR_EMIT_DEFAULT;
}
Example #17
0
static dr_emit_flags_t
event_bb_analysis(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating, OUT void **user_data)
{
    /* point at first instr */
    *user_data = (void *) instrlist_first(bb);
    return DR_EMIT_DEFAULT;
}
Example #18
0
/* frees the Instrs in the instrlist_t */
void
instrlist_clear(dcontext_t *dcontext, instrlist_t *ilist)
{
    instr_t *instr;
    while (NULL != (instr = instrlist_first(ilist))) {
        instrlist_remove(ilist, instr);
        instr_destroy(dcontext, instr);
    }
}
Example #19
0
static dr_emit_flags_t
bb_event(void* drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    instr_t *instr, *next_instr;
    int opcode;
    for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);
        opcode = instr_get_opcode(instr);
	if(instr_is_floating(instr)){
   	//	dr_fprintf(logF, "Has seen FPU instruction with opcode %d\n",opcode);
	
	}
	else if(is_SIMD_packed(opcode)){
   	//	dr_fprintf(logF, "Has seen SIMD packed instruction with opcode %d\n",opcode);
	}
//AVX?rcpps?

	else if(is_SIMD_arithm(opcode)){
		int is_single = 0;
//		printf("opcode is   %d\n", opcode);
//    		printf("number of sources  %d\n", instr_num_srcs(instr));  
 //   		printf("number of dests  %d\n", instr_num_dsts(instr));
		//assert(number of sources = 2);
		opnd_t source1 = instr_get_src(instr,0);
		opnd_t source2 = instr_get_src(instr,1);
		opnd_t dest = instr_get_dst(instr,0);
		if(opnd_is_memory_reference(source1)){
	//		dr_print_instr(drcontext, logF, instr, "INSTR: ");
//			dr_print_opnd(drcontext, logF, source1, "OPND1: ");
//			dr_print_opnd(drcontext, logF, source2, "OPND2: ");
			reg_id_t rd = opnd_get_reg(source2);
			reg_id_t rs = opnd_get_reg_used(source1, 0);
			dr_insert_clean_call(drcontext, bb, instr, 
				(void*) callback, true, 5, 
				OPND_CREATE_INTPTR(rs), OPND_CREATE_INTPTR(opnd_get_disp(source1)),
				OPND_CREATE_INTPTR(rd), OPND_CREATE_INTPTR(opcode), OPND_CREATE_INTPTR(instr_get_app_pc(instr)));

		}
		else if(opnd_is_reg(source1) && opnd_is_reg(source2)){
			reg_id_t reg1 = opnd_get_reg(source1);
			reg_id_t reg2 = opnd_get_reg(source2);
			dr_insert_clean_call(drcontext,bb,instr, (void*)getRegReg, 
				true, 4, 
				OPND_CREATE_INTPTR(reg1), OPND_CREATE_INTPTR(reg2)
				,OPND_CREATE_INTPTR(opcode), OPND_CREATE_INTPTR(instr_get_app_pc(instr))
			); 
		}
		else{
		//should not be the case, throw an exception
		}
	        fp_count++; 
      }
    }

    return DR_EMIT_DEFAULT;
}
Example #20
0
void instrlist_append_instrlist(dcontext_t *dcontext,instrlist_t *ilist,
                                instrlist_t *appendee)
{
    instr_t *first=instrlist_first(appendee);
    if (!first)
        return;
    instrlist_append(ilist,first);
    instrlist_init(appendee);
    instrlist_destroy(dcontext,appendee);
}
Example #21
0
dr_emit_flags_t
funcwrap_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
instr_t *instr, bool for_trace, bool translating,
void *user_data)
{

	instr_t * first = instrlist_first(bb);
	app_pc pc = instr_get_app_pc(first);
	module_data_t * module_data;
	per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index);
	module_t * md;
	app_pc offset;
	
	
	if (instr != first || data->nesting != 0){
		return DR_EMIT_DEFAULT;
	}

	module_data = dr_lookup_module(pc);
	data = drmgr_get_tls_field(drcontext, tls_index);

	
	if (module_data != NULL){
		md = md_lookup_module(head, module_data->full_path);
		if (md != NULL){
			offset = pc - module_data->start;
			
			for (int i = 1; i <= md->bbs[0].start_addr; i++){
				if (offset == md->bbs[i].start_addr){
					DEBUG_PRINT("bb instrumenting function\n");
					data->filter_func = true;
					dr_insert_clean_call(drcontext, bb, instr, clean_call, false, 1, OPND_CREATE_INTPTR(instr_get_app_pc(instr)));
					wrap_thread_id = dr_get_thread_id(drcontext);
					DEBUG_PRINT("done bb instrumenting function\n");

				}
			}
		}
	}

	

	/*if (data->filter_func){
		instrlist_disassemble(drcontext, instr_get_app_pc(instrlist_first(bb)), bb, logfile);
	}*/

	dr_free_module_data(module_data);


	return DR_EMIT_DEFAULT;

}
Example #22
0
static dr_emit_flags_t
event_bb(void *dc, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
    instr_t *where = instrlist_first(bb);
    instr_t *ret_label = INSTR_CREATE_label(dc);
    dr_save_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1);
    PRE(bb, where, INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                                        opnd_create_instr(ret_label)));
    PRE(bb, where, INSTR_CREATE_jmp(dc, opnd_create_pc(slowpath)));
    PRE(bb, where, ret_label);
    dr_restore_reg(dc, bb, where, DR_REG_XAX, SPILL_SLOT_1);
    return DR_EMIT_DEFAULT;
}
Example #23
0
/* event_bb_insert calls instrument_mem to instrument every
 * application memory reference.
 */
dr_emit_flags_t
memtrace_bb_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
                instr_t *instr, bool for_trace, bool translating,
                void *user_data)
{
    int i;
	reg_id_t reg;
	file_t out_file;
	instr_t * first = NULL;
	instr_t * current;
 
	//DR_ASSERT(instr_ok_to_mangle(instr));

	if (instr_ok_to_mangle(instr)){
		/* FIXME - need to generalize the filtering library */



		for (current = instrlist_first(bb); current != NULL; current = instr_get_next(current)){
			if (instr_ok_to_mangle(current)){
				first = current;
				break;
			}
		}


		if ((first != NULL) && filter_from_list(head, first, client_arg->filter_mode)){


			if (instr_reads_memory(instr)) {
				for (i = 0; i < instr_num_srcs(instr); i++) {
					if (opnd_is_memory_reference(instr_get_src(instr, i))) {
						instrument_mem(drcontext, bb, instr, i, false);
					}
				}
			}
			if (instr_writes_memory(instr)) {
				for (i = 0; i < instr_num_dsts(instr); i++) {
					if (opnd_is_memory_reference(instr_get_dst(instr, i))) {
						instrument_mem(drcontext, bb, instr, i, true);
					}
				}
			}

		}
	}

    return DR_EMIT_DEFAULT;
}
Example #24
0
static
dr_emit_flags_t bb_event(void *drcontext, app_pc tag, instrlist_t *bb, bool for_trace, bool translating)
{
    instr_t *instr, *next_instr;
    app_pc bb_addr, instr_addr;
    bool found_section;

    bb_addr = dr_fragment_app_pc(tag);

    /* vsyscall: some versions of windows jump to 0x7ffe0300 to
     * execute a syscall; this address is not contained in any module.
     */
    if ((ptr_uint_t)bb_addr == 0x7ffe0300 ||
        (ptr_uint_t)bb_addr == 0x7ffe0302)
        return DR_EMIT_DEFAULT;

    if (!is_in_known_module(bb_addr, &found_section, &section)) {
        dr_fprintf(STDERR, "ERROR: BB addr "PFX" in unknown module\n", bb_addr);
    }
    if (!found_section) {
        dr_fprintf(STDERR, "ERROR: BB addr "PFX" isn't within a module section\n", bb_addr);
    }
    if ((section.Characteristics & IMAGE_SCN_CNT_CODE) == 0) {
        dr_fprintf(STDERR, "ERROR: BB addr "PFX" isn't within a code section\n", bb_addr);
    }

    for (instr = instrlist_first(bb);
         instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);

        instr_addr = instr_get_app_pc(instr);
        if (!is_in_known_module(instr_addr, &found_section, &section)) {
            dr_fprintf(STDERR, "ERROR: instr addr "PFX" in unknown module\n", instr_addr);
        }
        if (!found_section) {
            dr_fprintf(STDERR, "ERROR: instr addr "PFX" isn't within a module section\n", instr_addr);
        }
        if ((section.Characteristics & IMAGE_SCN_CNT_CODE) == 0) {
            dr_fprintf(STDERR, "ERROR: instr addr "PFX" isn't within a code section\n", instr_addr);
        }
        if (instr_addr == exit_proc_addr) {
            dr_fprintf(STDERR, "Hit kernel32!ExitProcess\n");
            exit_proc_addr = NULL;
        }
    }
    return DR_EMIT_DEFAULT;
}
Example #25
0
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr, *first = instrlist_first(bb), *point = NULL;
    uint num_instrs;
	uint flags;
	uint need_restore;

	/* count instruction */
    for (instr  = first, num_instrs = 0;
         instr != NULL;
         instr = instr_get_next(instr)) {

        num_instrs++;

    }
	
	need_restore = 0;
	flags = instr_get_arith_flags(instr);
	/* eflags are not dead save eflags to register */
	if (!(TESTALL(EFLAGS_WRITE_6, flags) && !TESTANY(EFLAGS_READ_6, flags))) {
		need_restore = 1;
		dr_save_reg(drcontext, bb, first, DR_REG_XAX, SPILL_SLOT_1);
		dr_save_arith_flags_to_xax(drcontext, bb, first);
	}

	/* add the instruction count */
    instrlist_meta_preinsert
        (bb, first,
         INSTR_CREATE_add(drcontext, OPND_CREATE_ABSMEM
                               ((byte *)&global_count, OPSZ_4), OPND_CREATE_INT32(num_instrs)));

	/* Need to carry since it is a 8 byte variable. */
    instrlist_meta_preinsert
        (bb, first,
         INSTR_CREATE_adc(drcontext, OPND_CREATE_ABSMEM
                               ((byte *)&global_count + 4, OPSZ_4), OPND_CREATE_INT32(0)));

	/* resotre eflags */
	if (need_restore) {
		dr_restore_arith_flags_from_xax(drcontext, bb, first);
		dr_restore_reg(drcontext, bb, first, DR_REG_XAX, SPILL_SLOT_1);
	}

    return DR_EMIT_DEFAULT;
}
Example #26
0
static dr_emit_flags_t
event_bb(void *drcontext, void *tag, instrlist_t *bb, bool for_trace,
         bool translating)
{
    app_pc pc = instr_get_app_pc(instrlist_first(bb));
    if (pc == (app_pc)&func_0) took_over_thread[0] = true;
    if (pc == (app_pc)&func_1) took_over_thread[1] = true;
    if (pc == (app_pc)&func_2) took_over_thread[2] = true;
    if (pc == (app_pc)&func_3) took_over_thread[3] = true;
    if (pc == (app_pc)&func_4) took_over_thread[4] = true;
    if (pc == (app_pc)&func_5) took_over_thread[5] = true;
    if (pc == (app_pc)&func_6) took_over_thread[6] = true;
    if (pc == (app_pc)&func_7) took_over_thread[7] = true;
    if (pc == (app_pc)&func_8) took_over_thread[8] = true;
    if (pc == (app_pc)&func_9) took_over_thread[9] = true;
    return DR_EMIT_DEFAULT;
}
Example #27
0
static
dr_emit_flags_t bb_event(void* drcontext, void *tag, instrlist_t *bb,
                         bool for_trace, bool translating)
{
    instr_t *instr;
    if (!translating)
        increment(tag);

    /* I'm looking for a specific BB in the test .exe.  I've marked
     * it with a couple nops.
     */
#ifdef WINDOWS
    if ((app_pc)tag >= start && (app_pc)tag < end) {
#endif
        instr = instrlist_first(bb);

        if (instr_is_nop(instr)) {
            instr_t *next = instr_get_next(instr);

            /* The test app uses two nops as a marker to identify a specific bb.  Since
             * 2 nop instructions in a row aren't that uncommon on Linux (where we can't
             * restrict our search to just the test.exe module) we use an unusual nop
             * for the second one: xchg xbp, xbp */
            if (next != NULL && instr_is_nop(next) &&
                instr_get_opcode(next) == OP_xchg &&
                instr_writes_to_exact_reg(next, REG_XBP, DR_QUERY_DEFAULT)) {

                bb_build_count++;

                if (delay_flush_at_next_build) {
                    delay_flush_at_next_build = false;
                    dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event);
                }

                dr_insert_clean_call(drcontext, bb, instr, (void *)callback,
                                     false, 2, OPND_CREATE_INTPTR(tag),
                                     OPND_CREATE_INTPTR(instr_get_app_pc(instr)));
            }
        }
#ifdef WINDOWS
    }
#endif
    return DR_EMIT_DEFAULT;
}
Example #28
0
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating)
{
  uint num_instructions = 0;
  instr_t *instr;

  /* Count the number of instructions in this block */
  for(instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr))
  {
    num_instructions++;
  }

  /* Update the as-built counts */
  dr_mutex_lock(as_built_lock);
  counts_as_built.blocks++;
  counts_as_built.total_size += num_instructions;
  dr_mutex_unlock(as_built_lock);

  return DR_EMIT_DEFAULT;
}
Example #29
0
static
dr_emit_flags_t bb_event(void* drcontext, app_pc tag, instrlist_t* bb, bool for_trace, bool translating)
{
    if (tag >= start && tag < end) {
        instr_t* instr = instrlist_first(bb);

        dr_prepare_for_call(drcontext, bb, instr);
    
        MINSERT(bb, instr, INSTR_CREATE_push_imm
                (drcontext, OPND_CREATE_INT32((ptr_uint_t)tag)));
        MINSERT(bb, instr, INSTR_CREATE_push_imm
                (drcontext, OPND_CREATE_INT32((ptr_uint_t)drcontext)));
        MINSERT(bb, instr, INSTR_CREATE_call
                (drcontext, opnd_create_pc((void*)delete_fragment)));
        
        dr_cleanup_after_call(drcontext, bb, instr, 8);
    }
    return DR_EMIT_DEFAULT;
}
Example #30
0
void
cfi_cleanup_after_native_call(void *drcontext, instrlist_t *ilist, instr_t *where)
{
	instr_t *in = (where == NULL) ? instrlist_last(ilist) : instr_get_prev(where);

	CFI_ASSERT(drcontext != NULL, "dr_cleanup_after_call: drcontext cannot be NULL");
/*
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDI)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RSI)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBP)));*/
    /* skip xsp by popping into dead rbx */
  /*  PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RBX)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RDX)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RCX)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_RAX)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R8)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R9)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R10)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R11)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R12)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R13)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R14)));
    PRE(ilist, where, INSTR_CREATE_pop(drcontext, opnd_create_reg(REG_R15)));

    PRE(ilist, where, INSTR_CREATE_lea
        (drcontext, opnd_create_reg(REG_XSP),
         OPND_CREATE_MEM_lea(REG_XSP, REG_NULL, 0, XMM_SLOTS_SIZE)));

*/
    PRE(ilist, where, INSTR_CREATE_popf(drcontext));

    /* now go through and mark inserted instrs as meta */
    if (in == NULL)
        in = instrlist_first(ilist);
    else
        in = instr_get_next(in);

    while (in != where) {
        instr_set_ok_to_mangle(in, false);
        in = instr_get_next(in);
    }
}