Example #1
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    module_data_t *appmod;
    dr_set_client_name("DynamoRIO Sample Client 'modxfer_app2lib'",
                       "http://dynamorio.org/issues");
    appmod = dr_get_main_module();
    DR_ASSERT(appmod != NULL);
    app_base = appmod->start;
    app_end = appmod->end;
    dr_free_module_data(appmod);

    if (!drmgr_init())
        DR_ASSERT(false);

    /* register events */
    dr_register_exit_event(event_exit);
    if (!drmgr_register_bb_instrumentation_event(event_analyze_bb,
                                                 event_insert_instrumentation, NULL))
        DR_ASSERT(false);

    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, DR_LOG_ALL, 1, "Client 'modxfer_app2lib' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
#    ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called at init. */
        dr_enable_console_printing();
#    endif
        dr_fprintf(STDERR, "Client modxfer_app2lib is running\n");
    }
#endif
}
Example #2
0
DR_EXPORT void
dr_init(client_id_t id)
{
    /* Look up start_monitor() and stop_monitor() in the target app.
     * These functions are dummy markers that tell us when to start
     * and stop printing syscalls.
     */
    /* NOTE - we could use dr_module_lookup_by_name, but we use the iterator instead
     * to test it out. */
    dr_module_iterator_t *iter = dr_module_iterator_start();
    while (dr_module_iterator_hasnext(iter)) {
        module_data_t *data = dr_module_iterator_next(iter);
        if (strcmp(dr_module_preferred_name(data), TEST_NAME) == 0) {
            module_handle_t lib = data->handle;
            start_pc = (app_pc)dr_get_proc_address(lib, "start_monitor");
            stop_pc = (app_pc)dr_get_proc_address(lib, "stop_monitor");
        }
        dr_free_module_data(data);
    }
    dr_module_iterator_stop(iter);

    if (start_pc == NULL || stop_pc == NULL) {
        dr_fprintf(STDERR, "ERROR: did not find start/stop markers\n");
    }

    /* Register the BB hook */
    dr_register_bb_event(bb_event);
#ifdef LINUX  /* With early injection, libc won't be loaded until later. */
    dr_register_module_load_event(event_module_load);
#endif
}
Example #3
0
static
dr_signal_action_t signal_event_redirect(void *dcontext, dr_siginfo_t *info)
{
    if (info->sig == SIGSEGV) {
        app_pc addr;
        module_data_t *data = dr_lookup_module_by_name("client."EVENTS);
        dr_fprintf(STDERR, "signal event redirect\n");
        if (data == NULL) {
            dr_fprintf(STDERR, "couldn't find client."EVENTS" module\n");
            return DR_SIGNAL_DELIVER;
        }
        addr = (app_pc)dr_get_proc_address(data->handle, "redirect");
        dr_free_module_data(data);
        if (addr == NULL) {
            dr_fprintf(STDERR, "Couldn't find function redirect in client."EVENTS"\n");
            return DR_SIGNAL_DELIVER;
        }
#ifdef X64
        /* align properly in case redirect function relies on conventions (i#384) */
        info->mcontext->xsp = ALIGN_BACKWARD(info->mcontext->xsp, 16) - sizeof(void*);
#endif
        info->mcontext->pc = addr;
        return DR_SIGNAL_REDIRECT;
    }
    return DR_SIGNAL_DELIVER;
}
Example #4
0
static
bool exception_event_redirect(void *dcontext, dr_exception_t *excpt)
{
    app_pc addr;
    dr_mcontext_t mcontext = {sizeof(mcontext),DR_MC_ALL,};
    module_data_t *data = dr_lookup_module_by_name("client."EVENTS".exe");
    dr_fprintf(STDERR, "exception event redirect\n");
    if (data == NULL) {
        dr_fprintf(STDERR, "couldn't find "EVENTS".exe module\n");
        return true;
    }
    addr = (app_pc)dr_get_proc_address(data->handle, "redirect");
    dr_free_module_data(data);
    mcontext = *excpt->mcontext;
    mcontext.pc = addr;
    if (addr == NULL) {
        dr_fprintf(STDERR, "Couldn't find function redirect in "EVENTS".exe\n");
        return true;
    }
#ifdef X64
    /* align properly in case redirect function relies on conventions (i#419) */
    mcontext.xsp = ALIGN_BACKWARD(mcontext.xsp, 16) - sizeof(void*);
#endif
    dr_redirect_execution(&mcontext);
    dr_fprintf(STDERR, "should not be reached, dr_redirect_execution() should not return\n");
    return true;
}
Example #5
0
DR_EXPORT void
dr_init(client_id_t id)
{
    module_data_t *appmod  = dr_get_main_module();

    DR_ASSERT(appmod != NULL);
    app_base = appmod->start;
    app_end  = appmod->end;
    dr_free_module_data(appmod);

    /* register events */
    dr_register_exit_event(event_exit);
    dr_register_bb_event(event_basic_block);

    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, LOG_ALL, 1, "Client 'modxfer_app2lib' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
# ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called in dr_init(). */
        dr_enable_console_printing();
# endif
        dr_fprintf(STDERR, "Client modxfer_app2lib is running\n");
    }
