Dr. Memory |

Data Structures | Macros | Typedefs | Enumerations | Functions
umbra.h File Reference

Header for Umbra: DynamoRIO Shadow Memory Extension. More...

`#include "drmemory_framework.h"`

## Data Structures
struct | _umbra_shadow_memory_info_t
struct | _umbra_map_options_t

## Macros
#define | DRMGR_PRIORITY_NAME_EXCPT_UMBRA "umbra_except"
#define | UMBRA_MAP_SCALE_IS_UP(scale) ((scale) >= UMBRA_MAP_SCALE_UP_2X)

## Typedefs
typedef struct _umbra_shadow_memory_info_t | umbra_shadow_memory_info_t
typedef struct _umbra_map_t | umbra_map_t
typedef void(* | app_memory_create_cb_t) (umbra_map_t *map, app_pc start, size_t size)
typedef struct _umbra_map_options_t | umbra_map_options_t
typedef bool(* | shadow_iterate_func_t) (umbra_map_t *map, umbra_shadow_memory_info_t *info, void *user_data)

## Enumerations
enum | { DRMGR_PRIORITY_PRESYS_DRSYS = -100, DRMGR_PRIORITY_POSTSYS_DRSYS = -100, DRMGR_PRIORITY_POSTSYS_DRSYS_LAST = 10000, DRMGR_PRIORITY_MODLOAD_DRSYS = -100, DRMGR_PRIORITY_EXCPT_UMBRA = -100, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ = -150, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE = 150, DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE = -150 }
enum | umbra_map_scale_t { , UMBRA_MAP_SCALE_DOWN_4X, UMBRA_MAP_SCALE_DOWN_2X, UMBRA_MAP_SCALE_SAME_1X, UMBRA_MAP_SCALE_UP_2X }
enum | umbra_map_flags_t { UMBRA_MAP_CREATE_SHADOW_ON_TOUCH = 0x1, UMBRA_MAP_SHADOW_SHARED_READONLY = 0x2 }
enum | umbra_shadow_memory_flags_t { UMBRA_CREATE_SHADOW_SHARED_READONLY = 0x1 }
enum | umbra_shadow_memory_type_t { UMBRA_SHADOW_MEMORY_TYPE_UNKNOWN = 0x1, UMBRA_SHADOW_MEMORY_TYPE_NOT_SHADOW = 0x2, UMBRA_SHADOW_MEMORY_TYPE_NORMAL = 0x4, UMBRA_SHADOW_MEMORY_TYPE_SHARED = 0x8, UMBRA_SHADOW_MEMORY_TYPE_SHADOW_NOT_ALLOC = 0x10 }

