Exemple #1
0
static
void custom_windows_test(void)
{
    void *array;
    MEMORY_BASIC_INFORMATION mbi;
    bool ok;

    dr_fprintf(STDERR, "  testing custom windows alloc....");

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR |
                            DR_ALLOC_RESERVE_ONLY, PAGE_SIZE*2,
                            DR_MEMPROT_NONE, NULL);
    if (array == NULL)
        dr_fprintf(STDERR, "error: unable to reserve\n");
    if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi))
        dr_fprintf(STDERR, "error: unable to query prot\n");
    /* 0 is sometimes returned (see VirtualQuery docs) */
    if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0)
        dr_fprintf(STDERR, "error: wrong reserve prot %x\n", mbi.Protect);
    if (mbi.State != MEM_RESERVE)
        dr_fprintf(STDERR, "error: memory wasn't reserved\n");

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR |
                            DR_ALLOC_COMMIT_ONLY | DR_ALLOC_FIXED_LOCATION,
                            PAGE_SIZE, DR_MEMPROT_READ | DR_MEMPROT_WRITE, array);
    if (array == NULL)
        dr_fprintf(STDERR, "error: unable to commit\n");
    if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi))
        dr_fprintf(STDERR, "error: unable to query prot\n");
    if (mbi.Protect != PAGE_READWRITE)
        dr_fprintf(STDERR, "error: wrong commit prot %x\n", mbi.Protect);
    if (mbi.State != MEM_COMMIT || mbi.RegionSize != PAGE_SIZE)
        dr_fprintf(STDERR, "error: memory wasn't committed\n");

    write_array(array);

    ok = dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR |
                        DR_ALLOC_COMMIT_ONLY, array, PAGE_SIZE);
    if (!ok)
        dr_fprintf(STDERR, "error: failed to de-commit\n");
    if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi))
        dr_fprintf(STDERR, "error: unable to query prot\n");
    /* 0 is sometimes returned (see VirtualQuery docs) */
    if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0)
        dr_fprintf(STDERR, "error: wrong decommit prot %x\n", mbi.Protect);
    if (mbi.State != MEM_RESERVE)
        dr_fprintf(STDERR, "error: memory wasn't de-committed %x\n", mbi.State);

    ok = dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR |
                        DR_ALLOC_RESERVE_ONLY, array, PAGE_SIZE*2);
    if (!ok)
        dr_fprintf(STDERR, "error: failed to un-reserve\n");
    if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi))
        dr_fprintf(STDERR, "error: unable to query prot\n");
    /* 0 is sometimes returned (see VirtualQuery docs) */
    if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0)
        dr_fprintf(STDERR, "error: wrong unreserve prot %x\n", mbi.Protect);
    if (mbi.State != MEM_FREE)
        dr_fprintf(STDERR, "error: memory wasn't un-reserved\n");

    dr_fprintf(STDERR, "success\n");
}
Exemple #2
0
static
void custom_test(void)
{
    void *drcontext = dr_get_current_drcontext();
    void *array, *preferred;
    size_t size;
    uint prot;

    dr_fprintf(STDERR, "  testing custom memory alloc....");

    /* test global */
    array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL);
    write_array(array);
    dr_custom_free(NULL, 0, array, SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE);

    /* test thread-local */
    array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL);
    write_array(array);
    dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE);

    array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE,
                            SIZE, 0, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE,
                   array, SIZE);

    /* test non-heap */
    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE);

    /* Find a free region of memory without inadvertently "preloading" it.
     * First probe by allocating 2x the platform allocation alignment unit.
     */
    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, HINT_ALLOC_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    /* Then select the second half as the preferred address for the allocation test. */
    preferred = (void *)((ptr_uint_t)array + HINT_OFFSET);
    /* Free the probe allocation. */
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, array, HINT_ALLOC_SIZE);

    /* Now `preferred` is guaranteed to be available. */
    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE, preferred);
    ASSERT(array == preferred);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE,
                   array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
#ifdef X64
    ASSERT((ptr_uint_t)array < 0x80000000);
#endif
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR,
                   array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL);
    ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) &&
           size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                                         DR_MEMPROT_EXEC));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE);

    dr_fprintf(STDERR, "success\n");
}
Exemple #3
0
static
void custom_test(void)
{
    void *drcontext = dr_get_current_drcontext();
    void *array;
    size_t size;
    uint prot;

    dr_fprintf(STDERR, "  testing custom memory alloc....");

    /* test global */
    array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL);
    write_array(array);
    dr_custom_free(NULL, 0, array, SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE);

    /* test thread-local */
    array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL);
    write_array(array);
    dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE);

    array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE,
                            SIZE, 0, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE,
                   array, SIZE);

    /* test non-heap */
    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE, PREFERRED_ADDR);
    ASSERT(array == (void *)PREFERRED_ADDR);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    ASSERT(reachable_from_client(array));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE,
                   array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
#ifdef X64
    ASSERT((ptr_uint_t)array < 0x80000000);
#endif
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR,
                            PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL);
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR,
                   array, PAGE_SIZE);

    array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE,
                            DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL);
    ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) &&
           size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                                         DR_MEMPROT_EXEC));
    write_array(array);
    dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE);

    dr_fprintf(STDERR, "success\n");
}
Exemple #4
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);
}