DynamoRIO API
IA-32/AMD64/ARM/AArch64 Disassembly Library

DynamoRIO can be used as a standalone library for IA-32/AMD64/ARM/AArch64 disassembly, decoding, encoding, and general instruction manipulation, independently of controlling a target application. When used in this way, all aspects of DynamoRIO's API routines that apply to instrumentation or application control are not applicable; however, the full, rich instruction set API is enabled. For further information on the instruction set API see the following sections of the Code Manipulation API:

Using DynamoRIO as a Standalone Library

DynamoRIO can be used as a regular third-party library for a standalone application (instead of a client that operates on a target program). Two options are provided: using the regular DynamoRIO shared library, or using a special static library drdecode. The shared library provides not only decoding routines but also cross-platform resources such as file manipulation.

When using the DynamoRIO shared library, this initialization routine must be called prior to using any API routines:

This routine returns a dummy context that can be passed to API routines.

When using drdecode, the special context GLOBAL_DCONTEXT should be used whenever a context is required. The drdecode library does not require initialization.

Neither the context returned by dr_standalone_init() nor GLOBAL_DCONTEXT can be used as the drcontext for a thread running under DynamoRIO control! It is only for standalone programs that wish to use DynamoRIO as a library of routines for IA-32 instruction manipulation or other purposes.

In standalone mode, the dr_set_isa_mode() routine operates globally rather than per-thread.

Runtime options are ignored in standalone mode. Disassembly style can be controlled via disassemble_set_syntax(). The processor to use will not be automatically set and will be assumed to be VENDOR_INTEL. Use proc_set_vendor() to set to VENDOR_AMD instead.

Some DynamoRIO API routines are not supported in standalone mode. These include all event registration routines, module iteration, dr_memory_protect(), dr_messagebox(), dr_get_current_drcontext(), dr_get_thread_id(), tls fields, dr_thread_yield(), dr_sleep(), client threads, suspending threads, itimers, register spilling and restoring, dr_redirect_execution(), try/except, and code cache routines (e.g., dr_delete_fragment() or flush routines).

When using the drdecode library, no API routines other than those involving decoding, encoding, disassembling, instruction lists, instructions, or operands are supported. The various compute_address routines can be used by manually filling in dr_mcontext_t, although far memory references will have their segment base ignored. Other API routines are simply not present in the static library. There is no separate set of headers for use with drdecode.

When using DynamoRIO's CMake support, use the configure_DynamoRIO_decoder() function to set up include directories and to link with drdecode. The next section describes how to link with the DynamoRIO shared library.

Re-Relativization of Jumps and Calls

When encoding a relative jump or call to a different location than it was decoded from while in standalone mode, a re-encode must be forced in order to work around an issue where DynamoRIO does not re-relativize the target:

When not in standalone mode, all branches are mangled and thus this is never an issue. This should be fixed in a future release.

DynamoRIO Shared Library Issues

Since the DynamoRIO library on Windows includes or forwards implementations of certain C library routines (see C library utilities), standalone applications linking to both DynamoRIO and the C library may experience linker errors when building and floating point problems when running. To avoid these problems, explicitly list the C runtime library on the command line:

/link /nodefaultlib libcmt.lib dynamorio.lib

DynamoRIO writes to stderr and stdout using raw system calls, which can interfere with the buffering of library routines. When mixing use of printf or fprintf with DynamoRIO output (including not only dr_printf() and dr_fprintf() but also passing STDOUT or STDERR to routines like disassemble()), you may need to flush between library printing and DynamoRIO printing (e.g., using fflush(stdout)) to ensure that the library output is visible.

The binary tracedump reader (Use of Standalone API) is an example of use of DynamoRIO as a standalone library.

When building an application that uses DynamoRIO as a standalone library, follow the steps for Building a Client to include the header files and link with the DynamoRIO library, but omit the linker flags requesting no standard libraries or startup files. DynamoRIO's CMake support does this automatically via the configure_DynamoRIO_standalone() function.