## Functions
DR_EXPORT drmf_status_t | umbra_init (client_id_t client_id)
DR_EXPORT drmf_status_t | umbra_exit (void)
DR_EXPORT drmf_status_t | umbra_create_mapping (IN umbra_map_options_t *ops, OUT umbra_map_t **map_out)
DR_EXPORT drmf_status_t | umbra_destroy_mapping (IN umbra_map_t *map)
DR_EXPORT drmf_status_t | umbra_create_shadow_memory (IN umbra_map_t *map, IN umbra_shadow_memory_flags_t flags, IN app_pc app_addr, IN size_t app_size, IN ptr_uint_t value, IN size_t value_size)
DR_EXPORT drmf_status_t | umbra_delete_shadow_memory (IN umbra_map_t *map, IN app_pc app_addr, IN size_t app_size)
DR_EXPORT drmf_status_t | umbra_num_scratch_regs_for_translation (OUT int *num_regs)
DR_EXPORT drmf_status_t | umbra_insert_app_to_shadow (IN void *drcontext, IN umbra_map_t *map, IN instrlist_t *ilist, IN instr_t *where, IN reg_id_t addr_reg, IN reg_id_t *scratch_regs, IN int num_scratch_regs)
DR_EXPORT drmf_status_t | umbra_read_shadow_memory (IN umbra_map_t *map, IN app_pc app_addr, IN size_t app_size, INOUT size_t *shadow_size, OUT byte *buffer)
DR_EXPORT drmf_status_t | umbra_write_shadow_memory (IN umbra_map_t *map, IN app_pc app_addr, IN size_t app_size, INOUT size_t *shadow_size, IN byte *buffer)
DR_EXPORT drmf_status_t | umbra_shadow_set_range (IN umbra_map_t *map, IN app_pc app_addr, IN size_t app_size, OUT size_t *shadow_size, IN ptr_uint_t value, IN size_t value_size)
DR_EXPORT drmf_status_t | umbra_shadow_copy_range (IN umbra_map_t *map, IN app_pc app_src, IN app_pc app_dst, IN size_t app_size, OUT size_t *shadow_size)
DR_EXPORT drmf_status_t | umbra_value_in_shadow_memory (IN umbra_map_t *map, INOUT app_pc *app_addr, IN size_t app_size, IN ptr_uint_t value, IN size_t value_size, OUT bool *found)
DR_EXPORT drmf_status_t | umbra_get_shadow_block_size (IN umbra_map_t *map, OUT size_t *size)
DR_EXPORT drmf_status_t | umbra_iterate_app_memory (IN umbra_map_t *map, IN void *user_data, IN bool(*iter_func)(umbra_map_t *map, const dr_mem_info_t *info, void *user_data))
DR_EXPORT drmf_status_t | umbra_iterate_shadow_memory (IN umbra_map_t *map, IN void *user_data, IN shadow_iterate_func_t iter_func)
DR_EXPORT drmf_status_t | umbra_get_shadow_memory_type (IN umbra_map_t *map, IN byte *shadow_addr, OUT umbra_shadow_memory_type_t *shadow_type)
DR_EXPORT drmf_status_t | umbra_shadow_memory_is_shared (IN umbra_map_t *map, IN byte *shadow_addr, OUT umbra_shadow_memory_type_t *shadow_type)
DR_EXPORT drmf_status_t | umbra_get_shadow_memory (IN umbra_map_t *map, IN app_pc app_addr, OUT byte **shadow_addr, INOUT umbra_shadow_memory_info_t *shadow_info)
DR_EXPORT drmf_status_t | umbra_replace_shared_shadow_memory (IN umbra_map_t *map, IN app_pc app_addr, OUT byte **shadow_addr)
DR_EXPORT drmf_status_t | umbra_create_shared_shadow_block (IN umbra_map_t *map, IN ptr_uint_t value, IN size_t value_size, OUT byte **block)
DR_EXPORT drmf_status_t | umbra_get_shared_shadow_block (IN umbra_map_t *map, IN ptr_uint_t value, IN size_t value_size, OUT byte **block)
static void | umbra_shadow_memory_info_init (umbra_shadow_memory_info_t *info)
DR_EXPORT drmf_status_t | umbra_clear_redundant_blocks (umbra_map_t *map, uint *count)

## Detailed Description

Header for Umbra: DynamoRIO Shadow Memory Extension.

## Macro Definition Documentation

## ◆ DRMGR_PRIORITY_NAME_EXCPT_UMBRA

#define DRMGR_PRIORITY_NAME_EXCPT_UMBRA "umbra_except"

Name of Umbra signal/exception events.

## ◆ UMBRA_MAP_SCALE_IS_UP

#define UMBRA_MAP_SCALE_IS_UP | ( |  | scale | ) | ((scale) >= UMBRA_MAP_SCALE_UP_2X)

Check if a shadow memory mapping scale is scale up or down.

## Typedef Documentation

## ◆ app_memory_create_cb_t

typedef void(* app_memory_create_cb_t) (umbra_map_t *map, app_pc start, size_t size)

Application memory creation/deletion callback function type. These callbacks are called when the application performs system calls to allocate or delete memory.

## ◆ shadow_iterate_func_t

typedef bool(* shadow_iterate_func_t) (umbra_map_t *map, umbra_shadow_memory_info_t *info, void *user_data)

Iterate callback function type for umbra_iterate_shadow_memory.

Parameters

  [in] | map | The mapping object to use.
  [in] | info | Information about the shadow memory.
  [in] | user_data | User data passed during iteration.

## ◆ umbra_map_options_t

typedef struct _umbra_map_options_t umbra_map_options_t

Specifies parameters controlling the behavior of umbra_create_map().

## ◆ umbra_map_t

typedef struct _umbra_map_t umbra_map_t