#endif
}
Example #6
0
/* this is only called when the instrace mode is operand trace (this happens at the instrumentation time) */
static void operand_trace(instr_t * instr, void * drcontext){

	int i;
	char stringop[MAX_STRING_LENGTH];
	int pc = 0;
	per_thread_t * data = drmgr_get_tls_field(drcontext, tls_index);
	module_data_t * module_data = dr_lookup_module(instr_get_app_pc(instr));

	if (module_data != NULL){
		pc = instr_get_app_pc(instr) - module_data->start;
	}
	instr_disassemble_to_buffer(drcontext, instr, stringop, MAX_STRING_LENGTH);
	
	if (client_arg->instrace_mode == OPERAND_TRACE){

		dr_fprintf(data->outfile, "%s\n", stringop);

		for (i = 0; i < instr_num_dsts(instr); i++){
			opnd_disassemble_to_buffer(drcontext, instr_get_dst(instr, i), stringop, MAX_STRING_LENGTH);
			if ((instr_get_opcode(instr) == OP_lea) && opnd_is_base_disp(instr_get_dst(instr,i))){
				dr_fprintf(data->outfile, "dst-\n");
				print_base_disp_for_lea(data->outfile, instr_get_dst(instr, i));
			}
			else{
				dr_fprintf(data->outfile, "dst-%d-%s\n", i, stringop);
			}
		}

		for (i = 0; i < instr_num_srcs(instr); i++){
			opnd_disassemble_to_buffer(drcontext, instr_get_src(instr, i), stringop, MAX_STRING_LENGTH);
			if ((instr_get_opcode(instr) == OP_lea) && opnd_is_base_disp(instr_get_src(instr, i))){
				dr_fprintf(data->outfile, "src-\n");
				print_base_disp_for_lea(data->outfile, instr_get_src(instr, i));
			}
			else{
				dr_fprintf(data->outfile, "src-%d-%s\n", i, stringop);
			}
		}

		if (module_data != NULL){
			dr_fprintf(data->outfile, "app_pc-%d\n", pc);
		}
	}
	else if (client_arg->instrace_mode == INS_DISASM_TRACE){
		if (module_data != NULL){
			if (md_get_module_position(instrace_head, module_data->full_path) == -1){
				md_add_module(instrace_head, module_data->full_path, MAX_BBS_PER_MODULE);
			}
			dr_fprintf(data->outfile, "%d,%d,%s\n", md_get_module_position(instrace_head, module_data->full_path), pc, stringop);
		}
		else{
			dr_fprintf(data->outfile, "%d,%d,%s\n",0, 0, stringop);
		}
		
	}

	dr_free_module_data(module_data);

}
Example #7
0
static void
print_address(app_pc addr, int bits, double loss, double lossD)
{
	testarr[testcount] = lossD;
	testcount++;
	char key_string[KEY_MAX_LENGTH];
	snprintf(key_string, KEY_MAX_LENGTH, "%s", "main");//sym->name);


    const char* prefix = "PRINT ADDRESS: ";
    drsym_error_t symres;
    drsym_info_t *sym;
    char sbuf[sizeof(*sym) + MAX_SYM_RESULT];
    module_data_t *data;
    data = dr_lookup_module(addr);
    if (data == NULL) {
       // dr_fprintf(logF, "%s data is null "PFX" \n", prefix, addr);
        return;
    }
    snprintf(process_path, MAXIMUM_PATH,"%s",data->full_path);


    if(!callgrind_log_created){
	writeCallgrind(thread_id_for_log);
	callgrind_log_created = true;
    }

    sym = (drsym_info_t *) sbuf;
    sym->struct_size = sizeof(*sym);
    sym->name_size = MAX_SYM_RESULT;   

    symres = drsym_lookup_address(data->full_path, addr - data->start, sym,
                           DRSYM_DEFAULT_FLAGS);
/*

    if (symres == DRSYM_SUCCESS || symres == DRSYM_ERROR_LINE_NOT_AVAILABLE) {
        const char *modname = dr_module_preferred_name(data);
        if (modname == NULL)
            modname = "<noname>";
        //dr_fprintf(logF, "%s "PFX" %s, function name is: %s, "PIFX", line off "PFX" \n", prefix, addr,
                   //modname, sym->name, addr - data->start - sym->start_offs, sym->line_offs);


//printf("test ins %d\n", testcount);

//add check for line not available
       if (symres == DRSYM_ERROR_LINE_NOT_AVAILABLE) {
           // dr_fprintf(logF, "%s Line is not available\n", prefix);
        } else {
           // dr_fprintf(logF, "Line number is  %s:%"UINT64_FORMAT_CODE" %d\n",
                      // sym->file, sym->line, sym->line_offs);
        }
    } else
      //  dr_fprintf(logF, "%s some error "PFX" \n", prefix, addr);
  */
    dr_free_module_data(data);
}
Example #8
0
void clean_call_mem_information(instr_t * instr, app_pc mem_val, uint write){

	void * drcontext = dr_get_current_drcontext();
	module_data_t * data = dr_lookup_module(instr_get_app_pc(instr));
	uint offset;

	app_pc base_pc;
	size_t size;
	uint prot;
	file_t dump_file;
	char * dump_filename;
	
	DR_ASSERT(data != NULL);
	offset = instr_get_app_pc(instr) - data->start;

	dr_mutex_lock(mutex);

	//if (!md_lookup_bb_in_module(done_head, data->full_path, offset)){

		//md_add_bb_to_module(done_head, data->full_path, offset, MAX_BBS_PER_MODULE, false); 
		dr_query_memory(mem_val, &base_pc, &size, &prot);
		//DEBUG_PRINT("base pc - %x, size - %u, write - %u\n", base_pc, size, write);
		if (write){  /* postpone till the end of the function */
			if (!is_mem_region_present(write_regions, base_pc, size, write_region_size)){
				DEBUG_PRINT("write registered - offset - %x memval %x\n", offset, mem_val);
				add_to_mem_region(write_regions, base_pc, size, &write_region_size);
				DEBUG_PRINT("base pc %x, size %d\n", base_pc, size); 
			}
		}
		else{
			if (!is_mem_region_present(read_regions, base_pc, size, read_region_size)){
				add_to_mem_region(read_regions, base_pc, size, &read_region_size);
				//DEBUG_PRINT("size - %d\n", read_region_size);
				//DEBUG_PRINT("present - %d\n", is_mem_region_present(read_regions, base_pc, size, read_region_size));
				//dr_abort();
				DEBUG_PRINT("read registered - offset - %x memval %x\n", offset,  mem_val);
				DEBUG_PRINT("base pc %x, size %d\n", base_pc, size);
				dump_filename = get_mem_dump_filename(base_pc, size, write,0);
				dump_file = dr_open_file(dump_filename, DR_FILE_WRITE_OVERWRITE);
				DEBUG_PRINT("%s dumping file\n", dump_filename);
				do_mem_dump(dump_file, base_pc, size);
				DEBUG_PRINT("file dumped\n");
				dr_global_free(dump_filename, sizeof(char) * MAX_STRING_LENGTH);
				dr_close_file(dump_file);
			}
		}



	//}

	dr_mutex_unlock(mutex);
	dr_free_module_data(data);


}
Example #9
0
static int
get_sysnum(const char *wrapper)
{
    byte *entry;
    module_data_t *data = dr_lookup_module_by_name("ntdll.dll");
    ASSERT(data != NULL);
    entry = (byte *) dr_get_proc_address(data->handle, wrapper);
    dr_free_module_data(data);
    if (entry == NULL)
        return -1;
    return drmgr_decode_sysnum_from_wrapper(entry);
}
Example #10
0
static
bool is_in_known_module(app_pc pc, bool *found_section, IMAGE_SECTION_HEADER *section)
{
    bool found = false;
    module_data_t *data = dr_lookup_module(pc);
    if (data != NULL) {
        found = true;
        *found_section = dr_lookup_module_section(data->handle, pc, section);
    }
    dr_free_module_data(data);
    return found;
}
Example #11
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 #12
0
app_pc
get_ntdll_base(void)
{
    static app_pc ntdll_base; /* cached value */
    if (ntdll_base == NULL) {
        module_data_t *data = dr_lookup_module_by_name("ntdll.dll");
        ASSERT(data != NULL, "cannot find ntdll.dll");
        ntdll_base = data->start;
        dr_free_module_data(data);
        ASSERT(ntdll_base != NULL, "internal error finding ntdll.dll base");
    }
    return ntdll_base;
}
Example #13
0
app_pc
get_heap_start(void)
{
    static app_pc heap_start; /* cached value */
    if (heap_start == NULL) {
        app_pc cur_brk = get_brk(true/*pre-us*/);
        dr_mem_info_t info;
        module_data_t *data;
        /* Locate the heap */
        if (!dr_query_memory_ex(cur_brk - 1, &info)) {
            ASSERT(false, "cannot find heap region");
            return NULL;
        }
        if (info.type == DR_MEMTYPE_FREE || info.type == DR_MEMTYPE_IMAGE ||
            !TEST(DR_MEMPROT_WRITE, info.prot)) {
            /* Heap is empty */
            heap_start = cur_brk;
        } else {
            ASSERT(!dr_memory_is_dr_internal(info.base_pc), "heap location error");
            /* we no longer assert that these are equal b/c -replace_malloc
             * has extended the brk already
             */
            ASSERT(info.base_pc + info.size >= cur_brk, "heap location error");
            heap_start = info.base_pc;
            /* workaround for PR 618178 where /proc/maps is wrong on suse
             * and lists last 2 pages of executable as heap!
             */
            /* On some old Linux kernel, the heap might be right after the bss
             * segment. DR's map iterator used by dr_query_memory_ex cannot
             * split bss out of heap.
             * We use dr_lookup_module to find the right bounds of bss so that
             * we can check whether the base is bss, existing heap, or merge of
             * the two.
             */
            /* XXX: we still cannot handle the case that the application creates
             * memory right before the heap.
             */
            data = dr_lookup_module(info.base_pc);
            if (data != NULL) {
                if (data->start < heap_start && data->end > heap_start) {
                    heap_start = (byte *) ALIGN_FORWARD(data->end, PAGE_SIZE);
                    LOG(1, "WARNING: workaround for invalid heap_start "PFX" => "PFX"\n",
                        info.base_pc, heap_start);
                }
                dr_free_module_data(data);
            }
        }
    }
    return heap_start;
}
Example #14
0
/* Lookup the module containing addr and see if we have a table entry for it */
static table_entry_t *
get_entry_for_address(app_pc addr)
{
    module_data_t *data = dr_lookup_module(addr);
    table_entry_t *entry = NULL;
    if (data != NULL) {
        entry = table;
        while (entry != NULL &&
               _stricmp(dr_module_preferred_name(data), entry->value.module_name) != 0) {
            entry = entry->next;
        }
        dr_free_module_data(data);
    }
    return entry;
}
Example #15
0
static int
get_write_sysnum(void)
{
#ifdef LINUX
    return SYS_write;
#else
    byte *entry;
    module_data_t *data = dr_lookup_module_by_name("ntdll.dll");
    DR_ASSERT(data != NULL);
    entry = (byte *) dr_get_proc_address(data->handle, "NtWriteFile");
    DR_ASSERT(entry != NULL);
    dr_free_module_data(data);
    return drmgr_decode_sysnum_from_wrapper(entry);
#endif
}
Example #16
0
DR_EXPORT
void dr_init(client_id_t id)
{
    module_data_t *data;
    dr_fprintf(STDERR, "thank you for testing the client interface\n");
    dr_register_bb_event(bb_event);
    data = dr_lookup_module_by_name("kernel32.dll");
    if (data != NULL) {
        exit_proc_addr = (void *)dr_get_proc_address(data->handle, "ExitProcess");
        if (exit_proc_addr == NULL)
            dr_fprintf(STDERR, "ERROR: unable to find kernel32!ExitProcess\n");
        dr_free_module_data(data);
    } else {
        dr_fprintf(STDERR, "ERROR: unable to find ntdll.dll\n");
    }
}
Example #17
0
static bool
drmgr_cls_init(void)
{
    /* For callback init we watch for KiUserCallbackDispatcher.
     * For callback exit we watch for NtCallbackReturn or int 0x2b.
     */
    static int cls_initialized; /* 0=not tried; >0=success; <0=failure */
    module_data_t *data;
    module_handle_t ntdll_lib;
    app_pc addr_cbret;
    drmgr_priority_t priority = {sizeof(priority), "drmgr_cls", NULL, NULL, 0};

    if (cls_initialized > 0)
        return true;
    else if (cls_initialized < 0)
        return false;
    cls_initialized = -1;

    if (!drmgr_register_bb_instrumentation_event(drmgr_event_bb_analysis,
                                                 drmgr_event_bb_insert,
                                                 &priority))
        return false;
    dr_register_filter_syscall_event(drmgr_event_filter_syscall);

    data = dr_lookup_module_by_name("ntdll.dll");
    if (data == NULL) {
        /* fatal error: something is really wrong w/ underlying DR */
        return false;
    }
    ntdll_lib = data->handle;
    dr_free_module_data(data);
    addr_KiCallback = (app_pc) dr_get_proc_address(ntdll_lib, "KiUserCallbackDispatcher");
    if (addr_KiCallback == NULL)
        return false; /* should not happen */
    /* the wrapper is not good enough for two reasons: one, we want to swap
     * contexts at the last possible moment, not prior to executing a few
     * instrs; second, we'll miss hand-rolled syscalls
     */
    addr_cbret = (app_pc) dr_get_proc_address(ntdll_lib, "NtCallbackReturn");
    if (addr_cbret == NULL)
        return false; /* should not happen */
    sysnum_NtCallbackReturn = drmgr_decode_sysnum_from_wrapper(addr_cbret);
    if (sysnum_NtCallbackReturn == -1)
        return false; /* should not happen */
    cls_initialized = 1;
    return true;
}
Example #18
0
static int
get_write_sysnum(void)
{
    /* XXX: we could use the "drsyscall" Extension from the Dr. Memory Framework
     * (DRMF) to obtain the number of any system call from the name.
     */
#ifdef UNIX
    return SYS_write;
#else
    byte *entry;
    module_data_t *data = dr_lookup_module_by_name("ntdll.dll");
    DR_ASSERT(data != NULL);
    entry = (byte *) dr_get_proc_address(data->handle, "NtWriteFile");
    DR_ASSERT(entry != NULL);
    dr_free_module_data(data);
    return drmgr_decode_sysnum_from_wrapper(entry);
#endif
}
Example #19
0
static void
memtrace(void *drcontext)
{
    per_thread_t *data;
    int num_refs;
    mem_ref_t *mem_ref;
#ifdef READABLE_TRACE
    int i;
#endif

	module_data_t * mdata;

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

#ifdef READABLE_TRACE
    /*dr_fprintf(data->log,
               "Format: <instr address>,<(r)ead/(w)rite>,<data size>,<data address>\n");*/

	for (i = 0; i < num_refs; i++) {
		mdata = dr_lookup_module(mem_ref->pc);
		if (mdata != NULL){
			if (((uint)mem_ref->addr > data->stack_base) || ((uint)mem_ref->addr < data->stack_limit)){
				dr_fprintf(data->outfile, "%x,%x,%d,%d,"PFX"\n", mdata->start, mem_ref->pc - mdata->start
					, mem_ref->write ? 1 : 0 , mem_ref->size, mem_ref->addr);
			}
			dr_free_module_data(mdata);
		}
			
		++mem_ref;
	}

#else
    dr_write_file(data->log, data->buf_base,
                  (size_t)(data->buf_ptr - data->buf_base));
#endif

    memset(data->buf_base, 0, MEM_BUF_SIZE);
    data->num_refs += num_refs;
    data->buf_ptr   = data->buf_base;
}
Example #20
0
/* this is only called when the instrace mode is disassembly trace (this happens at the analysis time)*/
static void clean_call_disassembly_trace(){

	char disassembly[SHORT_STRING_LENGTH];

	per_thread_t * data = drmgr_get_tls_field(dr_get_current_drcontext(), tls_index);
	instr_trace_t * trace = (instr_trace_t *)data->buf_ptr;
	module_data_t * md;

	md = dr_lookup_module(instr_get_app_pc(trace->static_info_instr));

	instr_disassemble_to_buffer(dr_get_current_drcontext(), trace->static_info_instr, disassembly, SHORT_STRING_LENGTH);

	dr_fprintf(data->outfile, "%s ", disassembly);

	if (md != NULL){
		dr_fprintf(data->outfile, "%x", instr_get_app_pc(trace->static_info_instr) - md->start);
		dr_free_module_data(md);
	}
	dr_fprintf(data->outfile, "\n");
}
Example #21
0
DR_EXPORT
void dr_init(client_id_t id)
{
    /* Look up start_instrument() and stop_instrument() in the app.
     * These functions are markers that tell us when to start and stop
     * instrumenting.
     */
    module_data_t *prog = dr_lookup_module_by_name("client.cbr4.exe");
    ASSERT(prog != NULL);

    start_pc = (app_pc)dr_get_proc_address(prog->handle, "start_instrument");
    stop_pc = (app_pc)dr_get_proc_address(prog->handle, "stop_instrument");

    ASSERT(start_pc != NULL && stop_pc != NULL);
    dr_free_module_data(prog);

    table = new_table();

    dr_register_bb_event(bb_event);
    dr_register_exit_event(dr_exit);
}
Example #22
0
static
dr_signal_action_t signal_event_redirect(void *dcontext, dr_siginfo_t *info)
{
    if (info->sig == SIGSEGV) {
        app_pc addr;
        module_data_t *data = dr_lookup_module_by_name("client.events");
        dr_fprintf(STDERR, "signal event redirect\n");
        if (data == NULL) {
            dr_fprintf(STDERR, "couldn't find client.events module\n");
            return DR_SIGNAL_DELIVER;
        }
        addr = (app_pc)dr_get_proc_address(data->handle, "redirect");
        dr_free_module_data(data);
        if (addr == NULL) {
            dr_fprintf(STDERR, "Couldn't find function redirect in client.events\n");
            return DR_SIGNAL_DELIVER;
        }
        info->mcontext->pc = addr;
        return DR_SIGNAL_REDIRECT;
    }
    return DR_SIGNAL_DELIVER;
}
Example #23
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    module_data_t *app;
    generic_func_t repeatme_addr;
    drmgr_init();
    if (drfuzz_init(id) != DRMF_SUCCESS)
        EXPECT(false, "drfuzz failed to init");
    dr_register_exit_event(exit_event);

    /* fuzz repeatme */
    app = dr_get_main_module();
    if (app == NULL)
        EXPECT(false, "failed to get application module");
    repeatme_addr = dr_get_proc_address(app->handle, "repeatme");
    if (repeatme_addr == NULL)
        EXPECT(false, "failed to find function repeatme");
    if (drfuzz_fuzz_target(repeatme_addr, 1, 0, DRWRAP_CALLCONV_DEFAULT,
                           pre_fuzz_cb, post_fuzz_cb) != DRMF_SUCCESS)
        EXPECT(false, "drfuzz failed to fuzz function repeatme");
    dr_free_module_data(app);
}
Example #24
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    dr_set_client_name("DynamoRIO Sample Client 'inscount'",
                       "http://dynamorio.org/issues");

    /* Options */
    if (!droption_parser_t::parse_argv(DROPTION_SCOPE_CLIENT, argc, argv, NULL, NULL))
        DR_ASSERT(false);
    drmgr_init();

    /* Get main module address */
    if (only_from_app.get_value()) {
        module_data_t *exe = dr_get_main_module();
        if (exe != NULL)
            exe_start = exe->start;
        dr_free_module_data(exe);
    }

    /* register events */
    dr_register_exit_event(event_exit);
    drmgr_register_bb_instrumentation_event(event_bb_analysis, event_app_instruction,
                                            NULL);

    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, DR_LOG_ALL, 1, "Client 'inscount' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
