示例#1
0
/* inserts "inst" after "where" ("inst" can be a chain of insts) */
void
instrlist_postinsert(instrlist_t *ilist, instr_t *where, instr_t *inst)
{
    instr_t *wherenext;
    instr_t *top = inst;
    instr_t *bot;

    if (where == NULL) {
        /* if where is NULL there is no inst to send for an "after" */
        instrlist_prepend(ilist, inst);
        return;
    }

    CLIENT_ASSERT(where != NULL, "instrlist_postinsert: where cannot be NULL");
    CLIENT_ASSERT(instr_get_prev(inst) == NULL,
                  "instrlist_postinsert: cannot add middle of list");

    wherenext = instr_get_next(where);
    check_translation(ilist, inst);
    while (instr_get_next(inst)) {
        inst = instr_get_next(inst);
        check_translation(ilist, inst);
    }
    bot = inst;
    instr_set_next(where, top);
    instr_set_prev(top, where);
    if (wherenext) {
        instr_set_next(bot, wherenext);
        instr_set_prev(wherenext, bot);
    } else {
        ilist->last = bot;
    }
}
示例#2
0
/* inserts "inst" before "where" ("inst" can be a chain of insts) */
void
instrlist_preinsert(instrlist_t *ilist, instr_t *where, instr_t *inst)
{
    instr_t *whereprev;
    instr_t *top = inst;
    instr_t *bot;

    if (where == NULL) {
        /* if where is NULL there is no inst to send for a "before" */
        instrlist_append(ilist, inst);
        return;
    }

    CLIENT_ASSERT(where != NULL, "instrlist_preinsert: where cannot be NULL");
    CLIENT_ASSERT(instr_get_prev(inst) == NULL,
                  "instrlist_preinsert: cannot add middle of list");
    whereprev = instr_get_prev(where);
    check_translation(ilist, inst);
    while (instr_get_next(inst)) {
        inst = instr_get_next(inst);
        check_translation(ilist, inst);
    }
    bot = inst;
    if (whereprev) {
        instr_set_next(whereprev, top);
        instr_set_prev(top, whereprev);
    } else {
        ilist->first = top;
    }
    instr_set_next(bot, where);
    instr_set_prev(where, bot);
}
示例#3
0
文件: drx.c 项目: boolking/dynamorio
DR_EXPORT
bool
drx_aflags_are_dead(instr_t *where)
{
    instr_t *instr;
    uint flags;
    for (instr = where; instr != NULL; instr = instr_get_next(instr)) {
        /* we treat syscall/interrupt as aflags read */
        if (instr_is_syscall(instr) || instr_is_interrupt(instr))
            return false;
        flags = instr_get_arith_flags(instr, DR_QUERY_DEFAULT);
        if (TESTANY(EFLAGS_READ_ARITH, flags))
            return false;
        if (TESTALL(EFLAGS_WRITE_ARITH, flags))
            return true;
        if (instr_is_cti(instr)) {
            if (instr_is_app(instr) &&
                (instr_is_ubr(instr) || instr_is_call_direct(instr))) {
                instr_t *next = instr_get_next(instr);
                opnd_t   tgt  = instr_get_target(instr);
                /* continue on elision */
                if (next != NULL && instr_is_app(next) &&
                    opnd_is_pc(tgt) &&
                    opnd_get_pc(tgt) == instr_get_app_pc(next))
                    continue;
            }
            /* unknown target, assume aflags is live */
            return false;
        }
    }
    return false;
}
示例#4
0
文件: instrlist.c 项目: tidatida/drk
/* 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;
}
示例#5
0
文件: instrlist.c 项目: tidatida/drk
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;
}
示例#6
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;
}
示例#7
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;
}
示例#8
0
文件: rbuf.c 项目: jikk/dbi_study
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;
}
示例#9
0
/* removes "inst" from the instrlist_t it currently belongs to */
void
instrlist_remove(instrlist_t *ilist, instr_t *inst)
{
    if (instr_get_prev(inst))
        instr_set_next(instr_get_prev(inst), instr_get_next(inst));
    else
        ilist->first = instr_get_next(inst);

    if (instr_get_next(inst))
        instr_set_prev(instr_get_next(inst), instr_get_prev(inst));
    else
        ilist->last = instr_get_prev(inst);

    instr_set_prev(inst, NULL);
    instr_set_next(inst, NULL);
}
示例#10
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;
}
示例#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;
}
示例#12
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");
                    }
                }
            }
        }
    });
