Example #1
0
static void
module_unload_event(void *drcontext, const module_data_t *mod)
{
    if (strstr(dr_module_preferred_name(mod),
               "client.drwrap-test.appdll.") != NULL) {
        bool ok;
        ok = drwrap_replace(addr_replace, NULL, true);
        CHECK(ok, "un-replace failed");
        ok = drwrap_replace_native(addr_replace2, NULL, true, 0, NULL, true);
        CHECK(ok, "un-replace_native failed");
        ok = drwrap_replace_native(addr_replace_callsite, NULL, false, 0, NULL, true);
        CHECK(ok, "un-replace_native failed");

        unwrap_addr(addr_skip_flags, "skip_flags", mod, true, false);
        unwrap_addr(addr_level0, "level0", mod, true, true);
        unwrap_addr(addr_level1, "level1", mod, true, true);
        unwrap_addr(addr_level2, "level2", mod, true, true);
        unwrap_addr(addr_tailcall, "makes_tailcall", mod, true, true);
        unwrap_addr(addr_preonly, "preonly", mod, true, false);
        /* skipme, postonly, and runlots were already unwrapped */

        /* test longjmp */
        unwrap_unwindtest_addr(addr_long0, "long0", mod);
        unwrap_unwindtest_addr(addr_long1, "long1", mod);
        unwrap_unwindtest_addr(addr_long2, "long2", mod);
        unwrap_unwindtest_addr(addr_long3, "long3", mod);
        unwrap_unwindtest_addr(addr_longdone, "longdone", mod);
        drmgr_set_tls_field(drcontext, tls_idx, (void *)(ptr_uint_t)0);
#ifdef WINDOWS
        /* test SEH */
        if (load_count == 1) {
            ok = drwrap_unwrap(addr_long0, wrap_unwindtest_seh_pre,
                               wrap_unwindtest_seh_post);
            CHECK(ok, "unwrap failed");
            ok = drwrap_unwrap(addr_long1, wrap_unwindtest_seh_pre,
                               wrap_unwindtest_seh_post);
            CHECK(ok, "unwrap failed");
            ok = drwrap_unwrap(addr_long2, wrap_unwindtest_seh_pre,
                               wrap_unwindtest_seh_post);
            CHECK(ok, "unwrap failed");
            ok = drwrap_unwrap(addr_long3, wrap_unwindtest_seh_pre,
                               wrap_unwindtest_seh_post);
            CHECK(ok, "unwrap failed");
            ok = drwrap_unwrap(addr_longdone, wrap_unwindtest_seh_pre,
                               wrap_unwindtest_seh_post);
        }
        CHECK(ok, "unwrap failed");
#endif
    }
}
Example #2
0
void
replace_init(void)
{
    if (options.replace_libc) {
        app_pc addr;
        int i;
        char *s;

        /* replace_module_load will be called for each module to populate the hashtable */
        ASSERT(PAGE_START(get_function_entry((app_pc)replace_memset)) ==
               PAGE_START(get_function_entry((app_pc)replace_memmove)),
               "replace_ routines taking up more than one page");
        ASSERT(sizeof(int) >= sizeof(wchar_t),
               "wchar_t replacement functions assume wchar_t is not larger than int");
        replace_routine_start = (app_pc)
            PAGE_START(get_function_entry((app_pc)replace_memset));
        
        /* PR 485412: we support passing in addresses of libc routines to
         * be replaced if statically included in the executable and if
         * we have no symbols available
         */
        s = options.libc_addrs;
        i = 0;
        while (s != NULL) {
            if (sscanf(s, PIFX, (ptr_uint_t *)&addr) == 1 ||
                /* we save option space by having no 0x prefix but assuming hex */
                sscanf(s, PIFMT, (ptr_uint_t *)&addr) == 1) {
                LOG(2, "replacing %s @"PFX" in executable from options\n",
                    replace_routine_name[i], addr);
                if (!drwrap_replace((app_pc)addr, (app_pc)replace_routine_addr[i], false))
                    ASSERT(false, "failed to replace");
            }
            s = strchr(s, ',');
            if (s != NULL)
                s++;
            i++;
        }

#ifdef USE_DRSYMS
        hashtable_init(&replace_name_table, REPLACE_NAME_TABLE_HASH_BITS, HASH_STRING,
                       false/*!strdup*/);
        for (i=0; i<REPLACE_NUM; i++) {
            hashtable_add(&replace_name_table, (void *) replace_routine_name[i],
                          (void *)(ptr_int_t)(i+1)/*since 0 is "not found"*/);
        }
#endif
    }
}
Example #3
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);
    }
}