--- title: "umbra.h File Reference" layout: default permalink: /umbra_8h.html ---
Dr. Memory
|
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_EXCPT_UMBRA = -100 } |
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) |
Header for Umbra: DynamoRIO Shadow Memory Extension.
#define DRMGR_PRIORITY_NAME_EXCPT_UMBRA "umbra_except" |
Name of Umbra signal/exception events.
#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 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.
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.
[in] | map | The mapping object to use. |
[in] | info | Information about the shadow memory. |
[in] | user_data | User data passed during iteration. |
typedef struct _umbra_map_options_t umbra_map_options_t |
Specifies parameters controlling the behavior of umbra_create_map().
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(),
typedef struct _umbra_shadow_memory_info_t umbra_shadow_memory_info_t |
Information about a shadow memory region.
anonymous enum |
enum umbra_map_flags_t |
Umbra mapping creation flags for fine-grained control
enum umbra_map_scale_t |
Shadow memory mapping (scaling) schemes supported by Umbra.
app_addr
will be aligned to 8 if using UMBRA_MAP_SCALE_DOWN_8X mapping scheme. Shadow memory creation flags used in umbra_create_shadow_memory.
Shadow memory type.
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.
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
.
[in] | ops | The mapping object to use. |
[out] | map_out | The mapping options. |
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
.
[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. |
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.map
creation. 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.
[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. |
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
.
[in] | map | The mapping object to use. |
[in] | app_addr | Application memory address. |
[in] | app_size | Application memory size. |
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.map
creation instead. DR_EXPORT drmf_status_t umbra_destroy_mapping | ( | IN umbra_map_t * | map | ) |
Destroy a shadow memory mapping map
created by umbra_create_mapping.
DR_EXPORT drmf_status_t umbra_exit | ( | void | ) |
Clean up the Umbra extension.
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.
[in] | map | The mapping object to use. |
[out] | size | The shadow memory block size. |
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
.
[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.
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.shadow_info
. 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
.
[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 . |
shadow_addr
. 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
.
[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. |
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().
[in] | client_id | The client id for version check. |
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.
[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 |
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.drreg_reserve_aflags()
. 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).
[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. |
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.
[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. |
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.
[out] | num_regs | Number of scratch register required for translation. |
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
.
[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. |
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. 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.
[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. |
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
.
[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. |
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.
|
inlinestatic |
Convenience routine for initializing umbra_shadow_memory_info.
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.
[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 . |
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. 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
.
[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. |
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. 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
.
[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. |
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. 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
.
[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. |
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.