dr_os_utils.h File Reference

Operating-system-specific querying routines. More...

Data Structures

struct  _dr_app_arg_t
 
struct  _dr_os_version_info_t
 
struct  _dr_mem_info_t
 

Macros

#define DR_MEMPROT_NONE   0x00
 
#define DR_MEMPROT_READ   0x01
 
#define DR_MEMPROT_WRITE   0x02
 
#define DR_MEMPROT_EXEC   0x04
 
#define DR_MEMPROT_GUARD   0x08
 
#define DR_MEMPROT_PRETEND_WRITE   0x10
 
#define DR_MEMPROT_VDSO   0x20
 
#define PAGE_SIZE   dr_page_size()
 
#define PAGE_START(x)   (((ptr_uint_t)(x)) & ~(dr_page_size() - 1))
 
#define DR_TRY_EXCEPT(drcontext, try_statement, except_statement)
 

Typedefs

typedef struct _dr_app_arg_t dr_app_arg_t
 
typedef struct _dr_os_version_info_t dr_os_version_info_t
 
typedef void * dr_auxlib_handle_t
 
typedef void(* dr_auxlib_routine_ptr_t) ()
 
typedef struct _dr_mem_info_t dr_mem_info_t
 

Enumerations

enum  dr_state_flags_t {
  DR_STATE_PEB = 0x0001,
  DR_STATE_TEB_MISC = 0x0002,
  DR_STATE_STACK_BOUNDS = 0x0004,
  DR_STATE_ALL = ~0
}
 
enum  dr_app_arg_encoding_t {
  DR_APP_ARG_CSTR_COMPAT,
  DR_APP_ARG_UTF_16
}
 
enum  dr_os_version_t {
  DR_WINDOWS_VERSION_10_1803 = 105,
  DR_WINDOWS_VERSION_10_1709 = 104,
  DR_WINDOWS_VERSION_10_1703 = 103,
  DR_WINDOWS_VERSION_10_1607 = 102,
  DR_WINDOWS_VERSION_10_1511 = 101,
  DR_WINDOWS_VERSION_10 = 100,
  DR_WINDOWS_VERSION_8_1 = 63,
  DR_WINDOWS_VERSION_2012_R2 = DR_WINDOWS_VERSION_8_1,
  DR_WINDOWS_VERSION_8 = 62,
  DR_WINDOWS_VERSION_2012 = DR_WINDOWS_VERSION_8,
  DR_WINDOWS_VERSION_7 = 61,
  DR_WINDOWS_VERSION_2008_R2 = DR_WINDOWS_VERSION_7,
  DR_WINDOWS_VERSION_VISTA = 60,
  DR_WINDOWS_VERSION_2008 = DR_WINDOWS_VERSION_VISTA,
  DR_WINDOWS_VERSION_2003 = 52,
  DR_WINDOWS_VERSION_XP_X64 = DR_WINDOWS_VERSION_2003,
  DR_WINDOWS_VERSION_XP = 51,
  DR_WINDOWS_VERSION_2000 = 50,
  DR_WINDOWS_VERSION_NT = 40
}
 
enum  dr_mem_type_t {
  DR_MEMTYPE_FREE,
  DR_MEMTYPE_IMAGE,
  DR_MEMTYPE_DATA,
  DR_MEMTYPE_RESERVED,
  DR_MEMTYPE_ERROR,
  DR_MEMTYPE_ERROR_WINKERNEL
}
 

Functions

DR_API bool dr_using_app_state (void *drcontext)
 
DR_API void dr_switch_to_app_state (void *drcontext)
 
DR_API void dr_switch_to_app_state_ex (void *drcontext, dr_state_flags_t flags)
 
DR_API void dr_switch_to_dr_state (void *drcontext)
 
DR_API void dr_switch_to_dr_state_ex (void *drcontext, dr_state_flags_t flags)
 
DR_API int dr_get_app_args (DR_PARAM_OUT dr_app_arg_t *args_array, int args_count)
 
DR_API int dr_num_app_args (void)
 
const DR_API char * dr_app_arg_as_cstring (DR_PARAM_IN dr_app_arg_t *app_arg, char *buf, int buf_size)
 
const DR_API char * dr_get_application_name (void)
 
DR_API process_id_t dr_get_process_id (void)
 
DR_API process_id_t dr_get_process_id_from_drcontext (void *drcontext)
 
DR_API process_id_t dr_get_parent_id (void)
 
