DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { /* We need 2 reg slots beyond drreg's eflags slots => 3 slots */ drreg_options_t ops = { sizeof(ops), 3, false }; dr_set_client_name("DynamoRIO Sample Client 'memtrace'", "http://dynamorio.org/issues"); if (!drmgr_init() || drreg_init(&ops) != DRREG_SUCCESS || !drutil_init()) DR_ASSERT(false); /* register events */ dr_register_exit_event(event_exit); if (!drmgr_register_thread_init_event(event_thread_init) || !drmgr_register_thread_exit_event(event_thread_exit) || !drmgr_register_bb_app2app_event(event_bb_app2app, NULL) || !drmgr_register_bb_instrumentation_event(NULL /*analysis_func*/, event_app_instruction, NULL)) DR_ASSERT(false); client_id = id; mutex = dr_mutex_create(); tls_idx = drmgr_register_tls_field(); DR_ASSERT(tls_idx != -1); /* The TLS field provided by DR cannot be directly accessed from the code cache. * For better performance, we allocate raw TLS so that we can directly * access and update it with a single instruction. */ if (!dr_raw_tls_calloc(&tls_seg, &tls_offs, MEMTRACE_TLS_COUNT, 0)) DR_ASSERT(false); /* make it easy to tell, by looking at log file, which client executed */ dr_log(NULL, DR_LOG_ALL, 1, "Client 'memtrace' initializing\n"); }
DR_EXPORT void dr_init(client_id_t id) { drmgr_priority_t priority = {sizeof(priority), "drmgr-test", NULL, NULL, 0}; drmgr_priority_t priority4 = {sizeof(priority), "drmgr-test4", NULL, NULL, 0}; drmgr_priority_t sys_pri_A = {sizeof(priority), "drmgr-test-A", NULL, NULL, 10}; drmgr_priority_t sys_pri_B = {sizeof(priority), "drmgr-test-B", "drmgr-test-A", NULL, 5}; bool ok; drmgr_init(); dr_register_exit_event(event_exit); drmgr_register_thread_init_event(event_thread_init); drmgr_register_thread_exit_event(event_thread_exit); ok = drmgr_register_bb_instrumentation_event(event_bb_analysis, event_bb_insert, &priority); CHECK(ok, "drmgr register bb failed"); /* check register/unregister instrumentation_ex */ ok = drmgr_register_bb_instrumentation_ex_event(event_bb4_app2app, event_bb4_analysis, event_bb4_insert2, event_bb4_instru2instru, NULL); CHECK(ok, "drmgr_register_bb_instrumentation_ex_event failed"); ok = drmgr_unregister_bb_instrumentation_ex_event(event_bb4_app2app, event_bb4_analysis, event_bb4_insert2, event_bb4_instru2instru); CHECK(ok, "drmgr_unregister_bb_instrumentation_ex_event failed"); /* test data passing among all 4 phases */ ok = drmgr_register_bb_instrumentation_ex_event(event_bb4_app2app, event_bb4_analysis, event_bb4_insert, event_bb4_instru2instru, &priority4); tls_idx = drmgr_register_tls_field(); CHECK(tls_idx != -1, "drmgr_register_tls_field failed"); cls_idx = drmgr_register_cls_field(event_thread_context_init, event_thread_context_exit); CHECK(cls_idx != -1, "drmgr_register_tls_field failed"); dr_register_filter_syscall_event(event_filter_syscall); ok = drmgr_register_pre_syscall_event_ex(event_pre_sys_A, &sys_pri_A) && drmgr_register_pre_syscall_event_ex(event_pre_sys_B, &sys_pri_B); CHECK(ok, "drmgr register sys failed"); ok = drmgr_register_post_syscall_event_ex(event_post_sys_A, &sys_pri_A) && drmgr_register_post_syscall_event_ex(event_post_sys_B, &sys_pri_B); CHECK(ok, "drmgr register sys failed"); syslock = dr_mutex_create(); ok = drmgr_register_bb_app2app_event(one_time_bb_event, NULL); CHECK(ok, "drmgr app2app registration failed"); }
DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { drreg_options_t ops = { sizeof(ops), 4 /*max slots needed*/, false }; dr_set_client_name("DynamoRIO Sample Client 'memval'", "http://dynamorio.org/issues"); if (!drmgr_init() || !drutil_init() || !drx_init()) DR_ASSERT(false); if (drreg_init(&ops) != DRREG_SUCCESS) DR_ASSERT(false); /* register events */ dr_register_exit_event(event_exit); if (!drmgr_register_thread_init_event(event_thread_init) || !drmgr_register_thread_exit_event(event_thread_exit) || !drmgr_register_bb_app2app_event(event_bb_app2app, NULL) || !drmgr_register_bb_instrumentation_event(event_app_analysis, event_app_instruction, NULL)) DR_ASSERT(false); client_id = id; tls_idx = drmgr_register_tls_field(); trace_buffer = drx_buf_create_trace_buffer(MEM_BUF_SIZE, trace_fault); /* We could make this a trace buffer and specially handle faults, but it is not yet * worth the effort. */ write_buffer = drx_buf_create_circular_buffer(WRT_BUF_SIZE); DR_ASSERT(tls_idx != -1 && trace_buffer != NULL && write_buffer != NULL); /* make it easy to tell, by looking at log file, which client executed */ dr_log(NULL, DR_LOG_ALL, 1, "Client 'memval' initializing\n"); }
DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { /* We need 2 reg slots beyond drreg's eflags slots => 3 slots */ drreg_options_t ops = {sizeof(ops), 3, false}; /* Specify priority relative to other instrumentation operations: */ drmgr_priority_t priority = { sizeof(priority), /* size of struct */ "memtrace", /* name of our operation */ NULL, /* optional name of operation we should precede */ NULL, /* optional name of operation we should follow */ 0}; /* numeric priority */ dr_set_client_name("DynamoRIO Sample Client 'memtrace'", "http://dynamorio.org/issues"); page_size = dr_page_size(); drmgr_init(); drutil_init(); client_id = id; mutex = dr_mutex_create(); dr_register_exit_event(event_exit); if (!drmgr_register_thread_init_event(event_thread_init) || !drmgr_register_thread_exit_event(event_thread_exit) || !drmgr_register_bb_app2app_event(event_bb_app2app, &priority) || !drmgr_register_bb_instrumentation_event(NULL, event_bb_insert, &priority) || drreg_init(&ops) != DRREG_SUCCESS) { /* something is wrong: can't continue */ DR_ASSERT(false); return; } tls_index = drmgr_register_tls_field(); DR_ASSERT(tls_index != -1); code_cache_init(); /* make it easy to tell, by looking at log file, which client executed */ dr_log(NULL, DR_LOG_ALL, 1, "Client 'memtrace' initializing\n"); #ifdef SHOW_RESULTS 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 memtrace is running\n"); } #endif }
DR_EXPORT drmf_status_t drfuzz_init(client_id_t client_id) { drmf_status_t res; int count = dr_atomic_add32_return_sum(&drfuzz_init_count, 1); if (count > 1) return DRMF_SUCCESS; res = drmf_check_version(client_id); if (res != DRMF_SUCCESS) return res; callbacks = global_alloc(sizeof(drfuzz_callbacks_t), HEAPSTAT_MISC); memset(callbacks, 0, sizeof(drfuzz_callbacks_t)); drmgr_init(); drwrap_init(); #ifdef UNIX drmgr_register_signal_event(fault_handler); #else /* WINDOWS */ drmgr_register_exception_event(fault_handler); #endif drmgr_register_thread_init_event(thread_init); drmgr_register_thread_exit_event(thread_exit); drmgr_register_bb_app2app_event(bb_event, NULL); tls_idx_fuzzer = drmgr_register_tls_field(); if (tls_idx_fuzzer < 0) { DRFUZZ_ERROR("drfuzz failed to reserve TLS slot--initialization failed\n"); return DRMF_ERROR; } /* Synchronized to allow addition and removal of fuzz targets during execution * of the target program, e.g. to explore control flow paths. */ hashtable_init_ex(&fuzz_target_htable, 3, HASH_INTPTR, false/*no strdup*/, true/*synchronized*/, free_fuzz_target, NULL/*no custom hash*/, NULL/*no custom comparator*/); return DRMF_SUCCESS; }
/* * Main entry point that sets up all the facilities we need. */ DR_EXPORT void dr_client_main(client_id_t id, int argc, const char **argv) { dr_set_client_name( "Time-sensitive activity logger for PuTTY crypto testing", "https://www.chiark.greenend.org.uk/~sgtatham/putty/"); outfile = INVALID_FILE; bool ok = drmgr_init(); DR_ASSERT(ok); /* * Run our main instrumentation pass with lower priority than * drwrap, so that we don't start logging the inside of a function * whose drwrap pre-wrapper would have wanted to disable logging. */ drmgr_priority_t pri = {sizeof(pri), "sclog", NULL, NULL, DRMGR_PRIORITY_INSERT_DRWRAP+1}; ok = drmgr_register_bb_instrumentation_event( NULL, instrument_instr, &pri); DR_ASSERT(ok); ok = drutil_init(); DR_ASSERT(ok); ok = drwrap_init(); DR_ASSERT(ok); drsym_error_t symstatus = drsym_init(0); DR_ASSERT(symstatus == DRSYM_SUCCESS); dr_register_exit_event(exit_event); drreg_options_t ops = { sizeof(ops), 3, false }; drreg_status_t regstatus = drreg_init(&ops); DR_ASSERT(regstatus == DRREG_SUCCESS); drmgr_register_module_load_event(load_module); ok = drmgr_register_bb_app2app_event(expand_rep_movsb, NULL); DR_ASSERT(ok); }
/* test unregistering from inside an event */ static dr_emit_flags_t one_time_bb_event(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { int i; # define STRESS_REGISTER_ITERS 64 # define NAME_SZ 32 char *names[STRESS_REGISTER_ITERS]; drmgr_priority_t pri = { sizeof(pri), }; one_time_exec++; if (!drmgr_unregister_bb_app2app_event(one_time_bb_event)) CHECK(false, "drmgr unregistration failed"); /* stress-test adding and removing */ for (i = 0; i < STRESS_REGISTER_ITERS; i++) { /* force sorted insertion on each add */ pri.priority = STRESS_REGISTER_ITERS - i; names[i] = dr_thread_alloc(drcontext, NAME_SZ); dr_snprintf(names[i], NAME_SZ, "%d", pri.priority); pri.name = names[i]; if (!drmgr_register_bb_app2app_event(one_time_bb_event, &pri)) CHECK(false, "drmgr app2app registration failed"); } /* XXX: drmgr lets us add multiple instances of the same callback * so long as they have different priority names (or use default * priority) -- but on removal it only asks for callback and * removes the first it finds. Thus we cannot free any memory * tied up in a priority until we remove *all* of them. * Normally priorities use string literals, so seems ok. */ for (i = 0; i < STRESS_REGISTER_ITERS; i++) { if (!drmgr_unregister_bb_app2app_event(one_time_bb_event)) CHECK(false, "drmgr app2app unregistration failed"); } for (i = 0; i < STRESS_REGISTER_ITERS; i++) { dr_thread_free(drcontext, names[i], NAME_SZ); } return DR_EMIT_DEFAULT; }
DR_EXPORT void dr_init(client_id_t id) { int i = 0; int j = 0; drmgr_init(); dr_enable_console_printing(); setupInsPasses(); doCommandLineArgProcessing(id); DEBUG_PRINT("argument length - %d\n", argument_length); for (i = 0; i < argument_length; i++){ DEBUG_PRINT("\"%s - %s\"\n", arguments[i].name, arguments[i].arguments); } dr_register_nudge_event(nudge_event, id); /*if (log_mode){ populate_conv_filename(global_logfilename, logdir, "global", NULL); global_logfile = dr_open_file(global_logfilename, DR_FILE_WRITE_OVERWRITE); DR_ASSERT(global_logfile != INVALID_FILE); }*/ //dr_messagebox("client id - %d\n", id); DEBUG_PRINT("%s is starting\n", dr_get_application_name()); /* if you are using it only for photoshop do no instrument other exes */ if (strcmp(exec, "photoshop") == 0){ DEBUG_PRINT("photoshop detected only instrumenting Photoshop.exe\n"); if(strcmp(dr_get_application_name(), "Photoshop.exe") != 0){ return; } DEBUG_PRINT("starting to instrument Photoshop.exe\n"); } for( i=0 ; i<argument_length; i++){ for( j=0; j<pass_length; j++){ if(strcmp(arguments[i].name,ins_pass[j].name) == 0){ //we can now register the call backs DEBUG_PRINT("%s - registered\n", arguments[i].name); DEBUG_PRINT("%s - initializing...\n", arguments[i].name); ins_pass[j].init_func(id,arguments[i].name, arguments[i].arguments); DEBUG_PRINT("%s - initialized\n", arguments[i].name); //register thread events if(ins_pass[j].thread_init != NULL) drmgr_register_thread_init_event(ins_pass[j].thread_init); if(ins_pass[j].thread_exit != NULL) drmgr_register_thread_exit_event(ins_pass[j].thread_exit); //register bb events if(ins_pass[j].app2app_bb != NULL) drmgr_register_bb_app2app_event(ins_pass[j].app2app_bb, &ins_pass[j].priority); if(ins_pass[j].instrumentation_bb != NULL || ins_pass[j].analysis_bb != NULL) drmgr_register_bb_instrumentation_event(ins_pass[j].analysis_bb, ins_pass[j].instrumentation_bb, &ins_pass[j].priority); if (ins_pass[j].module_load != NULL) drmgr_register_module_load_event_ex(ins_pass[j].module_load, &ins_pass[j].priority); if (ins_pass[j].module_unload != NULL) drmgr_register_module_unload_event_ex(ins_pass[j].module_unload, &ins_pass[j].priority); } } } dr_register_exit_event(process_exit_routine_call); }