#    ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called at init. */
        dr_enable_console_printing();
#    endif
        dr_fprintf(STDERR, "Client inscount is running\n");
    }
#endif
}
Example #25
0
static void
print_address(file_t f, app_pc addr, const char *prefix)
{
    drsym_error_t symres;
    drsym_info_t sym;
    char name[MAX_SYM_RESULT];
    char file[MAXIMUM_PATH];
    module_data_t *data;
    data = dr_lookup_module(addr);
    if (data == NULL) {
        dr_fprintf(f, "%s "PFX" ? ??:0\n", prefix, addr);
        return;
    }
    sym.struct_size = sizeof(sym);
    sym.name = name;
    sym.name_size = MAX_SYM_RESULT;
    sym.file = file;
    sym.file_size = MAXIMUM_PATH;
    symres = drsym_lookup_address(data->full_path, addr - data->start, &sym,
                                  DRSYM_DEFAULT_FLAGS);
    if (symres == DRSYM_SUCCESS || symres == DRSYM_ERROR_LINE_NOT_AVAILABLE) {
        const char *modname = dr_module_preferred_name(data);
        if (modname == NULL)
            modname = "<noname>";
        dr_fprintf(f, "%s "PFX" %s!%s+"PIFX, prefix, addr,
                   modname, sym.name, addr - data->start - sym.start_offs);
        if (symres == DRSYM_ERROR_LINE_NOT_AVAILABLE) {
            dr_fprintf(f, " ??:0\n");
        } else {
            dr_fprintf(f, " %s:%"UINT64_FORMAT_CODE"+"PIFX"\n",
                       sym.file, sym.line, sym.line_offs);
        }
    } else
        dr_fprintf(f, "%s "PFX" ? ??:0\n", prefix, addr);
    dr_free_module_data(data);
}
Example #26
0
static dr_emit_flags_t
event_bb_analysis(void *drcontext, void *tag, instrlist_t *bb, bool for_trace,
                  bool translating, void **user_data)
{
    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
    /* Only count in app BBs */
    if (only_from_app.get_value()) {
        module_data_t *mod = dr_lookup_module(dr_fragment_app_pc(tag));
        if (mod != NULL) {
            bool from_exe = (mod->start == exe_start);
            dr_free_module_data(mod);
            if (!from_exe) {
                *user_data = NULL;
                return DR_EMIT_DEFAULT;
            }
        }
    }

    /* Count instructions. If an emulation client is running with this client,
     * we want to count all the original native instructions and the emulated
     * instruction but NOT the introduced native instructions used for emulation.
     */
    bool is_emulation = false;
    for (instr = instrlist_first(bb), num_instrs = 0; instr != NULL;
         instr = instr_get_next(instr)) {
        if (drmgr_is_emulation_start(instr)) {
            /* Each emulated instruction is replaced by a series of native
             * instructions delimited by labels indicating when the emulation
             * sequence begins and ends. It is the responsibility of the
             * emulation client to place the start/stop labels correctly.
             */
            num_instrs++;
            is_emulation = true;
            /* Data about the emulated instruction can be extracted from the
             * start label using the accessor function:
             * drmgr_get_emulated_instr_data()
             */
            continue;
        }
        if (drmgr_is_emulation_end(instr)) {
            is_emulation = false;
            continue;
        }
        if (is_emulation)
            continue;
        if (!instr_is_app(instr))
            continue;
        num_instrs++;
    }
    *user_data = (void *)(ptr_uint_t)num_instrs;

#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
    dr_printf("Finished counting for dynamorio_basic_block(tag=" PFX ")\n", tag);
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
    return DR_EMIT_DEFAULT;
}
Example #27
0
static void
event_exit(void)
{
    int i;
    char msg[512];
    int len;
    int j;
    uint64 xmod_xfer = 0;
    uint64 self_xfer = 0;
    for (i = 0; i < num_mods; i++) {
        dr_fprintf(logfile, "module %3d: %s\n", i,
                   dr_module_preferred_name(mod_array[i].info) == NULL ?
                   "<unknown>" : dr_module_preferred_name(mod_array[i].info));
        dr_fprintf(logfile, "%20llu instruction executed\n", mod_cnt[i]);
    }
    if (mod_cnt[UNKNOW_MODULE_IDX] != 0) {
        dr_fprintf(logfile, "unknown modules:\n%20llu instruction executed\n",
                   mod_cnt[UNKNOW_MODULE_IDX]);
    }
    for (i = 0; i < MAX_NUM_MODULES; i++) {
        for (j = 0; j < num_mods; j++) {
            if (xfer_cnt[i][j] != 0) {
                dr_fprintf(logfile, "mod %3d => mod %3d: %8u\n",
                           i, j, xfer_cnt[i][j]);
                if (i == j)
                    self_xfer += xfer_cnt[i][j];
                else
                    xmod_xfer += xfer_cnt[i][j];
            }
        }
    }
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "Instrumentation results:\n"
                      "\t%10llu instructions executed\n"
                      "\t%10llu (%2.3f%%) cross module indirect branches\n"
                      "\t%10llu (%2.3f%%) intra-module indirect branches\n",
                      ins_count,
                      xmod_xfer, 100*(float)xmod_xfer/ins_count,
                      self_xfer, 100*(float)self_xfer/ins_count);
    DR_ASSERT(len > 0);
    NULL_TERMINATE_BUFFER(msg);