DR_API bool dr_get_os_version (dr_os_version_info_t *info)
 
DR_API bool dr_is_wow64 (void)
 
DR_API void * dr_get_app_PEB (void)
 
DR_API process_id_t dr_convert_handle_to_pid (HANDLE process_handle)
 
DR_API HANDLE dr_convert_pid_to_handle (process_id_t pid)
 
DR_API dr_auxlib_handle_t dr_load_aux_library (const char *name, byte **lib_start, byte **lib_end)
 
DR_API dr_auxlib_routine_ptr_t dr_lookup_aux_library_routine (dr_auxlib_handle_t lib, const char *name)
 
DR_API bool dr_unload_aux_library (dr_auxlib_handle_t lib)
 
DR_API size_t dr_page_size (void)
 
DR_API bool dr_memory_is_readable (const byte *pc, size_t size)
 
DR_API bool dr_query_memory (const byte *pc, byte **base_pc, size_t *size, uint *prot)
 
DR_API bool dr_query_memory_ex (const byte *pc, DR_PARAM_OUT dr_mem_info_t *info)
 
DR_API size_t dr_virtual_query (const byte *pc, MEMORY_BASIC_INFORMATION *mbi, size_t mbi_size)
 
DR_API bool dr_safe_read (const void *base, size_t size, void *out_buf, size_t *bytes_read)
 
DR_API bool dr_safe_write (void *base, size_t size, const void *in_buf, size_t *bytes_written)
 
DR_API void dr_try_setup (void *drcontext, void **try_cxt)
 
DR_API int dr_try_start (void *buf)
 
DR_API void dr_try_stop (void *drcontext, void *try_cxt)
 
DR_API bool dr_memory_protect (void *base, size_t size, uint new_prot)
 
DR_API bool dr_memory_is_dr_internal (const byte *pc)
 
DR_API bool dr_memory_is_in_client (const byte *pc)
 

Detailed Description

Operating-system-specific querying routines.

Macro Definition Documentation

◆ DR_MEMPROT_EXEC

#define DR_MEMPROT_EXEC   0x04

Execute privileges.

◆ DR_MEMPROT_GUARD

#define DR_MEMPROT_GUARD   0x08

Guard page (Windows only)

◆ DR_MEMPROT_NONE

#define DR_MEMPROT_NONE   0x00

No read, write, or execute privileges.

◆ DR_MEMPROT_PRETEND_WRITE

#define DR_MEMPROT_PRETEND_WRITE   0x10

DR's default cache consistency strategy modifies the page protection of pages containing code, making them read-only. It pretends on application and client queries that the page is writable. On a write fault to such a region by the application or by client-added instrumentation, DR automatically handles the fault and makes the page writable. This requires flushing the code from the code cache, which can only be done safely when in an application context. Thus, a client writing to such a page is only supported when these criteria are met:

  1. The client code must be in an application code cache context. This rules out all event callbacks (including the basic block event) except for the pre and post system call events and the nudge event.
  2. The client must not hold any locks. An exception is a lock marked as an application lock (via dr_mutex_mark_as_app(), dr_rwlock_mark_as_app(), or dr_recurlock_mark_as_app()).
  3. The client code must not rely on returning to a particular point in the code cache, as that point might be flushed and removed during the write fault processing. This rules out a clean call (unless dr_redirect_execution() is used), but does allow something like drwrap_replace_native() which uses a continuation strategy.

A client write fault that does not meet the first two criteria will result in a fatal error report and an abort. It is up to the client to ensure it satisifies the third criterion.

Even when client writes do meet these criteria, for performance it's best for clients to avoid writing to such memory.

◆ DR_MEMPROT_READ

#define DR_MEMPROT_READ   0x01

Read privileges.

◆ DR_MEMPROT_VDSO

#define DR_MEMPROT_VDSO   0x20

In addition to the appropriate DR_MEMPROT_READ and/or DR_MEMPROT_EXEC flags, this flag will be set for the VDSO and VVAR pages on Linux. The VVAR pages may only be identified by DR on kernels that explicitly label the pages in the /proc/self/maps file (kernel 3.15 and above). In some cases, accessing the VVAR pages can cause problems (e.g., https://github.com/DynamoRIO/drmemory/issues/1778).

◆ DR_MEMPROT_WRITE

#define DR_MEMPROT_WRITE   0x02

Write privileges.

◆ DR_TRY_EXCEPT

#define DR_TRY_EXCEPT (   drcontext,
  try_statement,
  except_statement 
)
Value:
do { \
void *try_cxt; \
dr_try_setup(drcontext, &try_cxt); \
if (dr_try_start(try_cxt) == 0) { \
try_statement dr_try_stop(drcontext, try_cxt); \
} else { \
/* roll back first in case except faults or returns */ \
dr_try_stop(drcontext, try_cxt); \
except_statement \
} \
} while (0)

