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 wrap_pre(void *wrapcxt, OUT void **user_data) { bool ok; CHECK(wrapcxt != NULL && user_data != NULL, "invalid arg"); if (drwrap_get_func(wrapcxt) == addr_skip_flags) { CHECK(drwrap_get_arg(wrapcxt, 0) == (void *) 1, "get_arg wrong"); CHECK(drwrap_get_arg(wrapcxt, 1) == (void *) 2, "get_arg wrong"); } else if (drwrap_get_func(wrapcxt) == addr_level0) { dr_fprintf(STDERR, " <pre-level0>\n"); CHECK(drwrap_get_arg(wrapcxt, 0) == (void *) 37, "get_arg wrong"); ok = drwrap_set_arg(wrapcxt, 0, (void *) 42); CHECK(ok, "set_arg error"); *user_data = (void *) 99; } else if (drwrap_get_func(wrapcxt) == addr_level1) { dr_fprintf(STDERR, " <pre-level1>\n"); ok = drwrap_set_arg(wrapcxt, 1, (void *) 1111); CHECK(ok, "set_arg error"); } else if (drwrap_get_func(wrapcxt) == addr_tailcall) { dr_fprintf(STDERR, " <pre-makes_tailcall>\n"); } else if (drwrap_get_func(wrapcxt) == addr_level2) { dr_fprintf(STDERR, " <pre-level2>\n"); } else if (drwrap_get_func(wrapcxt) == addr_skipme) { dr_fprintf(STDERR, " <pre-skipme>\n"); drwrap_skip_call(wrapcxt, (void *) 7, 0); } else if (drwrap_get_func(wrapcxt) == addr_repeat) { dr_mcontext_t *mc = drwrap_get_mcontext(wrapcxt); dr_fprintf(STDERR, " <pre-repeat#%d>\n", repeated ? 2 : 1); repeat_xsp = mc->xsp; #ifdef ARM repeat_link = mc->lr; #endif if (repeated) /* test changing the arg value on the second pass */ drwrap_set_arg(wrapcxt, 0, (void *)2); CHECK(drwrap_redirect_execution(NULL) != DREXT_SUCCESS, "allowed redirect with NULL wrapcxt"); CHECK(drwrap_redirect_execution(wrapcxt) != DREXT_SUCCESS, "allowed redirect in pre-wrap"); } else if (drwrap_get_func(wrapcxt) == addr_preonly) { dr_fprintf(STDERR, " <pre-preonly>\n"); } else CHECK(false, "invalid wrap"); }
static void post_fuzz_handler(void *wrapcxt, void *user_data) { fuzz_pass_context_t *fp = (fuzz_pass_context_t *) user_data; pass_target_t *live = fp->live_targets; bool repeat = live->target->post_fuzz_cb(fp, (generic_func_t) live->target->func_pc); DRFUZZ_LOG(3, "post_fuzz() for target "PFX" (%s)\n", live->target->func_pc, repeat ? "repeat" : "stop"); if (repeat) { dr_mcontext_t *mc = drwrap_get_mcontext(wrapcxt); IF_DEBUG(drext_status_t redirect_status;); /* restore the original xsp before repeating */ DRFUZZ_LOG(4, "fuzz target "PFX": restoring xsp to "PFX"\n", live->target->func_pc, live->xsp); mc->xsp = live->xsp; mc->pc = live->target->func_pc; IF_DEBUG(redirect_status =) drwrap_redirect_execution(wrapcxt); DRFUZZ_LOG(4, "fuzz target "PFX" requesting redirect to self entry; result: %d\n", live->target->func_pc, live->target->func_pc, redirect_status); } else { /* the current target is finished, so pop from live stack and cache it */