#ifdef SHOW_RESULTS
    DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */
    dr_fprintf(logfile, "%s\n", msg);
    dr_mutex_lock(mod_lock);
    for (i = 0; i < num_mods; i++) {
        DR_ASSERT(mod_array[i].info != NULL);
        dr_free_module_data(mod_array[i].info);
    }
    dr_mutex_unlock(mod_lock);
    dr_mutex_destroy(mod_lock);
    log_file_close(logfile);
    drx_exit();
    if (!drmgr_unregister_bb_instrumentation_event(event_analyze_bb) ||
        !drmgr_unregister_module_load_event(event_module_load) ||
        !drmgr_unregister_module_unload_event(event_module_unload) ||
        drreg_exit() != DRREG_SUCCESS)
        DR_ASSERT(false);
    drmgr_exit();
}
Example #28
0
static void dynamic_info_instrumentation(void *drcontext, instrlist_t *ilist, instr_t *where,
               instr_t * static_info)
{


	/* 
		issues that may arise
		1. pc and eflags is uint but in 64 bit mode 8 byte transfers are done -> so far no problem (need to see this)
			need to see whether there is a better way
		2. double check all the printing
	*/

	/*
		this function does the acutal instrumentation

		arguments - 

		we get a filled pointer here about the operand types for a given instruction (srcs and dests)
		1) increment the pointer to the instr_trace buffers
		2) add this pointer to instr_trace_t wrapper
		3) check whether any of the srcs and dests have memory operations; if so add a lea instruction and get the dynamic address
			Add this address to instr_trace_t structure
		4) if the buffer is full call a function to dump it to the file and restore the head ptr of the buffer 
			(lean function is used utilizing a code cache to limit code bloat needed for a clean call before every instruction.)
	*/

    instr_t *instr, *call, *restore, *first, *second;
    opnd_t   ref, opnd1, opnd2;
    reg_id_t reg1 = DR_REG_XBX; /* We can optimize it by picking dead reg */
    reg_id_t reg2 = DR_REG_XCX; /* reg2 must be ECX or RCX for jecxz */
	reg_id_t reg3 = DR_REG_XAX;
    per_thread_t *data;
    uint pc;
	uint i;

	module_data_t * module_data;

	if (client_arg->instrace_mode == DISASSEMBLY_TRACE){
		dr_insert_clean_call(drcontext, ilist, where, clean_call_disassembly_trace, false, 0);
		return;
	}

    data = drmgr_get_tls_field(drcontext, tls_index);

    /* Steal the register for memory reference address *
     * We can optimize away the unnecessary register save and restore
     * by analyzing the code and finding the register is dead.
     */

    dr_save_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
    dr_save_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);
	dr_save_reg(drcontext, ilist, where, reg3, SPILL_SLOT_4);

	
	drmgr_insert_read_tls_field(drcontext, tls_index, ilist, where, reg2);

    /* Load data->buf_ptr into reg2 */
    opnd1 = opnd_create_reg(reg2);
    opnd2 = OPND_CREATE_MEMPTR(reg2, offsetof(per_thread_t, buf_ptr));
    instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);


	/* buf_ptr->static_info_instr = static_info; */
    /* Move static_info to static_info_instr field of buf (which is a instr_trace_t *) */
    opnd1 = OPND_CREATE_MEMPTR(reg2, offsetof(instr_trace_t, static_info_instr));
	instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t)static_info, opnd1, ilist, where, &first, &second);

	/* buf_ptr->num_mem = 0; */
    opnd1 = OPND_CREATE_MEMPTR(reg2, offsetof(instr_trace_t, num_mem));
    
	instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t)0, opnd1, ilist, where, &first, &second);

	for (i = 0; i<instr_num_dsts(where); i++){
		if (opnd_is_memory_reference(instr_get_dst(where, i))){
			ref = instr_get_dst(where, i);

			DR_ASSERT(opnd_is_null(ref) == false);


			dr_restore_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
			dr_restore_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);

#ifdef DEBUG_MEM_REGS
			dr_insert_clean_call(drcontext, ilist, where, clean_call_disassembly_trace, false, 0);
			dr_insert_clean_call(drcontext, ilist, where, clean_call_print_regvalues, false, 0);
#endif
			
			drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg1, reg2);