示例#13
0
文件: fubar.c 项目: 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;
}
示例#14
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;
}
示例#15
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;
}
示例#16
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;
}
示例#17
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;
}
示例#18
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);
    }
}
示例#19
0
/** Returns offset, in bytes, between starts of the first and the second
 *  instruction. Returns -1 if the second instruction does not follow the first
 *  instruction. */
int get_offset(void* ctx, instr_t* first, instr_t* second) {
  int offset = 0;
  while(first != second) {
    if(first == NULL) {
      return -1;
    }
    offset += instr_length(ctx, first);
    first = instr_get_next(first);
  }
  return offset;
}
示例#20
0
文件: utils.c 项目: zhaoqin/Umbra
instr_t *
instr_get_next_app_instr(instr_t *instr)
{
    while (instr != NULL) {
        instr = instr_get_next(instr);
        if (instr_get_app_pc(instr) != NULL &&
                !instr_is_meta_may_fault(instr))
            return instr;
    }
    return NULL;
}
示例#21
0
void
cfi_insert_meta_native_call_vargs(void *dcontext, instrlist_t *bb, instr_t *cursor,
                       bool clean_call, void *callee)
{
    instr_t *in = (cursor == NULL) ? instrlist_last(bb) : instr_get_prev(cursor);

   // PRE(ilist, instr, INSTR_CREATE_mov_ld(dcontext, opnd_create_reg(REG_RDI), opnd_create_reg(REG_RSP)));

    PRE(bb, cursor, INSTR_CREATE_call(dcontext, opnd_create_pc(callee)));

    /* mark it all meta */
    if (in == NULL)
        in = instrlist_first(bb);
    else
        in = instr_get_next(in);
    while (in != cursor) {
        instr_set_ok_to_mangle(in, false);
        in = instr_get_next(in);
    }
}
示例#22
0
文件: utils.c 项目: zhaoqin/Umbra
/* Remove the rest instructions from ilist after instr (including instr) */
void
instrlist_truncate(void *drcontext, instrlist_t *ilist, instr_t *instr)
{
    instr_t *next_instr;

    DR_ASSERT_MSG(instr != NULL, "Wrong instr to truncate!");
    for(; instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);
        instrlist_remove(ilist, instr);
        instr_destroy(drcontext, instr);
    }
}
示例#23
0
/* prepends inst to the list ("inst" can be a chain of insts) */
void
instrlist_prepend(instrlist_t *ilist, instr_t *inst)
{
    instr_t *top = inst;
    instr_t *bot;

    CLIENT_ASSERT(instr_get_prev(inst) == NULL,
                  "instrlist_prepend: cannot add middle of list");
    check_translation(ilist, inst);
    while (instr_get_next(inst)) {
        inst = instr_get_next(inst);
        check_translation(ilist, inst);
    }
    bot = inst;
    if (ilist->first) {
        instr_set_next(bot, ilist->first);
        instr_set_prev(ilist->first, bot);
        ilist->first = top;
    } else {
        ilist->first = top;
        ilist->last = bot;
    }
}
示例#24
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;
}
示例#25
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;
}
示例#26
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;
}
示例#27
0
/* iterate basic block to check if aflags are dead after (including) where */
static bool
bb_aflags_are_dead(instrlist_t *ilist, instr_t *where)
{
    instr_t *instr;
    uint flags;
    
    for (instr = where; instr != NULL; instr = instr_get_next(instr)) {
        flags = instr_get_arith_flags(instr);
        if (TESTANY(EFLAGS_READ_6, flags))
            return false;
        if (TESTALL(EFLAGS_WRITE_6, flags))
            return true;
    }
    return false;
}
示例#28
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;
}
示例#29
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;
}
示例#30
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;
}