Simple try..except support for executing operations that might fault and recovering if they do. Be careful with this feature as it has some limitations:

  • do not use a return within a try statement (we do not have language support)
  • any automatic variables that you want to use in the except block should be declared volatile
  • no locks should be grabbed in a try statement (because there is no finally support to release them)
  • nesting is supported, but finally statements are not supported

For fault-free reads in isolation, use dr_safe_read() instead. dr_safe_read() out-performs DR_TRY_EXCEPT.

For fault-free writes in isolation, dr_safe_write() can be used, although on Windows it invokes a system call and can be less performant than DR_TRY_EXCEPT.

◆ PAGE_SIZE

#define PAGE_SIZE   dr_page_size()

Size of a page of memory. This uses a function call so be careful where performance is critical.

◆ PAGE_START

#define PAGE_START (   x)    (((ptr_uint_t)(x)) & ~(dr_page_size() - 1))

Convenience macro to align to the start of a page of memory. It uses a function call so be careful where performance is critical.

Typedef Documentation

◆ dr_app_arg_t

typedef struct _dr_app_arg_t dr_app_arg_t

Contains information regarding an application's command-line argument.

◆ dr_auxlib_handle_t

typedef void* dr_auxlib_handle_t

A handle to a loaded client auxiliary library. This is a different type than module_handle_t and is not necessarily the base address.

◆ dr_auxlib_routine_ptr_t

typedef void(* dr_auxlib_routine_ptr_t) ()

An exported routine in a loaded client auxiliary library.

◆ dr_mem_info_t

typedef struct _dr_mem_info_t dr_mem_info_t

Describes a memory region. Used by dr_query_memory_ex().

◆ dr_os_version_info_t

Data structure used with dr_get_os_version()

Enumeration Type Documentation

◆ dr_app_arg_encoding_t

Encodings of an application's command-line argument.

Enumerator
DR_APP_ARG_CSTR_COMPAT 

C String Encoding.

DR_APP_ARG_UTF_16 

UTF 16 String Encoding.

◆ dr_mem_type_t

Flags describing memory used by dr_query_memory_ex().

Enumerator
DR_MEMTYPE_FREE 

No memory is allocated here

DR_MEMTYPE_IMAGE 

An executable file is mapped here

DR_MEMTYPE_DATA 

Some other data is allocated here

DR_MEMTYPE_RESERVED 

Reserved address space with no physical storage

DR_MEMTYPE_ERROR 

Query failed for unspecified reason

DR_MEMTYPE_ERROR_WINKERNEL 

Query failed due to the address being located in Windows kernel space. No further information is available so iteration must stop.

◆ dr_os_version_t

Windows versions

Enumerator
DR_WINDOWS_VERSION_10_1803 

Windows 10 1803 major update.

DR_WINDOWS_VERSION_10_1709 

Windows 10 1709 major update.

DR_WINDOWS_VERSION_10_1703 

Windows 10 1703 major update.

DR_WINDOWS_VERSION_10_1607 

Windows 10 1607 major update.

DR_WINDOWS_VERSION_10_1511 

Windows 10 TH2 1511. For future Windows updates that change system call numbers, we'll perform our own artificial minor version number update as done here, and use the YYMM version as the sub-name, as officially the OS version will supposedly remain 10.0 forever.

DR_WINDOWS_VERSION_10 

Windows 10 pre-TH2

DR_WINDOWS_VERSION_8_1 

Windows 8.1

DR_WINDOWS_VERSION_2012_R2 

Windows Server 2012 R2

DR_WINDOWS_VERSION_8 

Windows 8

DR_WINDOWS_VERSION_2012 

Windows Server 2012

DR_WINDOWS_VERSION_7 

Windows 7

DR_WINDOWS_VERSION_2008_R2 

Windows Server 2008 R2

DR_WINDOWS_VERSION_VISTA 

Windows Vista

DR_WINDOWS_VERSION_2008 

Windows Server 2008

DR_WINDOWS_VERSION_2003 

Windows Server 2003