#ifdef DEBUG_MEM_REGS
			dr_insert_clean_call(drcontext, ilist, where, clean_call_print_regvalues, false, 0);
#endif

#ifdef DEBUG_MEM_STATS
			dr_insert_clean_call(drcontext, ilist, where, clean_call_disassembly_trace, false, 0);
			dr_insert_clean_call(drcontext, ilist, where, clean_call_mem_stats, false, 1, opnd_create_reg(reg1));
#endif

			dr_insert_clean_call(drcontext, ilist, where, clean_call_populate_mem, false, 3, opnd_create_reg(reg1), OPND_CREATE_INT32(i), OPND_CREATE_INT32(DST_TYPE));

		}
	}

	for (i = 0; i<instr_num_srcs(where); i++){
		if (opnd_is_memory_reference(instr_get_src(where, i))){
			ref = instr_get_src(where, i);

			DR_ASSERT(opnd_is_null(ref) == false);			
			
			dr_restore_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
			dr_restore_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);

#ifdef DEBUG_MEM_REGS
			dr_insert_clean_call(drcontext, ilist, where, clean_call_disassembly_trace, false, 0);
			dr_insert_clean_call(drcontext, ilist, where, clean_call_print_regvalues, false, 0);
#endif

			drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg1, reg2);

#ifdef DEBUG_MEM_REGS

			dr_insert_clean_call(drcontext, ilist, where, clean_call_print_regvalues, false, 0);
