static void wrap_post(void *wrapcxt, void *user_data) { bool ok; CHECK(wrapcxt != NULL, "invalid arg"); if (drwrap_get_func(wrapcxt) == addr_level0) { dr_fprintf(STDERR, " <post-level0>\n"); /* not preserved for no-frills */ CHECK(load_count == 2 || user_data == (void *)99, "user_data not preserved"); CHECK(drwrap_get_retval(wrapcxt) == (void *) 42, "get_retval error"); } else if (drwrap_get_func(wrapcxt) == addr_level1) { dr_fprintf(STDERR, " <post-level1>\n"); ok = drwrap_set_retval(wrapcxt, (void *) -4); CHECK(ok, "set_retval error"); } else if (drwrap_get_func(wrapcxt) == addr_tailcall) { dr_fprintf(STDERR, " <post-makes_tailcall>\n"); } else if (drwrap_get_func(wrapcxt) == addr_level2) { dr_fprintf(STDERR, " <post-level2>\n"); } else if (drwrap_get_func(wrapcxt) == addr_skipme) { CHECK(false, "should have skipped!"); } else if (drwrap_get_func(wrapcxt) == addr_repeat) { dr_fprintf(STDERR, " <post-repeat#%d>\n", repeated ? 2 : 1); if (!repeated) { dr_mcontext_t *mc = drwrap_get_mcontext(wrapcxt); mc->pc = addr_repeat; mc->xsp = repeat_xsp; #ifdef ARM mc->lr = repeat_link; #endif CHECK(drwrap_redirect_execution(wrapcxt) == DREXT_SUCCESS, "redirect rejected"); CHECK(drwrap_redirect_execution(wrapcxt) != DREXT_SUCCESS, "allowed duplicate redirect"); } repeated = !repeated; } else if (drwrap_get_func(wrapcxt) == addr_postonly) { dr_fprintf(STDERR, " <post-postonly>\n"); drwrap_unwrap(addr_skipme, wrap_pre, wrap_post); CHECK(!drwrap_is_wrapped(addr_skipme, wrap_pre, wrap_post), "drwrap_is_wrapped query failed"); drwrap_unwrap(addr_postonly, NULL, wrap_post); CHECK(!drwrap_is_wrapped(addr_postonly, NULL, wrap_post), "drwrap_is_wrapped query failed"); drwrap_unwrap(addr_runlots, NULL, wrap_post); CHECK(!drwrap_is_wrapped(addr_runlots, NULL, wrap_post), "drwrap_is_wrapped query failed"); } else if (drwrap_get_func(wrapcxt) == addr_runlots) { dr_fprintf(STDERR, " <post-runlots>\n"); } else CHECK(false, "invalid wrap"); }
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 } }
DR_EXPORT drmf_status_t drfuzz_unfuzz_target(generic_func_t func_pc) { drmf_status_t res = DRMF_SUCCESS; fuzz_pass_context_t *fp = drfuzz_get_fuzzcxt(); pass_target_t *live_target = lookup_live_target(fp, (app_pc) func_pc); fuzz_target_t *target = hashtable_lookup(&fuzz_target_htable, func_pc); if (target == NULL) return DRMF_ERROR_INVALID_PARAMETER; if (live_target != NULL) { /* XXX i#1734: ideally we would check all threads, or flag the target as live */ DRFUZZ_ERROR("Attempt to unfuzz a live fuzz target\n"); return DRMF_ERROR; /* cannot unfuzz the target in this state */ } if (!hashtable_remove(&fuzz_target_htable, func_pc)) { DRFUZZ_ERROR("failed to remove "PIFX" from the fuzz target hashtable\n", func_pc); res = DRMF_ERROR; /* Missing entry does not prevent unfuzzing, */ free_fuzz_target(target); /* but at least free it. */ } if (!drwrap_unwrap((app_pc) func_pc, pre_fuzz_handler, post_fuzz_handler)) { DRFUZZ_ERROR("failed to unwrap the fuzz target "PIFX" via drwrap_unwrap\n", func_pc); res = DRMF_ERROR; } return res; }
/** Deletes wrapper context and removes corresponding wrapper. */ static void free_wrap( void* rawWrap ) { struct wrap* wrap = ( struct wrap* )rawWrap; if( !drwrap_unwrap( wrap->address, &wrapperPre, NULL ) ) { dr_printf( "drwrap_unwrap(%p) failed\n", (void*)wrap->address ); exit( 1 ); } dr_global_free( wrap, sizeof( struct wrap ) ); }
static void unwrap_unwindtest_addr(app_pc addr, const char *name, const module_data_t *mod) { bool ok; ok = drwrap_unwrap(addr, wrap_unwindtest_pre, wrap_unwindtest_post); CHECK(ok, "unwrap failed"); CHECK(!drwrap_is_wrapped(addr, wrap_unwindtest_pre, wrap_unwindtest_post), "drwrap_is_wrapped query failed"); }
static void unwrap_addr(app_pc addr, const char *name, const module_data_t *mod, bool pre, bool post) { bool ok; ok = drwrap_unwrap(addr, pre ? wrap_pre : NULL, post ? wrap_post : NULL); CHECK(ok, "unwrap failed"); CHECK(!drwrap_is_wrapped(addr, pre ? wrap_pre : NULL, post ? wrap_post : NULL), "drwrap_is_wrapped query failed"); }