DR_WINDOWS_VERSION_XP_X64 

Windows XP 64-bit

DR_WINDOWS_VERSION_XP 

Windows XP

DR_WINDOWS_VERSION_2000 

Windows 2000

DR_WINDOWS_VERSION_NT 

Windows NT

◆ dr_state_flags_t

Flags that control the behavior of dr_switch_to_app_state_ex() and dr_switch_to_dr_state_ex().

Enumerator
DR_STATE_PEB 

Switch the PEB pointer.

DR_STATE_TEB_MISC 

Switch miscellaneous TEB fields.

DR_STATE_STACK_BOUNDS 

Switch the TEB stack bounds fields.

DR_STATE_ALL 

Switch all state.

Function Documentation

◆ dr_app_arg_as_cstring()

const DR_API char* dr_app_arg_as_cstring ( DR_PARAM_IN dr_app_arg_t app_arg,
char *  buf,
int  buf_size 
)

Returns the passed argument app_arg as a string. buf is used only if needed, and therefore the caller should not assume that the string is in the buf. In other words, always use the returned value to refer to the string. Returns NULL on error such as when buf is needed as storage and the size of the buffer buf_size is not sufficient.

To obtain a suitable upper-bound size of the string buffer, get the size of the argument from the dr_app_arg_t value retrieved via dr_get_app_args().

Note
Currently, this function is only available on Unix with early injection.
An error code may be obtained via dr_get_error_code() when this routine fails.

◆ dr_convert_handle_to_pid()

DR_API process_id_t dr_convert_handle_to_pid ( HANDLE  process_handle)

Converts a process handle to a process id.

Returns
Process id if successful; INVALID_PROCESS_ID on failure.
Note
Windows only.

◆ dr_convert_pid_to_handle()

DR_API HANDLE dr_convert_pid_to_handle ( process_id_t  pid)

Converts a process id to a process handle.

Returns
Process handle if successful; INVALID_HANDLE_VALUE on failure.
Note
Windows only.

◆ dr_get_app_args()

DR_API int dr_get_app_args ( DR_PARAM_OUT dr_app_arg_t args_array,
int  args_count 
)

Provides information about the app's arguments by setting args_array up to the count denoted by args_count. Therefore, args_count is not the size of the buffer in bytes but the number of dr_app_arg_t values that args_array can store. Returns the number of args set or -1 on error.

Use dr_app_arg_as_cstring() to get the argument as a string.

Use dr_num_app_args() to query the total number of command-line arguments passed to the application.

Note
Currently, this function is only available on Unix with early injection.
An error code may be obtained via dr_get_error_code() when this routine fails.

◆ dr_get_app_PEB()

DR_API void* dr_get_app_PEB ( void  )

Returns a pointer to the application's Process Environment Block (PEB). DR swaps to a private PEB when running client code, in order to isolate the client and its dependent libraries from the application, so conventional methods of reading the PEB will obtain the private PEB instead of the application PEB.

Note
Windows only.

◆ dr_get_application_name()

const DR_API char* dr_get_application_name ( void  )

Returns the image name (without path) of the current application.

◆ dr_get_os_version()

DR_API bool dr_get_os_version ( dr_os_version_info_t info)

Returns information about the version of the operating system. Returns whether successful.

Note
Windows only.
The Windows API routine GetVersionEx may hide distinctions between versions, such as between Windows 8 and Windows 8.1. DR reports the true low-level version.

◆ dr_get_parent_id()

DR_API process_id_t dr_get_parent_id ( void  )

Returns the process id of the parent of the current process.

Note
Linux only.

◆ dr_get_process_id()

DR_API process_id_t dr_get_process_id ( void  )

Returns the process id of the current process.

◆ dr_get_process_id_from_drcontext()

DR_API process_id_t dr_get_process_id_from_drcontext ( void *  drcontext)

Returns the process id of the process associated with drcontext drcontext. The returned value may be different from dr_get_process_id() if the passed context was created in a different process, which may happen in thread exit callbacks.

◆ dr_is_wow64()

DR_API bool dr_is_wow64 ( void  )

Returns true if this process is a 32-bit process operating on a 64-bit Windows kernel, known as Windows-On-Windows-64, or WOW64. Returns false otherwise.

Note
Windows only.

◆ dr_load_aux_library()

DR_API dr_auxlib_handle_t dr_load_aux_library ( const char *  name,
byte **  lib_start,
byte **  lib_end 
)

