Пример #1
0
DR_EXPORT drmf_status_t
drfuzz_set_arg(void *fuzzcxt, int arg, void *val)
{
    fuzz_pass_context_t *fp = (fuzz_pass_context_t *) fuzzcxt;

    if (drwrap_set_arg(fp->live_targets->wrapcxt, arg, val))
        return DRMF_SUCCESS;
    else
        return DRMF_ERROR;
}
Пример #2
0
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");
}
Пример #3
0
static void
pre_fuzz_handler(void *wrapcxt, INOUT void **user_data)
{
    void *dcontext = drwrap_get_drcontext(wrapcxt);
    app_pc target_to_fuzz = drwrap_get_func(wrapcxt);
    fuzz_target_t *target = hashtable_lookup(&fuzz_target_htable, target_to_fuzz);
    fuzz_pass_context_t *fp = (fuzz_pass_context_t *) drmgr_get_tls_field(dcontext,
                                                                          tls_idx_fuzzer);
    bool is_target_entry = false;
    pass_target_t *live = NULL;
    dr_mcontext_t *mc;
    uint i;

    ASSERT(target != NULL, "pre_fuzz must be associated with a fuzz target");

    DRFUZZ_LOG(3, "pre_fuzz() for target "PFX" with %d args\n",
               target_to_fuzz, target->arg_count);

    /* XXX i#1734: this heuristic may be incorrect when a handled fault occurs during
     * the very last iteration of the last fuzz pass on any thread.
     */
    clear_thread_state(fp);

    /* Stop the target iterator that was captured at the last critical fault, because
     * the fact that we are in pre-fuzz implies the fault was handled and doesn't matter.
     */
    if (fp->thread_state->targets != NULL)
        drfuzz_target_iterator_stop(fp->thread_state->targets);

    /* XXX: assumes the fuzz target is never called recursively */
    if (fp->live_targets != NULL && fp->live_targets->target->func_pc == target_to_fuzz) {
        live = fp->live_targets; /* this is a repetition of the last live target */
    } else {
        is_target_entry = true; /* this is a new invocation of a target */
        live = activate_cached_target(fp, target_to_fuzz); /* check the cache */
        if (live == NULL)
            live = create_pass_target(dcontext, wrapcxt);
        live->next = fp->live_targets; /* push to live stack */
        fp->live_targets = live;
    }

    /* required by dr_redirect_execution() (avoids having to merge the mcontext) */
    mc = drwrap_get_mcontext_ex(wrapcxt, DR_MC_ALL); /* XXX: can we relax this? */

    if (is_target_entry) {
        live->xsp = mc->xsp;
#ifdef X86
        live->unclobber.retaddr_loc = (reg_t *) mc->xsp; /* see retaddr_unclobber_t */
#endif
        live->unclobber.retaddr = (reg_t) drwrap_get_retaddr(wrapcxt);
        DRFUZZ_LOG(4, "fuzz target "PFX": saving stack pointer "PFX"\n",
                   target_to_fuzz, mc->xsp);
        for (i = 0; i < target->arg_count; i++) { /* store the original arg values */
            live->original_args[i] = (reg_t) drwrap_get_arg(wrapcxt, i);
            /* copy original args to current args for the first iteration of the fuzz */
            live->current_args[i] = live->original_args[i];
            DRFUZZ_LOG(4, "fuzz target "PFX": saving original arg #%d: "PFX"\n",
                       target_to_fuzz, i, live->original_args[i]);
        }
    }

    /* restore the original arg values before calling the client */
    for (i = 0; i < target->arg_count; i++) {
        DRFUZZ_LOG(4, "fuzz target "PFX": restoring original arg #%d: "PFX"\n",
                   target_to_fuzz, i, live->original_args[i]);
        drwrap_set_arg(wrapcxt, i, (void *) live->original_args[i]);
    }

#ifdef ARM
    mc->lr = live->unclobber.retaddr; /* restore retaddr to link register */
#else /* X86 */
    *live->unclobber.retaddr_loc = live->unclobber.retaddr; /* restore retaddr to stack */
#endif

    target->pre_fuzz_cb(fp, (generic_func_t) target_to_fuzz, mc);
    drwrap_set_mcontext(wrapcxt);
    for (i = 0; i < target->arg_count; i++)
        live->current_args[i] = (reg_t) drwrap_get_arg(wrapcxt, i);

    *user_data = fp;
}