Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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
}
Ejemplo n.º 6
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");
    }
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}