static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr; uint num_instrs; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first(bb), num_instrs = 0; instr != NULL; instr = instr_get_next(instr)) { num_instrs++; } dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)inscount, false /* save fpstate */, 1, OPND_CREATE_INT32(num_instrs)); #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
/* replaces all inc with add 1, dec with sub 1 * if cannot replace (eflags constraints), leaves original instruction alone */ static dr_emit_flags_t event_trace(void *drcontext, void *tag, instrlist_t *trace, bool translating) { instr_t *instr, *next_instr; int opcode; if (!enable) return DR_EMIT_DEFAULT; #ifdef VERBOSE dr_printf("in dynamorio_trace(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, trace, STDOUT); #endif for (instr = instrlist_first(trace); instr != NULL; instr = next_instr) { /* grab next now so we don't go over instructions we insert */ next_instr = instr_get_next(instr); opcode = instr_get_opcode(instr); if (opcode == OP_inc || opcode == OP_dec) { if (!translating) ATOMIC_INC(num_examined); if (replace_inc_with_add(drcontext, instr, trace)) { if (!translating) ATOMIC_INC(num_converted); } } } #ifdef VERBOSE dr_printf("after dynamorio_trace(tag="PFX"):\n", tag); instrlist_disassemble(drcontext, tag, trace, STDOUT); #endif return DR_EMIT_DEFAULT; }
static void clean_call_mem_stats(reg_t memvalue){ dr_mem_info_t info; uint base; uint limit; uint reserve; void * drcontext = dr_get_current_drcontext(); dr_switch_to_app_state(drcontext); dr_query_memory_ex(memvalue, &info); dr_printf("mem - %d, base_pc - %d , size - %d, prot - %d, type - %d\n", memvalue, info.base_pc, info.size, info.prot, info.type); __asm{ mov EAX, FS : [0x04] mov[base], EAX mov EAX, FS : [0x08] mov[limit], EAX mov EAX, FS : [0xE0C] mov[reserve], EAX } dr_printf("stack information - %d %d %d\n", base, limit, reserve); dr_switch_to_dr_state(drcontext); }
void instrace_exit_event() { int i; DEBUG_PRINT("%s - total amount of instructions - %d\n",ins_pass_name, num_refs); if (client_arg->instrace_mode == OPCODE_TRACE){ dr_printf("opcodes that were covered in this part of the code - \n"); for (i = OP_FIRST; i <= OP_LAST; i++){ if (opcodes_visited[i]){ dr_printf(logfile,"%s - ", decode_opcode_name(i)); } } dr_printf("\n"); } md_delete_list(head, false); md_delete_list(instrace_head, false); dr_global_free(client_arg,sizeof(client_arg_t)); code_cache_exit(); drmgr_unregister_tls_field(tls_index); dr_mutex_destroy(mutex); if (log_mode){ dr_close_file(logfile); } drutil_exit(); drmgr_exit(); }
void dr_exit(void) { #ifdef SHOW_RESULTS /* Print all the cbr's seen over the life of the process, and * whether we saw taken, not taken, or both. */ int i; for (i=0; i<HASH_TABLE_SIZE; i++) { if (table[i] != NULL) { elem_t *iter; for (iter = table[i]->head; iter != NULL; iter = iter->next) { cbr_state_t state = iter->state; if (state == CBR_TAKEN) { dr_printf(""PFX": taken\n", iter->addr); } else if (state == CBR_NOT_TAKEN) { dr_printf(""PFX": not taken\n", iter->addr); } else { ASSERT(state == (CBR_TAKEN | CBR_NOT_TAKEN)); dr_printf(""PFX": both\n", iter->addr); } } } } #endif delete_table(table); }
static void event_exit(void) { dr_printf("insn_count: %ld\n", insn_count); dr_printf("read_count: %ld\n", read_count); dr_printf("writ_count: %ld\n", writ_count); dr_printf("read_size: %ld\n", read_size); dr_printf("writ_size: %ld\n", writ_size); }
static void onLoad( void* ctx, const module_data_t* m, bool loaded ) { dr_printf( "In onLoad(%s, %p-%p)\n", m->full_path, m->start, m->end ); dr_mutex_lock( outMutex ); dr_fprintf( outFile, "M %p %p %s\n", m->start, m->end, m->full_path ); dr_mutex_unlock( outMutex ); drsym_error_t rc = drsym_enumerate_symbols( m->full_path, onSymbol, (void*)m, 0 ); if( DRSYM_SUCCESS != rc ) { dr_printf( " drsym_enumerate_symbols() failed: %i\n", rc ); } }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *mbr = NULL; uint num_instrs; bool bb_in_app; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first(bb), num_instrs = 0; instr != NULL; instr = instr_get_next(instr)) { /* only care about app instr */ if (!instr_ok_to_mangle(instr)) continue; num_instrs++; /* Assuming most of the transfers between app and lib are paired, we * instrument indirect branches but not returns for better performance. */ if (instr_is_mbr(instr) && !instr_is_return(instr)) mbr = instr; } if (dr_fragment_app_pc(tag) >= app_base && dr_fragment_app_pc(tag) < app_end) bb_in_app = true; else bb_in_app = false; dr_insert_clean_call(drcontext, bb, instrlist_first(bb), (void *)(bb_in_app ? app_update : lib_update), false /* save fpstate */, 1, OPND_CREATE_INT32(num_instrs)); if (mbr != NULL) { dr_insert_mbr_instrumentation(drcontext, bb, mbr, (void *)(bb_in_app ? app_mbr : lib_mbr), SPILL_SLOT_1); } #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
static file_t open_sigil2_fifo(const char *path, int flags) { /* Wait for Sigil2 to create pipes * Timeout is empirical */ uint max_tests = 10; for(uint i=0; i<max_tests+1; ++i) { if(dr_file_exists(path)) break; if(i == max_tests) { dr_printf("%s\n", path); DR_ASSERT_MSG(false, "DrSigil timed out waiting for sigil2 fifos"); } struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 200000000L; nanosleep(&ts, NULL); } file_t f = dr_open_file(path, flags); if(f == INVALID_FILE) DR_ABORT_MSG("error opening empty fifo"); return f; }
static dr_emit_flags_t event_bb ( void* drcontext, void* tag, instrlist_t* bb, bool for_trace, bool translating ) { /* refer to dr_ir_instr.h */ instr_t* insn = instrlist_first(bb); for (; insn != NULL; insn = instr_get_next(insn)) { ++insn_count; if (instr_reads_memory(insn)) { ++read_count; read_size += instr_memory_reference_size(insn); dr_printf("read_size:%u\n", instr_memory_reference_size(insn)); } if (instr_writes_memory(insn)) { ++writ_count; writ_size += instr_memory_reference_size(insn); } } return DR_EMIT_DEFAULT; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *next_instr; #ifdef VERBOSE dr_printf("in dr_basic_block(tag="PFX")\n", tag); # if VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first_app(bb); instr != NULL; instr = next_instr) { next_instr = instr_get_next_app(instr); if (!instr_opcode_valid(instr)) continue; /* instrument calls and returns -- ignore far calls/rets */ if (instr_is_call_direct(instr)) { dr_insert_call_instrumentation(drcontext, bb, instr, (app_pc)at_call); } else if (instr_is_call_indirect(instr)) { dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_call_ind, SPILL_SLOT_1); } else if (instr_is_return(instr)) { dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_return, SPILL_SLOT_1); } } return DR_EMIT_DEFAULT; }
void memory_write(void *pc, void *prev_pc) { void *drcontext = dr_get_current_drcontext(); instr_t *instr = instr_create(drcontext); dr_mcontext_t mctx; opnd_t dst; ctx_t ctx; pc = dr_app_pc_for_decoding(pc); mctx.flags = DR_MC_CONTROL|DR_MC_INTEGER; mctx.size = sizeof(mctx); dr_get_mcontext(drcontext, &mctx); instr_init(drcontext, instr); if (!decode(drcontext, pc, instr)) { dr_printf("Decode of instruction at %p failed\n", pc); return; } ctx.addr = prev_pc; ctx.dr_addr = prev_pc; for (int i = 0; i < instr_num_dsts(instr); i++) { dst = instr_get_dst(instr, i); check_opnd(dst, pc, 0, drcontext, &mctx, &ctx); } instr_destroy(drcontext, instr); }
access_t *get_access(size_t offset, tree_t **t_access, malloc_t *block) { access_t *access; if ((access = search_same_addr_on_tree(*t_access, (void *)offset))) return access; // if no access with this offset is found we create a new one if (!(access = alloc_access(block))) { dr_printf("dr_malloc fail\n"); return NULL; } ds_memset(access, 0, sizeof(*access)); access->offset = offset; access->node.data = access; access->node.high_addr = (void *)offset; access->node.min_addr = (void *)offset; add_to_tree(t_access, (tree_t*)access); return access; }
static dr_emit_flags_t event_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst, bool for_trace, bool translating, void *user_data) { #ifdef SHOW_RESULTS bool aflags_dead; #endif if (!drmgr_is_first_instr(drcontext, inst)) return DR_EMIT_DEFAULT; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif #ifdef SHOW_RESULTS if (drreg_are_aflags_dead(drcontext, inst, &aflags_dead) == DRREG_SUCCESS && !aflags_dead) bbs_eflags_saved++; else bbs_no_eflags_saved++; #endif /* We demonstrate how to use drreg for aflags save/restore here. * We could use drx_insert_counter_update instead of drreg. * Xref sample opcodes.c as an example of using drx_insert_counter_update. */ if (drreg_reserve_aflags(drcontext, bb, inst) != DRREG_SUCCESS) DR_ASSERT(false && "fail to reserve aflags!"); /* racy update on the counter for better performance */ instrlist_meta_preinsert (bb, inst, INSTR_CREATE_inc(drcontext, OPND_CREATE_ABSMEM ((byte *)&global_count, OPSZ_4))); if (drreg_unreserve_aflags(drcontext, bb, inst) != DRREG_SUCCESS) DR_ASSERT(false && "fail to unreserve aflags!"); #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
/** Deletes wrapper context and removes corresponding wrapper. */ static void free_wrap( void* rawWrap ) { struct wrap* wrap = ( struct wrap* )rawWrap; if( !drwrap_unwrap( wrap->address, &wrapperPre, NULL ) ) { dr_printf( "drwrap_unwrap(%p) failed\n", (void*)wrap->address ); exit( 1 ); } dr_global_free( wrap, sizeof( struct wrap ) ); }
/** Allocates storage for wrapper context. */ static struct wrap* alloc_wrap() { struct wrap* wrap = ( struct wrap* )dr_global_alloc( sizeof( struct wrap ) ); if( wrap == NULL ) { dr_printf( "Failed to allocate memory for struct wrap\n" ); exit( 1 ); } return wrap; }
DR_EXPORT void dr_init(client_id_t client_id) { dr_probe_status_t stat; probe_def_init(); if ( ! dr_register_probes(&probes[0], NUM_PROBES) ) { dr_printf("register failed\n"); } if (probes[0].status==DR_PROBE_STATUS_UNSUPPORTED) { dr_printf("UN_SU_POR_TED\n"); } int rv = dr_get_probe_status(probes[0].id, &stat); if (!rv && stat==DR_PROBE_STATUS_INVALID_ID) { dr_printf("Failed to register probe: %d\n", probes[0].id); } }
void incr_orig(access_t *access, size_t size, void *pc, void *drcontext, malloc_t *block, ctx_t *ctx) { orig_t *orig_tree = search_same_addr_on_tree(access->origs, pc); orig_t *orig_list = orig_tree; while (orig_list && orig_list->size != size) orig_list = orig_list->next; if (orig_list) { orig_list->nb_hit++; return; } if (!orig_tree) { if (!(orig_tree = new_orig(size, pc, drcontext, block, ctx))) { dr_printf("dr_malloc fail\n"); return; } orig_tree->node.high_addr = pc; orig_tree->node.min_addr = pc; orig_tree->node.data = orig_tree; add_to_tree(&(access->origs), (tree_t*)orig_tree); return; } // if a an orig have the same addr but not the same size we create an other // entry and put it in the linked list for this node; if (!orig_list) { if (!(orig_list = new_orig(size, pc, drcontext, block, ctx))) { dr_printf("dr_malloc fail\n"); return; } while (orig_tree->next) orig_tree = orig_tree->next; orig_tree->next = orig_list; } }
static void clean_call_print_regvalues(){ uint regvalue; dr_mcontext_t mc = { sizeof(mc), DR_MC_ALL }; void * drcontext = dr_get_current_drcontext(); dr_get_mcontext(drcontext, &mc); dr_printf("---------\n"); regvalue = reg_get_value(DR_REG_XAX, &mc); dr_printf("xax - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XBX, &mc); dr_printf("xbx - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XCX, &mc); dr_printf("xcx - %x\n", regvalue); regvalue = reg_get_value(DR_REG_XDX, &mc); dr_printf("xdx - %x\n", regvalue); }
static void onUnload( void* ctx, const module_data_t* m ) { dr_printf( "In onUnload(%s, %p-%p)\n", m->full_path, m->start, m->end ); dr_mutex_lock( outMutex ); dr_fprintf( outFile, "m %p %p %s\n", (void*)m->start, (void*)m->end, m->full_path ); dr_mutex_unlock( outMutex ); hashtable_lock( &wraps ); hashtable_remove_range( &wraps, (void*)m->start, (void*)m->end ); hashtable_unlock( &wraps ); }
/*----------------------------------------------------------------------------*/ static void probe_def_init(void) { probes[0].name = "chrome probe"; probes[0].insert_loc.type = DR_PROBE_ADDR_LIB_OFFS; probes[0].insert_loc.lib_offs.library = "../mutatee/chrome"; drsym_init(0); { size_t exe_export_offs; drsym_error_t r = drsym_lookup_symbol("../mutatee/chrome", "doubler",&exe_export_offs, DRSYM_DEMANGLE); if (r!=DRSYM_SUCCESS) { dr_fprintf(STDERR, "<FAILED to find gpu::gles2::GLES2Implementation::Viewport\n"); } else { dr_printf("<Found Original symbol>\n"); probes[0].insert_loc.lib_offs.offset = exe_export_offs; } } //probes[0].insert_loc.lib_offs.offset = 0x50530; probes[0].callback_func.type = DR_PROBE_ADDR_LIB_OFFS; probes[0].callback_func.lib_offs.library = "libhooks.so"; { size_t exe_export_offs; drsym_error_t r = drsym_lookup_symbol("libhooks.so", "preHook",&exe_export_offs, DRSYM_DEMANGLE); if (r!=DRSYM_SUCCESS) { dr_fprintf(STDERR, "<FAILED to find gpu::gles2::GLES2Implementation::Viewport>\n"); } else { dr_printf("<Found Hook symbol>\n"); probes[0].callback_func.lib_offs.offset = exe_export_offs; } } drsym_exit(); /* probes[0].callback_func.lib_offs.offset = 0xe30; */ }
DR_EXPORT void dr_init( client_id_t id ) { dr_printf( "In dr_init()\n" ); // Initialize extensions. drsym_error_t rc = drsym_init( 0 ); if( DRSYM_SUCCESS != rc ) { dr_printf( "drsym_init() failed: %i\n", rc ); exit( 1 ); } bool wrapInit = drwrap_init(); if( !wrapInit ) { dr_printf( "drwrap_init() failed\n" ); exit( 1 ); } // Set up output. char fileName[256]; unsigned int pid = (unsigned int)dr_get_process_id(); dr_snprintf( fileName, sizeof( fileName ), "objcount-%u.out", pid ); fileName[sizeof( fileName ) - 1] = 0; outFile = dr_open_file( fileName, DR_FILE_WRITE_OVERWRITE ); outMutex = dr_mutex_create(); // Set up hashtable. hashtable_init_ex( &wraps, // table 16, // num_bits HASH_INTPTR, // hashtype false, // str_dup false, // synch &free_wrap, // free_payload_func NULL, // hash_key_func NULL ); // cmp_key_func // Register for events. dr_register_module_load_event( onLoad ); dr_register_exit_event( onExit ); }
static void onExit() { dr_printf( "In onExit()\n" ); // Clean up hashtable. hashtable_delete( &wraps ); // Clean up output. dr_mutex_destroy( outMutex ); dr_close_file( outFile ); // Clean up extensions. drwrap_exit(); drsym_exit(); }
void process_global_arguments(){ int i = 0; for (i = 0; i < argument_length; i++){ if (strcmp(arguments[i].name, "logdir") == 0){ dr_printf("global logdir - %s\n", arguments[i].arguments); strncpy(logdir, arguments[i].arguments, MAX_STRING_LENGTH); } else if (strcmp(arguments[i].name, "debug") == 0){ dr_printf("global debug - %s\n", arguments[i].arguments); debug_mode = arguments[i].arguments[0] - '0'; } else if (strcmp(arguments[i].name, "log") == 0){ dr_printf("global log - %s\n", arguments[i].arguments); log_mode = arguments[i].arguments[0] - '0'; } else if (strcmp(arguments[i].name, "exec") == 0){ dr_printf("exec - %s\n", arguments[i].arguments); strncpy(exec, arguments[i].arguments, MAX_STRING_LENGTH); } } }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr, *next_instr; #ifdef VERBOSE dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag); # ifdef VERBOSE_VERBOSE instrlist_disassemble(drcontext, tag, bb, STDOUT); # endif #endif for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) { /* grab next now so we don't go over instructions we insert */ next_instr = instr_get_next(instr); /* instrument calls and returns -- ignore far calls/rets */ if (instr_is_call_direct(instr)) { insert_counter_update(drcontext, bb, instr, offsetof(per_thread_t, num_direct_calls)); } else if (instr_is_call_indirect(instr)) { insert_counter_update(drcontext, bb, instr, offsetof(per_thread_t, num_indirect_calls)); } else if (instr_is_return(instr)) { insert_counter_update(drcontext, bb, instr, offsetof(per_thread_t, num_returns)); } } #if defined(VERBOSE) && defined(VERBOSE_VERBOSE) dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag); instrlist_disassemble(drcontext, tag, bb, STDOUT); #endif return DR_EMIT_DEFAULT; }
void check_opnd(opnd_t opnd, void *pc, int read, void *drcontext, dr_mcontext_t *mctx, void *prev_pc) { if (opnd_is_memory_reference(opnd) && opnd_is_base_disp(opnd)) add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)), opnd_get_disp(opnd) + (void *)reg_get_value(opnd_get_base(opnd), mctx), read, drcontext, prev_pc); else if (opnd_is_memory_reference(opnd) && opnd_get_addr(opnd)) add_hit(pc, opnd_size_in_bytes(opnd_get_size(opnd)), opnd_get_addr(opnd), read, drcontext, prev_pc); // for now no other kind of memory reference was noticed to access heap data else if (opnd_is_memory_reference(opnd)) dr_printf("need to implem other memory ref\n"); }
static void look_for_usercall(void *dcontext, byte *entry, const char *sym, LOADED_IMAGE *img, const char *modpath) { bool found_push_imm = false; int imm = 0; app_pc pc, pre_pc; instr_t *instr; if (entry == NULL) return; instr = instr_create(dcontext); pc = entry; while (true) { instr_reset(dcontext, instr); pre_pc = pc; pc = decode(dcontext, pc, instr); if (verbose) { instr_set_translation(instr, pre_pc); dr_print_instr(dcontext, STDOUT, instr, ""); } if (pc == NULL || !instr_valid(instr)) break; if (instr_get_opcode(instr) == OP_push_imm) { found_push_imm = true; imm = (int) opnd_get_immed_int(instr_get_src(instr, 0)); } else if (instr_is_call_direct(instr) && found_push_imm) { app_pc tgt = opnd_get_pc(instr_get_target(instr)); bool found = false; int i; for (i = 0; i < NUM_USERCALL; i++) { if (tgt == usercall_addr[i]) { dr_printf("Call #0x%02x to %s at %s+0x%x\n", imm, usercall_names[i], sym, pre_pc - entry); found = true; break; } } if (found) break; } else if (instr_is_return(instr)) break; if (pc - entry > MAX_BYTES_BEFORE_USERCALL) break; } instr_destroy(dcontext, instr); }
DR_EXPORT void dr_init(client_id_t id) { dr_printf("dr_init()\n"); my_bbcount = 0; stats_mutex = dr_mutex_create(); dr_register_exit_event(event_exit); dr_register_bb_event(event_basic_block); #ifdef SHOW_RESULTS dr_log(NULL, LOG_ALL, 1, "Client 'inspar' initializing\n"); if (dr_is_notify_on()) { # ifdef WINDOWS dr_enable_console_printing(); # endif dr_fprintf(STDERR, "Client inspar is running\n"); } #endif }
static void read_data(file_t f, void *drcontext) { byte sbuf[BUF_SIZE]; byte *pc, *prev_pc; int len, prev_buf_len = 0; /* FIXME: re-run 64-bit asking for 32-bit mode */ do { len = dr_read_file(f, sbuf, sizeof(sbuf)); pc = sbuf; while (pc < sbuf+len) { /* FIXME: want to cut it off instead of reading beyond for * end of file! If weren't printing it out as go along could * mark invalid after seeing whether instr overflows. */ prev_pc = pc; #if VERBOSE dr_printf("+0x%04x ", prev_pc - sbuf + prev_buf_len); #endif pc = disassemble_from_copy(drcontext, pc, ORIG_PC, STDOUT, false/*don't show pc*/, #if VERBOSE true/*show bytes*/ #else false/*do not show bytes*/ #endif ); /* If invalid, try next byte */ /* FIXME: udis86 is going to byte after the one that makes it * invalid: so if 1st byte is invalid opcode, go to 2nd; * if modrm makes it invalid (0xc5 0xc5), go to 3rd. * not clear that's nec. better but we need to reconcile that w/ * their diff for automated testing. */ if (pc == NULL) pc = prev_pc + 1; } prev_buf_len += sizeof(sbuf); } while (len == sizeof(sbuf)); }
orig_t *new_orig(size_t size, void *pc, void *drcontext, malloc_t *block, ctx_t *ctx) { orig_t *orig; void *next_pc; if (!(orig = alloc_orig(block))) { dr_printf("dr_malloc fail\n"); return NULL; } ds_memset(orig, 0, sizeof(*orig)); orig->size = size; orig->nb_hit = 1; orig->addr = pc; next_pc = decode_next_pc(drcontext, pc); orig->instr_size = next_pc - pc; orig->raw_instr = alloc_instr(block, orig->instr_size); copy_instr(orig->addr, orig->instr_size, orig->raw_instr); // get ctx isntruction to have information in structure recovery if (ctx->dr_addr) { orig->ctx_addr = ctx->addr; orig->ctx_instr_size = (void*)decode_next_pc(drcontext, ctx->dr_addr) - ctx->dr_addr; orig->raw_ctx_instr = alloc_instr(block, orig->ctx_instr_size); copy_instr(ctx->dr_addr, orig->ctx_instr_size, orig->raw_ctx_instr); } else { orig->ctx_addr = NULL; orig->ctx_instr_size = 0; } // get the start addr of the function doing the access get_caller_data(&(orig->start_func_addr), &(orig->start_func_sym), &(orig->module_name), drcontext, 0); return orig; }