Opaque "Umbra map handle" type used to refer to a particular Umbra mapping scheme object created by umbra_create_mapping(),

## ◆ umbra_shadow_memory_info_t

typedef struct _umbra_shadow_memory_info_t umbra_shadow_memory_info_t

Information about a shadow memory region.

## Enumeration Type Documentation

## ◆ anonymous enum

anonymous enum

Priority of Umbra events.

Enumerator
DRMGR_PRIORITY_PRESYS_DRSYS | Priority of the drsyscall pre-syscall and post-syscall events that are meant to take place before the corresponding events of a regular user of drsyscall. Dynamic iteration is not allowed until these events have taken place. Users of drsyscall should arrange their pre-syscall and post-syscall event callbacks to be called after the drsyscall event, unless they want to modify the pre-syscall arguments before they're stored or they want to modify the application's context, in which case their event should go beforehand.
DRMGR_PRIORITY_POSTSYS_DRSYS | See the comment for DRMGR_PRIORITY_PRESYS_DRSYS.
DRMGR_PRIORITY_POSTSYS_DRSYS_LAST | Priority of the drsyscall last-chance post-syscall event. This event must take place after any dynamic iteration of system call arguments, which means it must be after the post-syscall event in all users of drsyscall.
DRMGR_PRIORITY_MODLOAD_DRSYS | Priority of the drsyscall module load event. This event must take place before any user of drsyscall in order to populate the tables used by drsys_name_to_syscall().
DRMGR_PRIORITY_EXCPT_UMBRA | Priority of the Umbra signal/exception handling event. This event must take place before any user of drsyscall in order to allocate shadow memory if necessary.
DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ | Priority of the drsymcache module load event action that checks for a symbol cache file and reads it in. This event must occur before any drsymcache API usage in module load events of users of drsymcache.
DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE | Priority of the drsymcache module load event action that saves the current symbol cache from memory to disk.
DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE | Priority of the drsymcache module unload event action that saves the current symbol cache from memory to disk and then frees the in-memory cache data structures. This event must occur after any drsymcache API usage in module unload events of users of drsymcache.

## ◆ umbra_map_flags_t

enum umbra_map_flags_t

Umbra mapping creation flags for fine-grained control

Enumerator
UMBRA_MAP_CREATE_SHADOW_ON_TOUCH | If set, Umbra will try to create the shadow memory on the access to shadow memory that is not yet. When using this option, the user should handle exceptions caused by referencing shadow memory that Umbra fails to handle.
UMBRA_MAP_SHADOW_SHARED_READONLY | This is an optimization hint for reducing memory usage by allowing Umbra to map different application memory regions with identical shadow value to the same shared shadow memory block. Attempts to directly write shared shadow memory will cause exceptions that should be handled by the user.

## ◆ umbra_map_scale_t

enum umbra_map_scale_t

Shadow memory mapping (scaling) schemes supported by Umbra.

Note
  : Umbra does not support bit operations, so parameters passed to any Umbra routine will be automatically aligned for proper translation. For example, application memory address `app_addr` will be aligned to 8 if using UMBRA_MAP_SCALE_DOWN_8X mapping scheme.

Enumerator
UMBRA_MAP_SCALE_DOWN_4X | 8 app byte to 1 shadow byte
UMBRA_MAP_SCALE_DOWN_2X | 4 app byte to 1 shadow byte
UMBRA_MAP_SCALE_SAME_1X | 2 app byte to 1 shadow byte
UMBRA_MAP_SCALE_UP_2X | 1 app byte to 1 shadow byte

## ◆ umbra_shadow_memory_flags_t

enum umbra_shadow_memory_flags_t

Shadow memory creation flags used in umbra_create_shadow_memory.

Enumerator
UMBRA_CREATE_SHADOW_SHARED_READONLY | This is an optimization hint for reducing memory usage by allowing Umbra to map different application memory regions with identical shadow value to the same shared shadow memory block. Attempts to directly write shared shadow memory will cause exceptions that should be handled by the user. This allows user to control each individual shadow memory creation whether using special shared block or not.

## ◆ umbra_shadow_memory_type_t

enum umbra_shadow_memory_type_t

Shadow memory type.

