Example #1
0
void pre_calloc(void *wrapctx, OUT void **user_data)
{
  void		*drc;
  
  drc = drwrap_get_drcontext(wrapctx);

  dr_mutex_lock(lock);

  if (!module_is_wrapped(drc))
    {
      dr_mutex_unlock(lock);
      return;
    }

  *user_data = add_block((size_t)drwrap_get_arg(wrapctx, 1) *
			 (size_t)drwrap_get_arg(wrapctx, 0),
			 get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc),
			 drc);

  dr_mutex_unlock(lock);
}
Example #2
0
void post_realloc(void *wrapctx, void *user_data)
{
  malloc_t	*block;
  void          *ret = drwrap_get_retval(wrapctx);
  void		*drc = drwrap_get_drcontext(wrapctx);;
  realloc_tmp_t	*data = user_data;
  
  // if user_data is not set realloc was called to do a free
  // or the call to realloc is an init call or the block
  // was alloc by a non wrap module
  if (data)
    {
      dr_mutex_lock(lock);
      if (data->block)
        {
	  block = data->block;
	  set_addr_malloc(block, ret, block->flag, 1);
	  // we dont set the alloc arg in get_caller_data
	  // because the post wrap happen after the return
	  get_caller_data(&(block->alloc_func_pc), &(block->alloc_func_sym),
			  &(block->alloc_module_name), drc, 0);
	  block->alloc_pc = get_prev_instr_pc(drwrap_get_retaddr(wrapctx),
					      drc);
	}
      // if realloc is use like a malloc set, we the size here
      // because malloc wrapper receive a null size
      else if ((block = search_on_tree(active_blocks, ret)))
	{
	  block->size = data->size;
	  block->end = block->start + block->size;
	}

      dr_global_free(user_data, sizeof(realloc_tmp_t));

      dr_mutex_unlock(lock);
    }
}
Example #3
0
void pre_malloc(void *wrapctx, OUT void **user_data)
{
  void		*drc;

  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 (!malloc_init++ && !realloc_init) */
/*     { */
/*       dr_mutex_unlock(lock); */
/*       return; */
/*     } */
/* #else */
/*   if (malloc_init++ == 1 && realloc_init != 1) */
/*     { */
/*       dr_mutex_unlock(lock); */
/*       return; */
/*     } */
/* #endif */

  
  if (!module_is_wrapped(drc))
    {
      dr_mutex_unlock(lock);
      return;
    }
  
  *user_data = add_block((size_t)drwrap_get_arg(wrapctx, 0),
			 get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc),
			 drc);

  dr_mutex_unlock(lock);
}
Example #4
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;
}
Example #5
0
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);
}