Loads the library with the given path as an auxiliary client library. The library is not treated as an application module but as an extension of DR. The library will be included in dr_memory_is_in_client() and any faults in the library will be considered client faults. The bounds of the loaded library are returned in the optional out variables. On failure, returns NULL.

If only a filename and not a full path is given, this routine will search for the library in the standard search locations for DR's private loader.

◆ dr_lookup_aux_library_routine()

DR_API dr_auxlib_routine_ptr_t dr_lookup_aux_library_routine ( dr_auxlib_handle_t  lib,
const char *  name 
)

Looks up the exported routine with the given name in the given client auxiliary library loaded by dr_load_aux_library(). Returns NULL on failure.

◆ dr_memory_is_dr_internal()

DR_API bool dr_memory_is_dr_internal ( const byte *  pc)

Returns true iff pc is memory allocated by DR for its own purposes, and would not exist if the application were run natively.

◆ dr_memory_is_in_client()

DR_API bool dr_memory_is_in_client ( const byte *  pc)

Returns true iff pc is located inside a client library, an Extension library used by a client, or an auxiliary client library (see dr_load_aux_library()).

◆ dr_memory_is_readable()

DR_API bool dr_memory_is_readable ( const byte *  pc,
size_t  size 
)

Checks to see that all bytes with addresses in the range [pc, pc + size - 1] are readable and that reading from that range won't generate an exception (see also dr_safe_read() and DR_TRY_EXCEPT()).

Note
Nothing guarantees that the memory will stay readable for any length of time.
On Linux, especially if the app is in the middle of loading a library and has not properly set up the .bss yet, a page that seems readable can still generate SIGBUS if beyond the end of an mmapped file. Use dr_safe_read() or DR_TRY_EXCEPT() to avoid such problems.

◆ dr_memory_protect()

DR_API bool dr_memory_protect ( void *  base,
size_t  size,
uint  new_prot 
)

Modifies the memory protections of the region from start through start + size. Modification of memory allocated by DR or of the DR or client libraries themselves is allowed under the assumption that the client knows what it is doing. Modification of the ntdll.dll library on Windows is not allowed. Returns true if successful.

◆ dr_num_app_args()

DR_API int dr_num_app_args ( void  )

Returns the number of command-line arguments passed to the application.

Note
Currently, this function is only available on Unix with early injection.
An error code may be obtained via dr_get_error_code() when this routine fails.

◆ dr_page_size()

DR_API size_t dr_page_size ( void  )

Returns the size of a page of memory.

◆ dr_query_memory()

DR_API bool dr_query_memory ( const byte *  pc,
byte **  base_pc,
size_t *  size,
uint *  prot 
)

An os neutral method for querying a memory address. Returns true iff a memory region containing pc is found. If found additional information about the memory region is returned in the optional out arguments base_pc, size, and prot where base_pc is the start address of the memory region continaing pc, size is the size of said memory region and prot is an ORed combination of DR_MEMPROT_* flags describing its current protection.

Note
To examine only application memory, skip memory for which dr_memory_is_dr_internal() or dr_memory_is_in_client() returns true.
DR may mark writable code pages as read-only but pretend they're writable. When this happens, it will include both DR_MEMPROT_WRITE and DR_MEMPROT_PRETEND_WRITE in prot.

◆ dr_query_memory_ex()

DR_API bool dr_query_memory_ex ( const byte *  pc,
DR_PARAM_OUT dr_mem_info_t info 
)

Provides additional information beyond dr_query_memory(). Returns true if it was able to obtain information (including about free regions) and sets the fields of info. This routine can be used to iterate over the entire address space. Such an iteration should stop on reaching the top of the address space, or on reaching kernel memory (look for DR_MEMTYPE_ERROR_WINKERNEL) on Windows.

Returns false on failure and sets info->type to a DR_MEMTYPE_ERROR* code indicating the reason for failure.

Note
To examine only application memory, skip memory for which dr_memory_is_dr_internal() returns true.
DR may mark writable code pages as read-only but pretend they're writable. When this happens, it will include both DR_MEMPROT_WRITE and DR_MEMPROT_PRETEND_WRITE in info->prot.

◆ dr_safe_read()

DR_API bool dr_safe_read ( const void *  base,
size_t  size,
void *  out_buf,
size_t *  bytes_read 
)

Safely reads size bytes from address base into buffer out_buf. Reading is done without the possibility of an exception occurring. Returns true if the entire size bytes were read; otherwise returns false and if bytes_read is non-NULL returns the partial number of bytes read in bytes_read.

