Пример #1
0
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");
}
Пример #2
0
static void
wrap_unwindtest_pre(void *wrapcxt, OUT void **user_data)
{
    if (drwrap_get_func(wrapcxt) != addr_longdone) {
        void *drcontext = dr_get_current_drcontext();
        ptr_uint_t val = (ptr_uint_t) drmgr_get_tls_field(drcontext, tls_idx);
        dr_fprintf(STDERR, "  <pre-long%d>\n", val);
        /* increment per level of regular calls on way up */
        val++;
        drmgr_set_tls_field(drcontext, tls_idx, (void *)val);
    }
}
Пример #3
0
/** Wrapper pre-callback. */
static void wrapperPre( void* ctx, void** data ) {
  dr_mutex_lock( outMutex );

  uint64 currentTimeMillis = dr_get_milliseconds();
  if( currentTimeMillis > nextTimestampMillis ) {
    dr_fprintf( outFile, "T 0x%.16llx\n", currentTimeMillis );
    nextTimestampMillis = currentTimeMillis + timestampIntervalMillis;
  }

  dr_fprintf( outFile, "X %p %p\n", (void*)drwrap_get_func( ctx ),
                                    drwrap_get_arg( ctx, 0 ) );
  dr_mutex_unlock( outMutex );
}
Пример #4
0
static void
wrap_unwindtest_post(void *wrapcxt, void *user_data)
{
    void *drcontext = dr_get_current_drcontext();
    ptr_uint_t val = (ptr_uint_t) drmgr_get_tls_field(drcontext, tls_idx);
    if (drwrap_get_func(wrapcxt) == addr_longdone) {
        /* ensure our post-calls were all called and we got back to 0 */
        CHECK(val == 0, "post-calls were bypassed");
    } else {
        /* decrement on way down */
        val--;
        dr_fprintf(STDERR, "  <post-long%d%s>\n", val,
                   wrapcxt == NULL ? " abnormal" : "");
        drmgr_set_tls_field(drcontext, tls_idx, (void *)val);
    }
}
Пример #5
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");
}
Пример #6
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;
}