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; }
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; }
void pre_realloc(void *wrapctx, OUT void **user_data) { malloc_t *block; malloc_t *new_block; realloc_tmp_t *tmp = NULL; void *start = drwrap_get_arg(wrapctx, 0); size_t size = (size_t)drwrap_get_arg(wrapctx, 1); void *drc = drwrap_get_drcontext(wrapctx); dr_mutex_lock(lock); /* // the first call on 64 bit and the second in 32bit */ /* // are init call, so we have to do nothing */ /* #ifdef BUILD_64 */ /* if (!realloc_init) */ /* { */ /* realloc_init++; */ /* dr_mutex_unlock(lock); */ /* return; */ /* } */ /* #else */ /* if (realloc_init++ == 1) */ /* { */ /* dr_mutex_unlock(lock); */ /* return; */ /* } */ /* #endif */ // if size == 0, realloc call free if (!size) { // this can happen if a block is alloc by a non wrap module and realloc // on a wrapped one if (!(block = search_on_tree(active_blocks, start))) { dr_mutex_unlock(lock); return; } block->free_pc = get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc); get_caller_data(&(block->free_func_pc), &(block->free_func_sym), &(block->free_module_name), drc, 1); dr_mutex_unlock(lock); return; } if (!(tmp = dr_global_alloc(sizeof(realloc_tmp_t)))) { dr_printf("dr_malloc fail\n"); dr_mutex_unlock(lock); return; } // if realloc is use like malloc save the size to set it on the post wrapping tmp->size = size; *user_data = tmp; // if start == 0, realloc call malloc if (!start) { // if a block is alloc by a wrapped function and realloc by // an unwrapped one we have to take the realloc // so when realloc is called to do a malloc is the only case // when we have to check if the module is wrapped if(!module_is_wrapped(drc)) { *user_data = NULL; dr_global_free(tmp, sizeof(*tmp)); dr_mutex_unlock(lock); return; } tmp->block = NULL; dr_mutex_unlock(lock); return; } // this can happen if the block is alloc by a non wrapped module if (!(block = search_on_tree(active_blocks, start))) { *user_data = NULL; dr_global_free(tmp, sizeof(*tmp)); dr_mutex_unlock(lock); return; } else { del_from_tree(&active_blocks, start, NULL, false); if ((new_block = dr_custom_alloc(NULL, 0, sizeof(*new_block), DR_MEMPROT_WRITE | DR_MEMPROT_READ, NULL))) { block->flag |= FREE_BY_REALLOC; block->free_pc = get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc); get_caller_data(&(block->free_func_pc), &(block->free_func_sym), &(block->free_module_name), drc, 1); block->next = old_blocks; old_blocks = block; old_blocks_count++; if (!args->console && old_blocks_count == MAX_OLD_BLOCKS) { flush_old_block(); old_blocks_count = 0; } ds_memset(new_block, 0, sizeof(*new_block)); new_block->flag |= ALLOC_BY_REALLOC; block = new_block; } else dr_printf("fail alloc\n"); block->size = size; } tmp->block = block; dr_mutex_unlock(lock); }