Note
See also DR_TRY_EXCEPT().

◆ dr_safe_write()

DR_API bool dr_safe_write ( void *  base,
size_t  size,
const void *  in_buf,
size_t *  bytes_written 
)

Safely writes size bytes from buffer in_buf to address base. Writing is done without the possibility of an exception occurring. Returns true if the entire size bytes were written; otherwise returns false and if bytes_written is non-NULL returns the partial number of bytes written in bytes_written.

Note
See also DR_TRY_EXCEPT().

◆ dr_switch_to_app_state()

DR_API void dr_switch_to_app_state ( void *  drcontext)

Equivalent to dr_switch_to_app_state_ex(drcontext, DR_STATE_ALL).

◆ dr_switch_to_app_state_ex()

DR_API void dr_switch_to_app_state_ex ( void *  drcontext,
dr_state_flags_t  flags 
)

Swaps to the application version of any system state for the given thread. This is meant to be used prior to examining application memory, when private libraries are in use and there are two versions of system state. Invoking non-DR library routines while the application state is in place can lead to unpredictable results: call dr_switch_to_dr_state() (or the _ex version) before doing so.

This function does not affect whether the current machine context (registers) contains application state or not.

The flags argument allows selecting a subset of the state to swap.

◆ dr_switch_to_dr_state()

DR_API void dr_switch_to_dr_state ( void *  drcontext)

Equivalent to dr_switch_to_dr_state_ex(drcontext, DR_STATE_ALL).

◆ dr_switch_to_dr_state_ex()

DR_API void dr_switch_to_dr_state_ex ( void *  drcontext,
dr_state_flags_t  flags 
)

Should only be called after calling dr_switch_to_app_state() (or the _ex version), or in certain cases where a client is running its own code in an application state. Swaps from the application version of system state for the given thread back to the DR and client version.

This function does not affect whether the current machine context (registers) contains application state or not.

A client must call dr_switch_to_dr_state() in order to safely call private library routines if it is running in an application context where dr_using_app_state() returns true. On Windows, this is the case for any application context, as the system state is always swapped. On Linux, however, execution of application code in the code cache only swaps the machine context and not the system state. Thus, on Linux, while in the code cache, dr_using_app_state() will return false, and it is safe to invoke private library routines without calling dr_switch_to_dr_state(). Only if client or client-invoked code will examine a segment selector or descriptor does the state need to be swapped. A state swap is much more expensive on Linux (it requires a system call) than on Windows.

The same flags that were passed to dr_switch_to_app_state_ex() should be passed here.

◆ dr_try_setup()

DR_API void dr_try_setup ( void *  drcontext,
void **  try_cxt 
)

Do not call this directly: use the DR_TRY_EXCEPT macro instead.

◆ dr_try_start()

DR_API int dr_try_start ( void *  buf)

Do not call this directly: use the DR_TRY_EXCEPT macro instead.

◆ dr_try_stop()

DR_API void dr_try_stop ( void *  drcontext,
void *  try_cxt 
)

Do not call this directly: use the DR_TRY_EXCEPT macro instead.

◆ dr_unload_aux_library()

DR_API bool dr_unload_aux_library ( dr_auxlib_handle_t  lib)

Unloads the given library, which must have been loaded by dr_load_aux_library(). Returns whether successful.

◆ dr_using_app_state()

DR_API bool dr_using_app_state ( void *  drcontext)

Returns whether the given thread indicated by drcontext is currently using the application version of its system state.

See also
dr_switch_to_dr_state(), dr_switch_to_app_state().

This function does not indicate whether the machine context (registers) contains application state or not.

On Linux, DR very rarely switches the system state, while on Windows DR switches the system state to the DR and client version on every event callback or clean call.

◆ dr_virtual_query()

DR_API size_t dr_virtual_query ( const byte *  pc,
MEMORY_BASIC_INFORMATION *  mbi,
size_t  mbi_size 
)

Equivalent to the win32 API function VirtualQuery(). See that routine for a description of arguments and return values.

Note
Windows only.
DR may mark writable code pages as read-only but pretend they're writable. When this happens, this routine will indicate that the memory is writable. Call dr_query_memory() or dr_query_memory_ex() before attempting to write to application memory to ensure it's not read-only underneath.
DR_API void dr_try_stop(void *drcontext, void *try_cxt)
DR_API int dr_try_start(void *buf)