Note
  : A shadow memory may have more than one type, e.g., an address in redzone of shared special shadow memory block will return value with both UMBRA_SHADOW_MEMORY_TYPE_SHARED and UMBRA_SHADOW_MEMORY_TYPE_REDZONE being set.

Enumerator
UMBRA_SHADOW_MEMORY_TYPE_UNKNOWN | Unknown memory type
UMBRA_SHADOW_MEMORY_TYPE_NOT_SHADOW | Not a shadow memory: i.e., the address being translated is not from a valid application memory region. Umbra does not support storing metadata in shadow memory for such addresses.
UMBRA_SHADOW_MEMORY_TYPE_NORMAL | Normal writable shadow memory
UMBRA_SHADOW_MEMORY_TYPE_SHARED | Special read-only shadow memory
UMBRA_SHADOW_MEMORY_TYPE_SHADOW_NOT_ALLOC | Should be shadow memory, but not allocated yet

## Function Documentation

## ◆ umbra_clear_redundant_blocks()

DR_EXPORT drmf_status_t umbra_clear_redundant_blocks | ( | umbra_map_t * | map,
|  | uint * | count
| ) |  |

Clears and deletes redundant blocks consisting of only default values for `map`. This function is typically invoked when low on memory. It deletes normal blocks and sets mapping entries to the special basic block.

The number of redundant blocks destroyed is returned via `count`. This is an optional parameter and can be set to NULL if the count is not wanted.

Assumes that threads are suspended so that Umbra may safely modify shadow memory. It is up to the caller to suspend and resume threads.

This feature is only available on 32-bit and requires that the create-on-touch optimization (UMBRA_MAP_CREATE_SHADOW_ON_TOUCH) is enabled.

## ◆ umbra_create_mapping()

DR_EXPORT drmf_status_t umbra_create_mapping | ( | IN umbra_map_options_t * | ops,
|  | OUT umbra_map_t ** | map_out
| ) |  |

Create a shadow memory mapping according to the mapping options `ops`, and return the opaque pointer in `map_out`.

Parameters

  [in] | ops | The mapping object to use.
  [out] | map_out | The mapping options.

## ◆ umbra_create_shadow_memory()

DR_EXPORT drmf_status_t umbra_create_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN umbra_shadow_memory_flags_t | flags,
|  | IN app_pc | app_addr,
|  | IN size_t | app_size,
|  | IN ptr_uint_t | value,
|  | IN size_t | value_size
| ) |  |

Create shadow memory for application memory using mapping scheme `map`.

Parameters

  [in] | map | The mapping object to use.
  [in] | flags | Shadow memory creation options.
  [in] | app_addr | Application memory address.
  [in] | app_size | Application memory size.
  [in] | value | The initial value in shadow memory.
  [in] | value_size | The initial value size, could be 1, 2, 4, or 8 (x64). Only 1 is supported now.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

Note
  : If the newly created shadow memory overlaps with the existing shadow memory, the value of overlapped part will be clobbered with new value.
  : The actual size of created shadow memory might be larger than the required size, the extended part will be set as default value specified on `map` creation.

## ◆ umbra_create_shared_shadow_block()

DR_EXPORT drmf_status_t umbra_create_shared_shadow_block | ( | IN umbra_map_t * | map,
|  | IN ptr_uint_t | value,
|  | IN size_t | value_size,
|  | OUT byte ** | block
| ) |  |

Create special shared shadow memory that Umbra can map different application regions with the same shadow value as `value` to it.

Parameters

  [in] | map | The mapping object to use.
  [in] | value | The value used by the shadow block.
  [in] | value_size | The value size used by the shadow block.
  [out] | block | The pointer pointing to the base of the shadow block. Returns NULL if Umbra fails to create one.

Note
  : Umbra only creates special shared shadow memory if necessary. This routine forces Umbra create one even Umbra may not use it.
  : Umbra does not use special shared shadow block in current x64 implementation and always returns DRMF_ERROR_FEATURE_NOT_AVAILABLE.

## ◆ umbra_delete_shadow_memory()

DR_EXPORT drmf_status_t umbra_delete_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | IN size_t | app_size
| ) |  |

Delete shadow memory from mapping scheme `map` for application memory at `app_addr`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | Application memory address.
  [in] | app_size | Application memory size.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

