Пример #1
0
static void at_not_taken(app_pc src, app_pc fall)
{
    int app_errno;
    dr_mcontext_t mcontext;
    void *drcontext = dr_get_current_drcontext();

    /* 
     * Record the fact that we've seen the fallthrough case.
     */
    elem_t *elem = lookup(table, src);
    ASSERT(elem != NULL);
    elem->state |= CBR_NOT_TAKEN;

    dr_fprintf(STDERR, "cbr not taken\n");

    /* 
     * Remove the bb from the cache so it will be re-built the next
     * time it is executed.  Since the flush will remove the fragment
     * we're already in, redirect execution to the target.
     */
    dr_flush_region(src, 1);
    dr_get_mcontext(drcontext, &mcontext, &app_errno);
    mcontext.xip = fall;
    dr_redirect_execution(&mcontext, app_errno);
}
Пример #2
0
/** Records given fragment. */
void record_frag(void* ctx, instrlist_t* frag, frag_id_t id) {
  bool flushed;
  struct trace_buffer_t* tb;

  tb = dr_get_tls_field(ctx);
  tb_tlv_complete(tb);
  for(flushed = false; ; tb_flush(tb), flushed = true) {
    struct frag_t* frag_data;
    void* current;

    tb_tlv(tb, TYPE_FRAG);
    frag_data = tb->current;
    current = record_frag_instrs(ctx, frag, &frag_data->chunks, tb_end(tb));
    if(current) {
      frag_data->id = id;
      tb->current = current;
      tb_tlv_complete(tb);
      tb_tlv(tb, TYPE_TRACE);
      break;
    } else {
      if(flushed) {
        dr_fprintf(STDERR, "fatal: not enough buffer space after flush\n");
        dr_exit_process(1);
      }
      tb_tlv_cancel(tb);
    }
  }
}
Пример #3
0
dr_emit_flags_t handle_bb(void* ctx,
                          void* tag,
                          instrlist_t* bb,
                          bool for_trace,
                          bool translating) {
  bool new_frag;
  bool instrument;

#ifdef TRACE_DEBUG
  dr_fprintf(STDERR,
             "debug: handle_bb(tag=%p, for_trace=%u, translating=%u)\n",
             tag,
             for_trace,
             translating);
#endif

  check_ctx(ctx, "handle_bb");

  new_frag = true;
  instrument = true;
  if(for_trace) {
    // Traces are instrumented separately, we only need to increment counter.
    new_frag = false;
    instrument = false;
  }
  if(translating) {
    // Reuse existing fragment when translating.
    new_frag = false;
  }

  handle_frag(ctx, tag, bb, new_frag, instrument, 0);

  return DR_EMIT_DEFAULT;
}
Пример #4
0
DR_EXPORT void
dr_init(client_id_t id)
{
    dr_set_client_name("DynamoRIO Sample Client 'instrcalls'",
                       "http://dynamorio.org/issues");
    my_id = id;
    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, LOG_ALL, 1, "Client 'instrcalls' initializing\n");
    /* also give notification to stderr */
#ifdef SHOW_RESULTS
    if (dr_is_notify_on()) {
# ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called in dr_init(). */
        dr_enable_console_printing();
# endif
        dr_fprintf(STDERR, "Client instrcalls is running\n");
    }
#endif
    dr_register_exit_event(event_exit);
    dr_register_bb_event(event_basic_block);
    dr_register_thread_init_event(event_thread_init);
    dr_register_thread_exit_event(event_thread_exit);
#ifdef SHOW_SYMBOLS
    if (drsym_init(0) != DRSYM_SUCCESS) {
        dr_log(NULL, LOG_ALL, 1, "WARNING: unable to initialize symbol translation\n");
    }
#endif
}
Пример #5
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    module_data_t *appmod;
    dr_set_client_name("DynamoRIO Sample Client 'modxfer_app2lib'",
                       "http://dynamorio.org/issues");
    appmod = dr_get_main_module();
    DR_ASSERT(appmod != NULL);
    app_base = appmod->start;
    app_end  = appmod->end;
    dr_free_module_data(appmod);

    /* register events */
    dr_register_exit_event(event_exit);
    dr_register_bb_event(event_basic_block);

    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, LOG_ALL, 1, "Client 'modxfer_app2lib' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
# ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called at init. */
        dr_enable_console_printing();
# endif
        dr_fprintf(STDERR, "Client modxfer_app2lib is running\n");
    }
#endif
}
Пример #6
0
DR_EXPORT void 
dr_init(client_id_t id)
{
    dr_register_exit_event(event_exit);
    dr_register_trace_event(event_trace);
    /* this optimization is only worthwhile on the Pentium 4, where
     * an add of 1 is faster than an inc
     */
    enable = (proc_get_family() == FAMILY_PENTIUM_4);
    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, LOG_ALL, 1, "Client 'inc2add' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
# ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called in dr_init(). */
        dr_enable_console_printing();
# endif
        dr_fprintf(STDERR, "Client inc2add is running\n");
    }
