Ejemplo n.º 1
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
}
Ejemplo n.º 2
0
static void
event_module_load(void *drcontext, const module_data_t *info, bool loaded)
{
    uint64 early_inject;

    /* do some more dr_get_proc_address testing */
    if (strncmp(dr_module_preferred_name(info), "libc.", 5) == 0) {
        module_handle_t lib = info->handle;
        dr_export_info_t fn_info;
        dr_fprintf(STDERR, "found libc\n");
        if (dr_get_proc_address(lib, "malloc") == NULL)
            dr_fprintf(STDERR, "ERROR: can't find malloc in libc\n");
        if (dr_get_proc_address(lib, "free") == NULL)
            dr_fprintf(STDERR, "ERROR: can't find free in libc\n");
        if (dr_get_proc_address(lib, "printf") == NULL)
            dr_fprintf(STDERR, "ERROR: can't find printf in libc\n");

        /* i#884: gettimeofday is indirect code on my system, and calling it
         * will crash unless we wait until libc is fully relocated.
         * dr_get_proc_address() wraps the fault in a try/except and returns
         * NULL.  The _ex variant does not, so we use that to test the lookup.
         */
        if (!dr_get_proc_address_ex(lib, "gettimeofday", &fn_info, sizeof(fn_info)))
            dr_fprintf(STDERR, "ERROR: can't find gettimeofday in libc\n");

        dr_unregister_module_load_event(event_module_load);
    }
}
Ejemplo n.º 3
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.º 4
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.º 5
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.º 6
0
static void
wrap_unwindtest_addr(OUT app_pc *addr, const char *name, const module_data_t *mod)
{
    bool ok;
    *addr = (app_pc) dr_get_proc_address(mod->handle, name);
    CHECK(*addr != NULL, "cannot find lib export");
    ok = drwrap_wrap(*addr, wrap_unwindtest_pre, wrap_unwindtest_post);
    CHECK(ok, "wrap unwindtest failed");
    CHECK(drwrap_is_wrapped(*addr, wrap_unwindtest_pre, wrap_unwindtest_post),
          "drwrap_is_wrapped query failed");
}
Ejemplo n.º 7
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.º 8
0
static void
wrap_addr(OUT app_pc *addr, const char *name, const module_data_t *mod,
          bool pre, bool post)
{
    bool ok;
    *addr = (app_pc) dr_get_proc_address(mod->handle, name);
    CHECK(*addr != NULL, "cannot find lib export");
    ok = drwrap_wrap(*addr, pre ? wrap_pre : NULL, post ? wrap_post : NULL);
    CHECK(ok, "wrap failed");
    CHECK(drwrap_is_wrapped(*addr, pre ? wrap_pre : NULL, post ? wrap_post : NULL),
          "drwrap_is_wrapped query failed");
}
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 void
module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    app_pc towrap = (app_pc)dr_get_proc_address(mod->handle, "SSL_write");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_write, NULL);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap SSL_write\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "SSL_read");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_read, wrap_post_SSL_read);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap SSL_read\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "gnutls_record_send");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_write, NULL);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap gnutls_record_send\n");
            DR_ASSERT(ok);
        }
    }

    towrap = (app_pc)dr_get_proc_address(mod->handle, "gnutls_record_recv");
    if (towrap != NULL) {
        bool ok = drwrap_wrap(towrap, wrap_pre_SSL_read, wrap_post_SSL_read);
        if (!ok) {
            dr_fprintf(STDERR, "Couldn’t wrap gnutls_record_recv\n");
            DR_ASSERT(ok);
        }
    }
}
Ejemplo n.º 11
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.º 12
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.º 13
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.º 14
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);
}
Ejemplo n.º 15
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.º 16
0
static
void module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    app_pc towrap = (app_pc)
        dr_get_proc_address(mod->start, IF_WINDOWS_ELSE("HeapAlloc", "malloc"));
    if (towrap != NULL) {
#ifdef SHOW_RESULTS
        bool ok =
#endif
            drwrap_wrap(towrap, wrap_pre, wrap_post);
#ifdef SHOW_RESULTS
        if (ok)
            dr_fprintf(STDERR, "<wrapped HeapAlloc @"PFX"\n", towrap);
        else {
            /* We expect this w/ forwarded exports (e.g., on win7 both
             * kernel32!HeapAlloc and kernelbase!HeapAlloc forward to
             * the same routine in ntdll.dll)
             */
            dr_fprintf(STDERR, "<FAILED to wrap HeapAlloc @"PFX": already wrapped?\n",
                       towrap);
        }
#endif
    }
}
Ejemplo n.º 17
0
static void
module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
{
    if (strstr(dr_module_preferred_name(mod),
               "client.drwrap-test.appdll.") != NULL) {
        bool ok;
        instr_t inst;
        app_pc init_pc, pc, next_pc;

        load_count++;
        if (load_count == 2) {
            /* test no-frills */
            drwrap_set_global_flags(DRWRAP_NO_FRILLS);
        }

        addr_replace = (app_pc) dr_get_proc_address(mod->handle, "replaceme");
        CHECK(addr_replace != NULL, "cannot find lib export");
        ok = drwrap_replace(addr_replace, (app_pc) replacewith, false);
        CHECK(ok, "replace failed");

        addr_replace2 = (app_pc) dr_get_proc_address(mod->handle, "replaceme2");
        CHECK(addr_replace2 != NULL, "cannot find lib export");
        ok = drwrap_replace_native(addr_replace2, (app_pc) replacewith2, true/*at entry*/,
                                   0, (void *)(ptr_int_t)DRWRAP_NATIVE_PARAM, false);
        CHECK(ok, "replace_native failed");

        init_pc = (app_pc) dr_get_proc_address(mod->handle, "replace_callsite");
        CHECK(init_pc != NULL, "cannot find lib export");
        /* Find callsite: we assume we'll linearly hit a ret.  We take final call
         * to skip any PIC call.
         */
        instr_init(drcontext, &inst);
        pc = init_pc;
        do {
            instr_reset(drcontext, &inst);
            next_pc = decode(drcontext, pc, &inst);
            if (!instr_valid(&inst))
                break;
            /* if initial jmp, follow it to handle ILT-indirection */
            if (pc == init_pc && instr_is_ubr(&inst))
                next_pc = opnd_get_pc(instr_get_target(&inst));
            else if (instr_is_call(&inst))
                addr_replace_callsite = pc;
            pc = next_pc;
        } while (instr_valid(&inst) && !instr_is_return(&inst));
        CHECK(addr_replace_callsite != NULL, "cannot find lib export");
        ok = drwrap_replace_native(addr_replace_callsite, (app_pc) replace_callsite,
                                   false/*!at entry*/, 0,
                                   (void *)(ptr_int_t)DRWRAP_NATIVE_PARAM, false);
        CHECK(ok, "replace_native failed");
        instr_free(drcontext, &inst);

        wrap_addr(&addr_level0, "level0", mod, true, true);
        wrap_addr(&addr_level1, "level1", mod, true, true);
        wrap_addr(&addr_level2, "level2", mod, true, true);
        wrap_addr(&addr_tailcall, "makes_tailcall", mod, true, true);
        wrap_addr(&addr_skipme, "skipme", mod, true, true);
        wrap_addr(&addr_repeat, "repeatme", mod, true, true);
        wrap_addr(&addr_preonly, "preonly", mod, true, false);
        wrap_addr(&addr_postonly, "postonly", mod, false, true);
        wrap_addr(&addr_runlots, "runlots", mod, false, true);

        /* test longjmp */
        wrap_unwindtest_addr(&addr_long0, "long0", mod);
        wrap_unwindtest_addr(&addr_long1, "long1", mod);
        wrap_unwindtest_addr(&addr_long2, "long2", mod);
        wrap_unwindtest_addr(&addr_long3, "long3", mod);
        wrap_unwindtest_addr(&addr_longdone, "longdone", mod);
        drmgr_set_tls_field(drcontext, tls_idx, (void *)(ptr_uint_t)0);
#ifdef WINDOWS
        /* test SEH */
        /* we can't do this test for no-frills b/c only one wrap per addr */
        if (load_count == 1) {
            ok = drwrap_wrap_ex(addr_long0, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long1, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long2, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_long3, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
            ok = drwrap_wrap_ex(addr_longdone, wrap_unwindtest_seh_pre,
                                wrap_unwindtest_seh_post,
                                NULL, DRWRAP_UNWIND_ON_EXCEPTION);
            CHECK(ok, "wrap failed");
        }
#endif
        /* test leaner wrapping */
        if (load_count == 2)
            drwrap_set_global_flags(DRWRAP_NO_FRILLS | DRWRAP_FAST_CLEANCALLS);
        wrap_addr(&addr_skip_flags, "skip_flags", mod, true, false);
    }
}