Note
  : part of the shadow memory might not be actually deleted, which will be set to the value specified on `map` creation instead.

## ◆ umbra_destroy_mapping()

DR_EXPORT drmf_status_t umbra_destroy_mapping | ( | IN umbra_map_t * | map | ) |

Destroy a shadow memory mapping `map` created by umbra_create_mapping.

## ◆ umbra_exit()

DR_EXPORT drmf_status_t umbra_exit | ( | void |  | ) |

Clean up the Umbra extension.

## ◆ umbra_get_shadow_block_size()

DR_EXPORT drmf_status_t umbra_get_shadow_block_size | ( | IN umbra_map_t * | map,
|  | OUT size_t * | size
| ) |  |

Get the shadow block size, which is the unit size Umbra allocates/frees the shadow memory.

Parameters

  [in] | map | The mapping object to use.
  [out] | size | The shadow memory block size.

## ◆ umbra_get_shadow_memory()

DR_EXPORT drmf_status_t umbra_get_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | OUT byte ** | shadow_addr,
|  | INOUT umbra_shadow_memory_info_t * | shadow_info
| ) |  |

Get shadow memory address for application memory address `app_addr`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | The application memory address.
  [out] | shadow_addr | The shadow memory address for `app_addr`.
  [in,out] | shadow_info | The information about the shadow memory for `app_addr`.

For lazily allocated shadow memory, this routine will not allocate shadow memory that is not yet allocated. The caller must explicitly call umbra_create_shadow_memory() prior to de-referencing the returned shadow address if the type is UMBRA_SHADOW_MEMORY_TYPE_SHADOW_NOT_ALLOC. Use umbra_read_shadow_memory() or umbra_write_shadow_memory() if automatic allocation is desired.

Note
  : `shadow_info->struct_size` must be set to `sizeof(umbra_shadow_memory_info_t)` for compatiblity.
  : `shadow_info` contains the information about the shadow memory block and its application memory, so the caller can cache the information and access the shadow memory later without querying Umbra again. However, if the shadow memory is a special shared memory block, it may be replaced with normal shadow memory and the caller will not see it, and the caller will see the old special value if using cached information. It is up to the caller to decide whether this is acceptable.
  : No redzone will be included in the `shadow_info`.

## ◆ umbra_get_shadow_memory_type()

DR_EXPORT drmf_status_t umbra_get_shadow_memory_type | ( | IN umbra_map_t * | map,
|  | IN byte * | shadow_addr,
|  | OUT umbra_shadow_memory_type_t * | shadow_type
| ) |  |

Get shadow memory type for address `shadow_addr`.

Parameters

  [in] | map | The mapping object to use.
  [in] | shadow_addr | The shadow memory address for `app_addr`.
  [out] | shadow_type | The type of the shadow memory at `shadow_addr`.

Note
  : this routine has high runtime overhead since it may need iterate all shadow memory to determine the shadow memory type for `shadow_addr`.

## ◆ umbra_get_shared_shadow_block()

DR_EXPORT drmf_status_t umbra_get_shared_shadow_block | ( | IN umbra_map_t * | map,
|  | IN ptr_uint_t | value,
|  | IN size_t | value_size,
|  | OUT byte ** | block
| ) |  |

Get special shared shadow memory created by umbra_create_shared_shadow_block or Umbra with identical `value` and `value_size`.

Parameters

  [in] | map | The mapping object to use.
  [in] | value | The value used by the shadow block.
  [in] | value_size | The value size used by the shadow block.
  [out] | block | The pointer pointing to the base of the shadow block. Returns NULL if Umbra fails to find one.

Note
  : Umbra does not use special shared shadow block in current x64 implementation and always returns DRMF_ERROR_FEATURE_NOT_AVAILABLE.

## ◆ umbra_init()

DR_EXPORT drmf_status_t umbra_init | ( | client_id_t | client_id | ) |

Initialize the Umbra extension. Must be called prior to any of the other routines. Can be called multiple times (by separate components, normally) but each call must be paired with a corresponding call to umbra_exit().

Parameters

  [in] | client_id | The client id for version check.

Returns
  success code.

## ◆ umbra_insert_app_to_shadow()