#endif
    /* initialize our global variables */
    num_examined = 0;
    num_converted = 0;
}
Пример #7
0
static
void thread_exit_event2(void *drcontext)
{
    inc_count_second(EVENT_THREAD_EXIT_2);
    if (!dr_unregister_thread_exit_event(thread_exit_event2))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #8
0
static
void delete_event1(void *dcontext, void *tag)
{
    inc_count_first(EVENT_DELETE_1, EVENT_DELETE_2);
    if (!dr_unregister_delete_event(delete_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #9
0
static void
bb_table_print(void *drcontext, per_thread_t *data)
{
    ASSERT(data != NULL, "data must not be NULL");
    if (data->log == INVALID_FILE) {
        ASSERT(false, "invalid log file");
        return;
    }
    dr_fprintf(data->log, "BB Table: %u bbs\n",
               drtable_num_entries(data->bb_table));
    if (TEST(DRCOVLIB_DUMP_AS_TEXT, options.flags)) {
        dr_fprintf(data->log, "module id, start, size:\n");
        drtable_iterate(data->bb_table, data, bb_table_entry_print);
    } else
        drtable_dump_entries(data->bb_table, data->log);
}
Пример #10
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    drreg_options_t ops = { sizeof(ops), 2 /*max slots needed*/, false };
    dr_set_client_name("DynamoRIO Sample Client 'countcalls'",
                       "http://dynamorio.org/issues");
    if (!drmgr_init() || drreg_init(&ops) != DRREG_SUCCESS)
        DR_ASSERT(false);
    /* register events */
    dr_register_exit_event(event_exit);
    drmgr_register_thread_init_event(event_thread_init);
    drmgr_register_thread_exit_event(event_thread_exit);
    drmgr_register_bb_instrumentation_event(NULL, event_instruction, NULL);
    tls_idx = drmgr_register_tls_field();

    /* make it easy to tell, by looking at log file, which client executed */
    dr_log(NULL, DR_LOG_ALL, 1, "Client 'countcalls' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
#    ifdef WINDOWS
        /* ask for best-effort printing to cmd window.  must be called at init. */
        dr_enable_console_printing();
#    endif
        dr_fprintf(STDERR, "Client countcalls is running\n");
    }
#endif
}
Пример #11
0
static void
wrap_pre_SSL_write(void *wrapcxt, OUT void **user_data)
{
    /* int SSL_write(SSL *ssl, const void *buf, int num);
     *
     * ssize_t gnutls_record_send(gnutls_session_t session,
     *                            const void * data, size_t sizeofdata);
     */

    void *ssl = (void *)drwrap_get_arg(wrapcxt, 0);
    unsigned char *buf = (unsigned char *)drwrap_get_arg(wrapcxt, 1);
    size_t sz = (size_t)drwrap_get_arg(wrapcxt, 2);

    /* By generating unique filenames (per SSL context), we are able to
     * simplify logging of SSL traffic (no file locking is required).
     */
    char filename[MAXIMUM_PATH] = { 0 };
    dr_snprintf(filename, BUFFER_SIZE_ELEMENTS(filename), "trace-%x.write", ssl);
    NULL_TERMINATE_BUFFER(filename);
    FILE *fp = fopen(filename, "ab+");
    /* Error handling of logging operations isn't critical - in fact, we don't
     * even know what to do in such error conditions, so we simply return!
     */
    if (!fp) {
        dr_fprintf(STDERR, "Couldn’t open the output file %s\n", filename);
        return;
    }

    /* We assume that SSL_write always succeeds and writes the whole buffer. */
    fwrite(buf, 1, sz, fp);
    fclose(fp);
}
Пример #12
0
static void
event_exit(void)
{
    dr_mutex_destroy(syslock);
    CHECK(checked_tls_from_cache, "failed to hit clean call");
    CHECK(checked_cls_from_cache, "failed to hit clean call");
    CHECK(checked_tls_write_from_cache, "failed to hit clean call");
    CHECK(checked_cls_write_from_cache, "failed to hit clean call");
    CHECK(one_time_exec == 1, "failed to execute one-time event");

    if (!drmgr_unregister_bb_instrumentation_event(event_bb_analysis))
        CHECK(false, "drmgr unregistration failed");

    if (!drmgr_unregister_bb_instrumentation_ex_event(event_bb4_app2app,
                                                      event_bb4_analysis,
                                                      event_bb4_insert,
                                                      event_bb4_instru2instru))
        CHECK(false, "drmgr unregistration failed");

    if (!drmgr_unregister_cls_field(event_thread_context_init,
                                    event_thread_context_exit, cls_idx))
        CHECK(false, "drmgr unregistration failed");

    drmgr_exit();
    dr_fprintf(STDERR, "all done\n");
}
Пример #13
0
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    dr_set_client_name("DynamoRIO Sample Client 'inline'",
                       "http://dynamorio.org/issues");
    if (!drmgr_init())
        DR_ASSERT(false);

    hashtable_init_ex(&head_table, HASH_BITS, HASH_INTPTR, false/*!strdup*/,
                      false/*synchronization is external*/,
                      free_trace_head_entry, NULL, NULL);

    dr_register_exit_event(event_exit);
    if (!drmgr_register_bb_instrumentation_event(event_analyze_bb, NULL, NULL))
        DR_ASSERT(false);
    dr_register_delete_event(event_fragment_deleted);
    dr_register_end_trace_event(query_end_trace);

    /* Make it easy to tell from the log file which client executed. */
    dr_log(NULL, DR_LOG_ALL, 1, "Client 'inline' initializing\n");
#ifdef SHOW_RESULTS
    /* also give notification to stderr */
    if (dr_is_notify_on()) {
# ifdef WINDOWS
        /* Ask for best-effort printing to cmd window.  Must be called at init. */
        dr_enable_console_printing();
# endif
        dr_fprintf(STDERR, "Client inline is running\n");
    }
#endif
}
Пример #14
0
static void
event_exit(void)
{
    /* ensure our file was not closed by the app */
    if (!dr_file_seek(file, 0, DR_SEEK_SET))
        dr_fprintf(STDERR, "seek error in exit event\n");
    dr_close_file(file);
    dr_fprintf(STDERR, "file separation check\n");

    /* i#1213: test float i/o.
     * Technically we should save fpstate (for detach) but we're not bothering.
     */
    dr_fprintf(STDERR, "float i/o test: %6.5g\n", 3.1415916);

    dr_fprintf(STDERR, "done\n");
}
Пример #15
0
/*
 * Hardware division instructions are unlikely to run in time
 * independent of the data, so we log both their parameters.
 */
static void log_div(uint n, uint d, const char *loc)
{
    if (outfile == INVALID_FILE || logging_paused)
        return;
    dr_fprintf(outfile, "%s: divide %"PRIuMAX" / %"PRIuMAX"\n",
               loc, (uintmax_t)n, (uintmax_t)d);
}
Пример #16
0
DR_EXPORT
void dr_init(client_id_t id)
{
    client_id = id;
    dr_fprintf(STDERR, "thank you for testing the client interface\n");
    drmgr_init();
    cls_idx = drmgr_register_cls_field(event_thread_context_init,
                                       event_thread_context_exit);
    ASSERT(cls_idx != -1);
    dr_register_nudge_event(event_nudge, id);
    dr_register_filter_syscall_event(event_filter_syscall);
    drmgr_register_pre_syscall_event(event_pre_syscall);
    drmgr_register_post_syscall_event(event_post_syscall);
    dr_register_exit_event(event_exit);

#ifdef WINDOWS
    sysnum_CreateProcess = get_sysnum("NtCreateProcess");
    ASSERT(sysnum_CreateProcess != -1);
    /* not asserting on these since added later */
    sysnum_CreateProcessEx = get_sysnum("NtCreateProcessEx");
    sysnum_CreateUserProcess = get_sysnum("NtCreateUserProcess");
    sysnum_ResumeThread = get_sysnum("NtResumeThread");
    ASSERT(sysnum_ResumeThread != -1);
#endif
}
Пример #17
0
static
void module_load_event1(void *drcontext, const module_data_t *info, bool loaded)
{
    inc_count_first(EVENT_MODULE_LOAD_1, EVENT_MODULE_LOAD_2);
    if (!dr_unregister_module_load_event(module_load_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #18
0
DR_EXPORT
void dr_init(client_id_t id)
{
    module_data_t *data;
    dr_fprintf(STDERR, "thank you for testing the client interface\n");
    dr_register_bb_event(bb_event);
    data = dr_lookup_module_by_name("kernel32.dll");
    if (data != NULL) {
        exit_proc_addr = (void *)dr_get_proc_address(data->handle, "ExitProcess");
        if (exit_proc_addr == NULL)
            dr_fprintf(STDERR, "ERROR: unable to find kernel32!ExitProcess\n");
        dr_free_module_data(data);
    } else {
        dr_fprintf(STDERR, "ERROR: unable to find ntdll.dll\n");
    }
}
Пример #19
0
static
void module_unload_event2(void *drcontext, const module_data_t *info)
{
    inc_count_second(EVENT_MODULE_UNLOAD_2);
    if (!dr_unregister_module_unload_event(module_unload_event2))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #20
0
static
void thread_init_event1(void *drcontext)
{
    inc_count_first(EVENT_THREAD_INIT_1, EVENT_THREAD_INIT_2);
    if (!dr_unregister_thread_init_event(thread_init_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #21
0
static
void post_syscall_event2(void *drcontext, int sysnum)
{
    inc_count_second(EVENT_POST_SYSCALL_2);
    if (!dr_unregister_post_syscall_event(post_syscall_event2))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #22
0
static
void fork_init_event1(void *drcontext)
{
    inc_count_first(EVENT_FORK_INIT_1, EVENT_FORK_INIT_2);
    if (!dr_unregister_fork_init_event(fork_init_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
}
Пример #23
0
static
void decrement(void *tag)
{
    elem_t *elem;

    elem = find(tag);
    if (elem == NULL) {
        dr_fprintf(STDERR, "ERROR removing "PFX"\n", tag);
    }
    else {
        elem->count--;

        if (elem->count == 0) {
            if (head == elem) {
                head = elem->next;
            }
            if (tail == elem) {
                tail = elem->prev;
            }
            if (elem->next) {
                elem->next->prev = elem->prev;
            }
            if (elem->prev) {
                elem->prev->next = elem->next;
            }

            dr_global_free(elem, sizeof(elem_t));
        }
    }
}
Пример #24
0
void tb_flush(struct trace_buffer_t* tb) {
  size_t size;
  int64 pos;
  size_t written;
  void* aligned_current;

  tb_tlv_complete(tb);

  // Align current position to block boundary.
  aligned_current = aligned_block(tb->current);
  memset(tb->current, 'X', aligned_current - tb->current);
  tb->current = aligned_current;

  size = tb->current - (void*)&tb->block;
  if(size == sizeof(struct block_t)) {
    // Nothing to do.
    return;
  }
  tb->block.length = (uint32_t)size;
  tb->block.crc32 = 0;
  tb->block.crc32 = crc32((char*)&tb->block, size);

  // Write data.
  dr_mutex_lock(tb->mutex);
  pos = dr_file_tell(tb->file);
  if(pos == -1) {
    dr_fprintf(STDERR, "fatal: dr_file_tell() failed\n");
    dr_exit_process(1);
  }
  dr_fprintf(STDERR,
             "info: flushing tb=%p file-offset=%" PRId64 " size=%u"
             " tb-thread=0x%" PRIx64 " current-thread=0x%" PRIx64 "\n",
             tb,
             pos,
             (unsigned int)size,
             tb->block.thread_id,
             (uint64_t)dr_get_thread_id(dr_get_current_drcontext()));
  written = dr_write_file(tb->file, &tb->block, size);
  dr_mutex_unlock(tb->mutex);
  if(written != size) {
    dr_fprintf(STDERR, "fatal: dr_write_file() failed\n");
    dr_exit_process(1);
  }

  // Reset position.
  tb->current = tb + 1;
}
Пример #25
0
static void
exit_event(void)
{
    if (drfuzz_exit() != DRMF_SUCCESS)
        EXPECT(false, "drfuzz failed to exit");
    dr_fprintf(STDERR, "TEST PASSED\n");
    drmgr_exit();
}
Пример #26
0
static
bool filter_syscall_event2(void *drcontext, int sysnum)
{
    inc_count_second(EVENT_FILTER_SYSCALL_2);
    if (!dr_unregister_filter_syscall_event(filter_syscall_event2))
        dr_fprintf(STDERR, "unregister failed!\n");
    return true;
}
Пример #27
0
static
bool pre_syscall_event1(void *drcontext, int sysnum)
{
    inc_count_first(EVENT_PRE_SYSCALL_1, EVENT_PRE_SYSCALL_2);
    if (!dr_unregister_pre_syscall_event(pre_syscall_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
    return true;
}
Пример #28
0
static
dr_custom_trace_action_t end_trace_event2(void *dcontext, void *trace_tag, void *next_tag)
{
    inc_count_second(EVENT_END_TRACE_2);
    if (!dr_unregister_end_trace_event(end_trace_event2))
        dr_fprintf(STDERR, "unregister failed!\n");
    return CUSTOM_TRACE_DR_DECIDES;
}
Пример #29
0
static
dr_emit_flags_t bb_event(void* drcontext, void* tag, instrlist_t* bb, bool for_trace, bool translating)
{
    dr_fprintf(STDERR, "got BB event\n");
    dr_insert_clean_call(drcontext, bb, instrlist_first(bb),
                         (void *)unregister, false, 0);
    return DR_EMIT_DEFAULT;
}
Пример #30
0
static
dr_custom_trace_action_t end_trace_event1(void *dcontext, void *trace_tag, void *next_tag)
{
    inc_count_first(EVENT_END_TRACE_1, EVENT_END_TRACE_2);
    if (!dr_unregister_end_trace_event(end_trace_event1))
        dr_fprintf(STDERR, "unregister failed!\n");
    return 0;
}