#endif

#ifdef DEBUG_MEM_STATS
			dr_insert_clean_call(drcontext, ilist, where, clean_call_disassembly_trace, false, 0);
			dr_insert_clean_call(drcontext, ilist, where, clean_call_mem_stats, false, 1, opnd_create_reg(reg1));
#endif

			dr_insert_clean_call(drcontext, ilist, where, clean_call_populate_mem, false, 3, opnd_create_reg(reg1), OPND_CREATE_INT32(i), OPND_CREATE_INT32(SRC_TYPE));

		}
	}
	

	

	drmgr_insert_read_tls_field(drcontext, tls_index, ilist, where, reg2);
    /* Load data->buf_ptr into reg2 */
    opnd1 = opnd_create_reg(reg2);
    opnd2 = OPND_CREATE_MEMPTR(reg2, offsetof(per_thread_t, buf_ptr));
    instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

	/* arithmetic flags are saved here for buf_ptr->eflags filling */
	dr_save_arith_flags_to_xax(drcontext, ilist, where);

	/* load the eflags */
	opnd1 = OPND_CREATE_MEMPTR(reg2, offsetof(instr_trace_t, eflags));
	opnd2 = opnd_create_reg(reg3);
    instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);


	/* load the app_pc */
	opnd1 = OPND_CREATE_MEMPTR(reg2, offsetof(instr_trace_t, pc));
	module_data = dr_lookup_module(instr_get_app_pc(where));

	//dynamically generated code - module information not available - then just store 0 at the pc slot of the instr_trace data
	if (module_data != NULL){
		pc = instr_get_app_pc(where) - module_data->start;
		dr_free_module_data(module_data);
	}
	else{
		pc = 0;
	}

	instrlist_insert_mov_immed_ptrsz(drcontext, (ptr_int_t)pc, opnd1, ilist, where, &first, &second);



	/* buf_ptr++; */
    /* Increment reg value by pointer size using lea instr */
    opnd1 = opnd_create_reg(reg2);
    opnd2 = opnd_create_base_disp(reg2, DR_REG_NULL, 0,
                                  sizeof(instr_trace_t),
                                  OPSZ_lea);
    instr = INSTR_CREATE_lea(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

    /* Update the data->buf_ptr */
    drmgr_insert_read_tls_field(drcontext, tls_index, ilist, where, reg1);
    opnd1 = OPND_CREATE_MEMPTR(reg1, offsetof(per_thread_t, buf_ptr));
    opnd2 = opnd_create_reg(reg2);
    instr = INSTR_CREATE_mov_st(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

    /* we use lea + jecxz trick for better performance
     * lea and jecxz won't disturb the eflags, so we won't insert
     * code to save and restore application's eflags.
     */
    /* lea [reg2 - buf_end] => reg2 */
    opnd1 = opnd_create_reg(reg1);
    opnd2 = OPND_CREATE_MEMPTR(reg1, offsetof(per_thread_t, buf_end));
    instr = INSTR_CREATE_mov_ld(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);
    opnd1 = opnd_create_reg(reg2);
    opnd2 = opnd_create_base_disp(reg1, reg2, 1, 0, OPSZ_lea);
    instr = INSTR_CREATE_lea(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);

    /* jecxz call */
    call  = INSTR_CREATE_label(drcontext);
    opnd1 = opnd_create_instr(call);
    instr = INSTR_CREATE_jecxz(drcontext, opnd1);
    instrlist_meta_preinsert(ilist, where, instr);

    /* jump restore to skip clean call */
    restore = INSTR_CREATE_label(drcontext);
    opnd1 = opnd_create_instr(restore);
    instr = INSTR_CREATE_jmp(drcontext, opnd1);
    instrlist_meta_preinsert(ilist, where, instr);

    /* clean call */
    /* We jump to lean procedure which performs full context switch and
     * clean call invocation. This is to reduce the code cache size.
     */
    instrlist_meta_preinsert(ilist, where, call);
    /* mov restore DR_REG_XCX */
    opnd1 = opnd_create_reg(reg2);
    /* this is the return address for jumping back from lean procedure */
    opnd2 = opnd_create_instr(restore);
    /* We could use instrlist_insert_mov_instr_addr(), but with a register
     * destination we know we can use a 64-bit immediate.
     */
    instr = INSTR_CREATE_mov_imm(drcontext, opnd1, opnd2);
    instrlist_meta_preinsert(ilist, where, instr);
    /* jmp code_cache */
    opnd1 = opnd_create_pc(code_cache);
    instr = INSTR_CREATE_jmp(drcontext, opnd1);
    instrlist_meta_preinsert(ilist, where, instr);

    /* restore %reg */
    instrlist_meta_preinsert(ilist, where, restore);

	//dr_restore_arith_flags_from_xax(drcontext, ilist, where);
    dr_restore_reg(drcontext, ilist, where, reg1, SPILL_SLOT_2);
    dr_restore_reg(drcontext, ilist, where, reg2, SPILL_SLOT_3);
	dr_restore_reg(drcontext, ilist, where, reg3, SPILL_SLOT_4);

	//instrlist_disassemble(drcontext, instr_get_app_pc(instrlist_first(ilist)), ilist, logfile);

}
Example #29
0
static void
module_table_entry_free(void *entry)
{
    dr_free_module_data(((module_entry_t *)entry)->data);
    dr_global_free(entry, sizeof(module_entry_t));
}
Example #30
0
DR_EXPORT
drmf_status_t
drsymcache_init(client_id_t client_id,
                const char *symcache_dir_in,
                size_t modsize_cache_threshold)
{
#ifdef WINDOWS
    module_data_t *mod;
#endif
    drmf_status_t res;
    drmgr_priority_t pri_mod_load_cache =
        {sizeof(pri_mod_load_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL,
         DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ};
    drmgr_priority_t pri_mod_unload_cache =
        {sizeof(pri_mod_unload_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL,
         DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE};
    drmgr_priority_t pri_mod_save_cache =
        {sizeof(pri_mod_save_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE_SAVE, NULL, NULL,
         DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE};

    /* handle multiple sets of init/exit calls */
    int count = dr_atomic_add32_return_sum(&symcache_init_count, 1);
    if (count > 1)
        return DRMF_WARNING_ALREADY_INITIALIZED;

    res = drmf_check_version(client_id);
    if (res != DRMF_SUCCESS)
        return res;

    drmgr_init();
    drmgr_register_module_load_event_ex(symcache_module_load, &pri_mod_load_cache);
    drmgr_register_module_unload_event_ex(symcache_module_unload, &pri_mod_unload_cache);
    drmgr_register_module_load_event_ex(symcache_module_load_save, &pri_mod_save_cache);

    initialized = true;

    op_modsize_cache_threshold = modsize_cache_threshold;

    hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS,
                      IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING),
                      true/*strdup*/, false/*!synch*/,
                      symcache_free_entry, NULL, NULL);
    symcache_lock = dr_mutex_create();

    dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir),
                "%s", symcache_dir_in);
    NULL_TERMINATE_BUFFER(symcache_dir);
    if (!dr_directory_exists(symcache_dir)) {
        if (!dr_create_dir(symcache_dir)) {
            /* check again in case of a race (i#616) */
            if (!dr_directory_exists(symcache_dir)) {
                NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir);
                ASSERT(false, "unable to create symcache dir");
                dr_abort();
            }
        }
    }

#ifdef WINDOWS
    /* It's common for tools to query ntdll in their init routines so we add it
     * early here
     */
    mod = dr_lookup_module_by_name("ntdll.dll");
    if (mod != NULL) {
        symcache_module_load(dr_get_current_drcontext(), mod, true);
        dr_free_module_data(mod);
    }
#endif

    return DRMF_SUCCESS;
}