DR_EXPORT drmf_status_t umbra_insert_app_to_shadow | ( | IN void * | drcontext,
|  | IN umbra_map_t * | map,
|  | IN instrlist_t * | ilist,
|  | IN instr_t * | where,
|  | IN reg_id_t | addr_reg,
|  | IN reg_id_t * | scratch_regs,
|  | IN int | num_scratch_regs
| ) |  |

Insert instructions into `ilist` before `where` to translate application address stored in `reg_addr` to shadow address and store it into `reg_addr`.

Umbra may use page faults to implement lazy shadow memory allocation. When generating meta instructions to read shadow values, be sure to assign translation values to the instructions.

Parameters

  [in] | drcontext | The DynamoRIO context for current thread.
  [in] | map | The mapping object to use.
  [in] | ilist | The instruction list to be inserted into.
  [in] | where | The instruction to be inserted before
  [in] | addr_reg | The Register holding the application address for translation, and holding the shadow memory address after translation.
  [in] | scratch_regs | The array of scratch registers for use.
  [in] | num_scratch_regs | Number of scratch register

Note
  : `num_scratch_regs` must not be smaller than the value returned from umbra_num_scratch_regs_for_translation, otherwise error code DRMF_ERROR_NOT_ENOUGH_REGS is returned.
  : This method destroys aflags. Be sure to save and restore aflags before and after this method is called, e.g. with `drreg_reserve_aflags()`.

## ◆ umbra_iterate_app_memory()

DR_EXPORT drmf_status_t umbra_iterate_app_memory | ( | IN umbra_map_t * | map,
|  | IN void * | user_data,
|  | IN bool(*)(umbra_map_t *map, const dr_mem_info_t *info, void *user_data) | iter_func
| ) |  |

Iterate the application memory (i.e., any memory that are not part of shadow memory, DynamoRIO internal memory, or DynamoRIO's client memory).

Parameters

  [in] | map | The mapping object to use.
  [in] | user_data | The user data passed to `iter_func`.
  [in] | iter_func | The iterate callback function. It can return false to stop the iteration.

Note
  : the memory allocated by dr_raw_mem_alloc by client might be iterated since they are not considered as part of DynamoRIO internal or client memory.

## ◆ umbra_iterate_shadow_memory()

DR_EXPORT drmf_status_t umbra_iterate_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN void * | user_data,
|  | IN shadow_iterate_func_t | iter_func
| ) |  |

Iterate shadow memory and call `iter_func` on each shadow memory block.

Parameters

  [in] | map | The mapping object to use.
  [in] | user_data | The user data passed to `iter_func`.
  [in] | iter_func | The iterate callback function. It can return false to stop the iteration.

## ◆ umbra_num_scratch_regs_for_translation()

DR_EXPORT drmf_status_t umbra_num_scratch_regs_for_translation | ( | OUT int * | num_regs | ) |

Query the number of scratch registers needed (excluding the register holding the application address) for address translation from application memory to shadow memory.

Parameters

  [out] | num_regs | Number of scratch register required for translation.

## ◆ umbra_read_shadow_memory()

DR_EXPORT drmf_status_t umbra_read_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | IN size_t | app_size,
|  | INOUT size_t * | shadow_size,
|  | OUT byte * | buffer
| ) |  |

Read shadow memory for application memory at `app_addr` to `buffer`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | Application memory address.
  [in] | app_size | Application memory size.
  [in,out] | shadow_size | The max buffer size. Return the number of bytes actually read.
  [out] | buffer | The buffer holds the read value.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

## ◆ umbra_replace_shared_shadow_memory()

DR_EXPORT drmf_status_t umbra_replace_shared_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | OUT byte ** | shadow_addr
| ) |  |

Replace the special shared shadow memory for application address `app_addr` with normal writable shadow memory. Do nothing if it is already uses normal writable shadow memory or not allocated yet.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | The application memory address to be replaced.
  [out] | shadow_addr | Return the replaced shadow memory address.

## ◆ umbra_shadow_copy_range()

DR_EXPORT drmf_status_t umbra_shadow_copy_range | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_src,
|  | IN app_pc | app_dst,
|  | IN size_t | app_size,
|  | OUT size_t * | shadow_size
| ) |  |

Copy value from shadow memory for application memory at `app_src` to shadow memory for application memory at `app_dst`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_src | Source application memory address.
  [in] | app_dst | Destination application memory address.
  [in] | app_size | Application memory size.
  [out] | shadow_size | The number of bytes actually copied.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

Note
  : Overlap is allowed.

## ◆ umbra_shadow_memory_info_init()

static void umbra_shadow_memory_info_init | ( | umbra_shadow_memory_info_t * | info | ) |
| inline static

Convenience routine for initializing umbra_shadow_memory_info.

## ◆ umbra_shadow_memory_is_shared()

DR_EXPORT drmf_status_t umbra_shadow_memory_is_shared | ( | IN umbra_map_t * | map,
|  | IN byte * | shadow_addr,
|  | OUT umbra_shadow_memory_type_t * | shadow_type
| ) |  |

Similar to umbra_get_shadow_memory_type, but only check if `shadow_addr` is in a special shared shadow memory block. `shadow_type` is set to be UMBRA_SHADOW_MEMORY_TYPE_SHARED (optionally with UMBRA_SHADOW_MEMORY_TYPE_REDZONE also set) if `shadow_addr` is in any special shared shadow memory block and UMBRA_SHADOW_MEMORY_TYPE_UNKNOWN otherwise. If `shadow_addr` is in the redzone of a special shared shadow memory block, UMBRA_SHADOW_MEMORY_TYPE_REDZONE is also set along with UMBRA_SHADOW_MEMORY_TYPE_SHARED.

Parameters

  [in] | map | The mapping object to use.
  [in] | shadow_addr | The shadow memory address.
  [out] | shadow_type | The type of the shadow memory at `shadow_addr`.

Note
  : This is a routine for efficient check if `shadow_addr` is in a special shared shadow memory. UMBRA_SHADOW_MEMORY_TYPE_UNKNOWN is set even `shadow_addr` could be normal writable shadow memory.

## ◆ umbra_shadow_set_range()

DR_EXPORT drmf_status_t umbra_shadow_set_range | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | IN size_t | app_size,
|  | OUT size_t * | shadow_size,
|  | IN ptr_uint_t | value,
|  | IN size_t | value_size
| ) |  |

Set a range of shadow memory for application memory at `app_addr`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | Application memory address.
  [in] | app_size | Application memory size.
  [out] | shadow_size | The number of bytes actually written.
  [in] | value | The value to be set in shadow memory.
  [in] | value_size | The value size for `value`, could be 1, 2, 4, or 8 (x64). Only 1 is supported now.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

## ◆ umbra_value_in_shadow_memory()

DR_EXPORT drmf_status_t umbra_value_in_shadow_memory | ( | IN umbra_map_t * | map,
|  | INOUT app_pc * | app_addr,
|  | IN size_t | app_size,
|  | IN ptr_uint_t | value,
|  | IN size_t | value_size,
|  | OUT bool * | found
| ) |  |

Check whether `value` is in the shadow memory for application memory at `app_addr`.

Parameters

  [in] | map | The mapping object to use.
  [in,out] | app_addr | Starting application memory address. Return the application address at which if found.
  [in] | app_size | Application memory size.
  [in] | value | The value to be set in shadow memory.
  [in] | value_size | The value size for `value`, could be 1, 2, 4, or 8 (x64). Only 1 is supported now.
  [out] | found | Return true if `value` found in the range.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.

## ◆ umbra_write_shadow_memory()

DR_EXPORT drmf_status_t umbra_write_shadow_memory | ( | IN umbra_map_t * | map,
|  | IN app_pc | app_addr,
|  | IN size_t | app_size,
|  | INOUT size_t * | shadow_size,
|  | IN byte * | buffer
| ) |  |

Write shadow memory for application memory at `app_addr` from `buffer`.

Parameters

  [in] | map | The mapping object to use.
  [in] | app_addr | Application memory address.
  [in] | app_size | Application memory size.
  [in,out] | shadow_size | The max buffer size. Return the number of bytes actually written.
  [in] | buffer | The buffer holds the value to write.

Returns
  success code. If `app_addr` is not a valid application address and the shadow mapping implementation does not support shadow memory for invalid addresses, returns DRMF_ERROR_INVALID_ADDRESS.