| /* ****************************************************************************** |
| * Copyright (c) 2010-2017 Google, Inc. All rights reserved. |
| * Copyright (c) 2011 Massachusetts Institute of Technology All rights reserved. |
| * Copyright (c) 2007-2010 VMware, Inc. All rights reserved. |
| * ******************************************************************************/ |
| |
| /* |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * * Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * * Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * * Neither the name of VMware, Inc. nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| */ |
| |
| /** |
| **************************************************************************** |
| **************************************************************************** |
| **************************************************************************** |
| \if vmsafe |
| \mainpage VMsafe In-Process API |
| \section VMsafe_intro Introduction |
| This document describes a component of the VMsafe model that provides control |
| at a process level and explains how to use it. For the rest of the document |
| this component shall be referred to as the VMsafe In-Process Runtime or VIPER. |
| |
| VIPER allows a user specified (via a Guest Agent) in-process agent (referred to |
| as client from now on) to monitor and modify the execution of any given |
| process. VIPER is different from the security agent on the security monitor VM |
| or an in-guest agent as neither of them provides direct control at the |
| process level because they are unaware of processes. VIPER on the other hand |
| is fully aware of process and resides within the address space of each one that |
| is intended to be monitored or controlled. It provides a finer grain of |
| control as it allows the user to decide which processes and what aspects of the |
| processes' execution to monitor and control. Also, a client is an optional |
| component for any VMsafe-based solution. The figure below gives an idea of how |
| VIPER fits in with other VMsafe components. All user- or ISV-provided parts of a |
| VMsafe solution are shown in blue and the VMsafe components in gray. |
| |
| \image html viper.png |
| \image rtf viper.png |
| \image latex viper.eps |
| |
| \else |
| \mainpage The DynamoRIO API |
| \endif |
| |
| \image html drlogo.png |
| \image rtf drlogo.png |
| |
| DynamoRIO is a <em>runtime code manipulation system</em> that supports |
| code transformations on any part of a program, <em>while it executes</em>. |
| DynamoRIO gives complete control over the runtime code stream and does not |
| limit transformations to trampoline insertion. DynamoRIO exports an |
| interface for building dynamic tools for a wide variety of uses: program |
| analysis and understanding, profiling, instrumentation, optimization, |
| translation, etc. DynamoRIO provides efficient, transparent, and |
| comprehensive manipulation of an unmodified application running on a stock |
| operating system (Windows, Linux, or Android) and commodity IA-32, AMD64, |
| ARM, and AArch64 hardware. See \ref sec_limit_platforms for details of |
| which platform combinations are fully supported. |
| |
| This document describes the DynamoRIO system and the various API's that it |
| exports for building custom tools. It is divided into the following |
| sections: |
| |
| - \subpage page_deploy |
| <br>How to run DynamoRIO. |
| |
| - \subpage using |
| <br>How to make use of DynamoRIO. |
| |
| \if vmsafe |
| - \subpage API_security |
| <br>An interface for customizing and applying the award-winning Memory |
| Firewall security software. |
| |
| - \subpage API_probe |
| <br>A powerful probe insertion interface that can operate with the code cache |
| or in a lighter-weight but more restrictive mode without code cache. |
| \endif |
| - \subpage API_BT |
| <br>DynamoRIO's full runtime code manipulation interface. |
| |
| \ifnot vmsafe |
| - \subpage page_standalone |
| <br>DynamoRIO can be used as a standalone library for IA-32/AMD64/ARM/AArch64 |
| disassembly, decoding, encoding, and general instruction manipulation. |
| A separate static library is provided for this purpose. |
| \endif |
| |
| - \subpage API_tutorial |
| <br>Gives a few short tutorials on using DynamoRIO. |
| |
| - \subpage API_samples |
| <br>Shows some sample use cases and reference implementations. |
| |
| - \subpage overview |
| <br>A description of the implementation of the DynamoRIO system. |
| |
| - \subpage release_notes |
| <br>Release notes for this release, including changes since prior |
| releases \ifnot vmsafe and plans for future releases \endif. |
| |
| - \subpage page_license |
| |
| <br> |
| |
| *************************************************************************** |
| *************************************************************************** |
| \page overview DynamoRIO System Details |
| |
| DynamoRIO is a system for runtime code manipulation that is efficient, |
| transparent, and comprehensive, able to observe and manipulate every |
| executed instruction in an unmodified application running on a stock |
| operating system and commodity hardware. |
| |
| *************************************************************************** |
| \section sec_intro Introduction |
| |
| DynamoRIO operates in user mode on a target process. It acts as a |
| <em>process virtual machine</em>, interposing between the application and |
| the operating system. It has a complete view of the application code |
| stream and acts as a runtime control point, allowing custom tools to be |
| embedded inside it: |
| |
| \image html interpose.png |
| \image rtf interpose.png |
| \image latex interpose.eps "Flow chart" width=10cm |
| |
| The application itself, along with the underlying operating system and |
| hardware, remain unchanged. DynamoRIO operates in native (non-virtual) |
| environments as well as inside guest operating systems running on virtual |
| machines. Tools created on top of DynamoRIO will operate without change |
| whether the underlying operating system is native or a virtual machine |
| guest. |
| |
| *************************************************************************** |
| \section sec_system System Operation |
| |
| DynamoRIO operates by shifting an application's execution from its original |
| instructions to a <em>code cache</em>, where the instructions can be freely |
| modified. DynamoRIO occupies the address space with the application and has |
| full control over execution, taking over whenever control leaves the code |
| cache or when the operating system directly transfers control to the |
| application (<em>kernel-mediated control transfers</em>): |
| |
| \image html flow-highlevel.png |
| \image rtf flow-highlevel.png |
| \image latex flow-highlevel.eps "Flow chart" width=10cm |
| |
| DynamoRIO copies the application code one <em>dynamic basic block</em> at a |
| time into its basic block code cache. A block that directly targets another |
| block already resident in the cache is linked to that block to avoid the |
| cost of returning to the DynamoRIO dispatcher. |
| |
| Frequently executed sequences of basic blocks are combined into |
| <em>traces</em>, which are placed in a separate code cache. DynamoRIO makes |
| these traces available via its interface for convenient access to hot |
| application code streams. |
| |
| The following figure shows the flow of control between the components of |
| DynamoRIO and its code caches: |
| |
| \image html flow.png |
| \image rtf flow.png |
| \image latex flow.eps "Flow chart" width=15cm |
| |
| The context switch is between DynamoRIO's operational state and the machine |
| state of the application: both are still within the same process. |
| |
| Indirect branches require dynamic resolution of their targets, which is |
| performed via an inlined table lookup or a compare to a known target |
| inlined into a trace. |
| |
| \section sec_sys_transp Transparency |
| |
| Transparency is an important requirement for DynamoRIO and its clients. |
| The subject is fully covered in \subpage transparency. |
| |
| \ifnot vmsafe |
| *************************************************************************** |
| \section sec_refs References |
| |
| The canonical reference for DynamoRIO is: |
| |
| - Derek Bruening.<br> |
| <a href="http://www.burningcutlery.com/derek/phd.html"> |
| Efficient, Transparent, and Comprehensive Runtime Code Manipulation</a>.<br> |
| Ph.D. Thesis, MIT, September 2004. |
| |
| Other publications describing DynamoRIO include: |
| |
| - Derek Bruening and Vladimir Kiriansky.<br> |
| <a href="http://www.burningcutlery.com/derek/docs/procshared-VEE08.pdf"> |
| Process-Shared and Persistent Code Caches</a>.<br> |
| International Conference on Virtual Execution Environments (VEE-08), March 2008.<br> |
| |
| - Derek Bruening, Vladimir Kiriansky, Timothy Garnett, and Sanjeev Banerji.<br> |
| <a href="http://www.burningcutlery.com/derek/docs/threadshared-CGO06.pdf"> |
| Thread-Shared Software Code Caches</a>.<br> |
| International Symposium on Code Generation and Optimization (CGO-06), March 2006.<br> |
| |
| - Derek Bruening and Saman Amarasinghe. <br> |
| <a href="http://www.burningcutlery.com/derek/docs/cacheconscap-CGO05.pdf"> |
| Maintaining Consistency and Bounding Capacity of Software Code Caches</a>.<br> |
| International Symposium on Code Generation and Optimization (CGO-05), March 2005. <br> |
| |
| - Gregory Sullivan, Derek Bruening, Iris Baron, Timothy Garnett, and |
| Saman Amarasinghe. <br> |
| <a href="http://www.burningcutlery.com/derek/docs/IVME03.pdf"> |
| Dynamic Native Optimization of Interpreters</a>. <br> |
| ACM Workshop on Interpreters, Virtual Machines and Emulators (IVME-03), June 2003.<br> |
| |
| - Derek Bruening, Timothy Garnett, and Saman Amarasinghe. <br> |
| <a href="http://www.burningcutlery.com/derek/docs/adaptive-CGO03.pdf"> |
| An Infrastructure for Adaptive Dynamic Optimization</a>. <br> |
| International Symposium on Code Generation and Optimization (CGO-03), March 2003. <br> |
| |
| - Derek Bruening, Evelyn Duesterwald, and Saman Amarasinghe.<br> |
| <a href="http://www.burningcutlery.com/derek/docs/win32-FDDO.pdf"> |
| Design and Implementation of a Dynamic Optimization Framework for Windows</a>.<br> |
| 4th ACM Workshop on Feedback-Directed and Dynamic |
| Optimization (FDDO-4), December 2001.<br> |
| |
| \endif |
| |
| \image html favicon.ico |
| |
| \page page_deploy Deployment |
| \if vmsafe |
| A DynamoRIO application consists of a guest agent and one or more clients. Each of |
| these must be linked against the necessary DynamoRIO dynamic libraries, which |
| are provided as part of the SDK. These DynamoRIO dynamic libraries must be |
| installed when the DynamoRIO application is installed on a guest OS. |
| |
| Any DynamoRIO application wanting to get control of a process must |
| first register a client (which is a self-contained executable |
| library) for that process. Otherwise DynamoRIO will not be |
| initialized for that process. This is done by the guest agent, which |
| can either be a service or a standalone executable. The guest agent |
| should use dr_register_process() and dr_register_client() to register |
| a process name for which control is desired, which clients to use for |
| each process, and which mode to run the clients in (more on this |
| below). DynamoRIO will be initialized in the specified mode for |
| registered processes started subsequently. DynamoRIO will then load |
| the corresponding clients into such processes and call each client's |
| initialization routine, dr_client_main(). There are three modes of operation |
| for DynamoRIO which map to the three API's provided by DynamoRIO |
| (see below). Depending upon the mode chosen the usage model will |
| change. |
| |
| In addition to registering the processes for which control is desired, the |
| guest agent can also unregister them as needed using dr_unregister_process(). |
| The guest agent can also send update messages to processes currently |
| initialized with DynamoRIO and a client using dr_nudge_process(). |
| For example, this can be used by the guest agent when it has obtained new |
| information (data, libraries, etc.), from a management server or over the |
| internet from a security vendor, to let clients know about them. |
| |
| Process registration, unregistration, and nudging require administrative |
| privileges. On Windows Vista or higher, if UAC is enabled, process registration must be |
| performed by an elevated (runas admin) process. When using the -syswide_on |
| parameter, be sure that the cmd shell being used was started with elevated |
| permissions. |
| |
| \else |
| |
| Once the DynamoRIO distribution contents are unpacked (see \ref |
| sec_package), configuration and execution of applications under DynamoRIO |
| is handled by a set of libraries and tools. On Windows, the |
| tools are \c drconfig.exe, \c drrun.exe, and \c drinject.exe. The |
| corresponding libraries (whose APIs are exposed by the tools) are \c |
| drconfiglib.dll and \c drinjectlib.dll with header files \c dr_config.h and |
| \c dr_inject.h. On Linux, the tools are named \c drconfig, \c drrun, and \c |
| drinject, and the libraries are \c libdrconfiglib.a and \c |
| libdrinjectlib.a. |
| |
| \ifnot vmsafe |
| When using DynamoRIO as a third-party disassembly library (see \ref |
| page_standalone), no deployment is needed, as DynamoRIO does not control a |
| target application when used as a regular library. |
| \endif |
| |
| \section win_deploy Windows Deployment |
| |
| There are two methods for running a process under DynamoRIO: the one-time |
| configure-and-run, and the two-step separate configuration and execution. |
| The \c drrun.exe tool supports the first, simpler model, while the \c |
| drconfig.exe and \c drinject.exe tools support the second, more powerful |
| model. The \c drconfig.exe tool, or the corresponding the \c |
| drconfiglib.dll library, can also be used to \ref sec_comm "nudge" running |
| processes. |
| |
| Configuration information is stored in files in the current user's profile |
| directory, which is obtained from the environment variable \c USERPROFILE. |
| Thus, configurations are persistent across reboots and are private to each |
| user. If the <tt>DYNAMORIO_CONFIGDIR</tt> environment variable is set, |
| its value is used instead of \c USERPROFILE. |
| If neither is set, a temp directory will be used when creating new |
| configuration files for configure-and-run execution. |
| |
| DynamoRIO also supports global configurations, which are stored in |
| the "config" subdirectory of the directory specified by the \c |
| DYNAMORIO_HOME registry value in the registry key \c |
| \\HKLM\\SOFTWARE\\DynamoRIO\\DynamoRIO (or for 32-bit on 64-bit Windows |
| (WOW64) \c \\HKLM\\SOFTWARE\\Wow6432Node\\DynamoRIO\\DynamoRIO). Setting |
| that \c DYNAMORIO_HOME value and creating the directory it points to must |
| be done manually. The provided tools support reading and writing both |
| local and global configuration files, and automatically creating the local |
| directory. DynamoRIO gives local files precedence when both exist. Note |
| that applications that do not have a \c USEPROFILE environment variable can |
| be controlled using <tt>DYNAMORIO_CONFIGDIR</tt> or global configurations. |
| Also note that by default \c USERPROFILE is not set over cygwin ssh and |
| must be explicitly set in the shell startup files. |
| |
| Configurations are per-process, with the basename of the process used for |
| identification (e.g., \c notepad.exe). One-time configuration also uses the |
| process id to specify that the configuration is for that process instance |
| only. |
| |
| As an example, assume you have unpacked the DynamoRIO distribution and |
| your current directory is its base directory. Run \c notepad.exe with the |
| bbsize sample client using the following configure-and-run command: |
| \if vmsafe |
| \code |
| bin32/drrun.exe -mode code -c samples/bin32/bbsize.dll -- notepad |
| \endcode |
| \else |
| \code |
| bin32/drrun.exe -c samples/bin32/bbsize.dll -- notepad |
| \endcode |
| \endif |
| |
| To use system-wide injection, allowing for an application to be run |
| under DynamoRIO regardless of how it is invoked, configure the application |
| first (-syswide_on requires administrative privileges): |
| \if vmsafe |
| \code |
| bin32/drconfig.exe -reg notepad.exe -syswide_on -mode code -c samples/bin32/bbsize.dll |
| \endcode |
| \else |
| \code |
| bin32/drconfig.exe -reg notepad.exe -syswide_on -c samples/bin32/bbsize.dll |
| \endcode |
| \endif |
| |
| The next time \c notepad.exe is started by the current user, it will run under |
| DynamoRIO with the bbsize client. |
| |
| To unregister \c notepad.exe, issue the following command: |
| \code |
| bin32/drconfig.exe -unreg notepad.exe |
| \endcode |
| |
| Invoke any of the \c drconfig.exe, \c drrun.exe, or \c drinject.exe tools |
| with no arguments to see the full list of options available. |
| |
| By default, DynamoRIO follows into all child processes, with the parent's |
| settings inherited by the child if there is no configuration set up ahead |
| of time for the child application. To instead only |
| follow children that are configured (via \c drconfig.exe), use the |
| \ref op_children "-no_follow_children" runtime option. |
| |
| To \ref sec_comm "nudge" all instances of \c notepad.exe running under |
| DynamoRIO with argument "5", use: |
| \code |
| bin32/drconfig.exe -nudge notepad.exe 0 5 |
| \endcode |
| This will result in a nudge event with argument=5 delivered to the |
| client callback registered with dr_register_nudge_event() in all |
| \c notepad.exe processes running under DynamoRIO. The third argument, |
| 0, is an ID supplied at registration which uniquely identifies the |
| target client (see dr_deploy.h for details). |
| |
| To view 32-bit or WOW64 processes running under DynamoRIO the |
| \c drview.exe tool can be used. The bin64 version will display both 32-bit |
| and 64-bit processes and will indicate which are 32-bit. The bin32 version |
| will display 64-bit processes but is unable to determine whether DynamoRIO |
| is present. |
| |
| \attention |
| Note that on Windows NT a reboot is required after using -syswide_on or -syswide_off. |
| |
| DynamoRIO uses the |
| <tt>\\HKLM\\SOFTWARE\\Microsoft\\Windows\\Windows NT\\CurrentVersion\\AppInit_DLLs</tt> |
| key |
| (for 32-bit on 64-bit Windows (WOW64), |
| <tt>\\HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\AppInit_DLLs</tt>) |
| for -syswide_on to inject into new processes without having to directly |
| launch them \c drrun.exe or \c drinject.exe. For injection to work, the |
| registered process must statically link to user32.dll (only a few small |
| non-graphical windows applications don't link user32.dll). If a target |
| application does not link to user32.dll, DynamoRIO can still inject if the |
| process is launched with \c drinject.exe or if the parent process (usually |
| cmd.exe or explorer.exe for user launched processes) is running under |
| DynamoRIO. The drinject.exe tool uses the configuration information set |
| by \c drconfig.exe for the target application. |
| |
| \attention |
| The -syswide_on, -syswide_off, use of global configuration files, and |
| nudging certain processes may require administrative privileges. On |
| Windows Vista or higher, if UAC is enabled, use an elevated (runas admin) |
| process. When using \c drconfig.exe and \c drrun.exe in these scenarios, be |
| sure that the cmd shell being used was started with elevated permissions. |
| |
| An alternative method to run an application under DynamoRIO is the \ref |
| sec_startstop "app_start()/app_stop()" interface, which requires modifying |
| application source code. |
| |
| \section lin_deploy Linux Deployment |
| |
| Once DynamoRIO has been unpacked, the same set of helper binaries as on |
| Windows provide flexibility in configuring and executing applications. |
| |
| There are two methods for invoking an application under DynamoRIO: |
| -# Configure and launch in one step via \p drrun |
| -# Configure via \p drconfig and launch via \p drinject |
| |
| As an example of the simpler method, the following command runs \c ls |
| under DynamoRIO with the bbsize sample client: |
| \code |
| % bin32/drrun -c samples/bin32/libbbsize.so -- ls |
| \endcode |
| Run \c drrun with no options to get a list of the options and |
| environment variable shortcuts it supports. To disable following across |
| child execve calls, use the \ref op_children "-no_follow_children" runtime |
| option. |
| |
| Use the tools in \c bin32/ for 32-bit applications and the tools in \c |
| bin64/ for 64-bit applications. |
| |
| The two-step method allows for greater control over child processes. The |
| \p drconfig tool writes a configuration file for a given application |
| name. DynamoRIO reads its options from the configuration file at runtime. |
| Once each process name is configured, the \p drinject tool can be used to |
| invoke the parent process. The \p drrun tool can also be used but it |
| creates a temporary configuration file that will override settings |
| requested via \p drconfig. The configuration file for each application is |
| stored in <tt>$DYNAMORIO_CONFIGDIR/.dynamorio/<appname>.config32</tt> |
| (or a \p config64 suffix for 64-bit). If <tt>DYNAMORIO_CONFIGDIR</tt> is |
| not set, <tt>$HOME/.dynamorio/<appname>.config32</tt> is used; |
| if neither is set, a temp directory will be used when creating new |
| configuration files for configure-and-run execution. On Android, if |
| neither <tt>/data/local/tmp</tt> nor the current working directory are |
| writable, you will need to specify a writable directory by setting the |
| <tt>DYNAMORIO_CONFIGDIR</tt> environment variable. |
| |
| DynamoRIO also supports global configuration |
| files in <tt>/etc/dynamorio/<appname>.config32</tt> when a local |
| configuration file is not found. \p drconfig does not support directly |
| writing a global config file but such files can be copied from or modeled |
| on local files. |
| |
| If a target application executes an \c execve that discards the \c HOME |
| environment variable, the resulting process will still run under DynamoRIO |
| control with the same settings as the parent process. |
| Use <tt>DYNAMORIO_CONFIGDIR</tt> or global configuration files to |
| specify separate options for such a child process. |
| |
| When running scripts it is best to explicitly invoke the interpreter rather |
| than invoking the script directly: |
| |
| \code |
| % bin64/drrun -- /bin/bash myscript.sh |
| \endcode |
| |
| To \ref sec_comm "nudge" a process with pid \c targetpid running under |
| DynamoRIO and pass argument "5" to the nudge callback, use the \c |
| nudgeunix tool: |
| \code |
| bin32/nudgeunix -pid targetpid -client 0 5 |
| \endcode |
| This will result in a nudge event with argument=5 delivered to the |
| client callback registered with dr_register_nudge_event() in the |
| target process. The 0 argument is an ID supplied at registration which |
| uniquely identifies the target client (see dr_deploy.h for details). |
| If you used the -c argument to drrun or drconfig to register the client, the |
| client's id defaults to 0. |
| |
| An alternative method to run an application under DynamoRIO is the \ref |
| sec_startstop "app_start()/app_stop()" interface, which requires modifying |
| application source code. |
| |
| \section android_deploy Android Deployment |
| |
| Android deployment is generally the same as \ref lin_deploy except for the |
| following differences. |
| |
| For pure native applications, the default configuration file location (if |
| <tt>DYNAMORIO_CONFIGDIR</tt> is not explicitly set) is usually (depending |
| on whether <tt>$HOME</tt> happens to be writable) <tt>/data/local/tmp</tt>. |
| |
| For Android applications on recent versions of Android, SELinux prevents |
| writing to <tt>/data/local/tmp</tt>. The application's data directory |
| should be pointed at in the \p TMPDIR or <tt>DYNAMORIO_CONFIGDIR</tt> |
| environment variables, as shown below in the example wrapper script. We |
| recommend using \p TMPDIR as its value will also be used by tools such as |
| Dr. Memory for their log files. |
| |
| To launch an Android application under DynamoRIO, use a wrapper script and |
| point at the script via the \p logwrapper property set on your |
| application's name prefixed by \p <tt>wrap.</tt>. For example, if your |
| application's name is <tt>com.myco.appname</tt>, set the property for |
| <tt>wrap.com.myco.appname</tt>, truncating to 31 characters: |
| |
| \code |
| setprop wrap.com.myco.appname "logwrapper /system/xbin/wrap.sh" |
| \endcode |
| |
| The wrapper shell script should contain the command line prefix you wish to |
| use to launch your application under DynamoRIO: |
| |
| \code |
| #!/system/bin/sh |
| export TMPDIR=/data/data/com.myco.appname |
| exec /system/xbin/dynamorio/bin32/drrun -- $@ |
| \endcode |
| |
| Be sure to place the DynamoRIO binaries and the wrapper script in an |
| executable location, such as <tt>/system/xbin</tt>. Alternatively, disable |
| SELinux via <tt>setenforce 0</tt>. |
| |
| If you run into problems with configuration files being created due to |
| SELinux denials (look in the logs for such denials), it may be simplest to |
| disable SELinux via <tt>setenforce 0</tt>. We have attempted to get |
| everything to work without this step, but we are not able to test on all |
| versions or configurations of Android. |
| |
| \endif |
| |
| \section client_ops Passing Options to Clients |
| |
| All of the earlier examples did not need to pass any arguments to the client. |
| When using the -c argument to set the client, all arguments between the client |
| path and the double dash are passed to the client. When using the -client |
| argument to drrun, the third argument following -client is passed through to |
| the client. For example, all these invocations of drrun pass '-op1 |
| -op2 "value with spaces"' to the client: |
| |
| \code |
| bin32/drrun.exe -c libmyclient.dll -op1 -op2 \"value with spaces\" -- notepad |
| bin32/drrun.exe -client myclient.dll 0 '-op1 -op2 "value with spaces"' -- notepad |
| \endcode |
| |
| On Linux: |
| |
| \code |
| bin32/drrun -c libmyclient.so -op1 -op2 \"value with spaces\" -- ls |
| bin32/drrun -client libmyclient.so 0 '-op1 -op2 "value with spaces"' -- ls |
| \endcode |
| |
| When using a two-step model, the options are passed to \p drconfig: |
| |
| \code |
| bin32/drconfig.exe -reg notepad.exe -c myclient.dll -op1 -op2 \"value with spaces\" |
| bin32/drconfig.exe -reg notepad.exe -client myclient.dll 0 '-op1 -op2 "value with spaces"' |
| \endcode |
| |
| The client's options are passed directly to its \p dr_client_main() |
| initialization routine, in the same manner as arguments are passed to a |
| regular application's \p main() routine. To match standalone application |
| conventions, \p argv[0] is set to the client library path, with the actual |
| parameters starting at index 1. The client can also optionally call |
| dr_get_option_array() to retrieve the options passed to it. C++ clients |
| can use the convenience of the \ref page_droption. |
| |
| Client options are not allowed to contain semicolons. Additionally, the |
| client option string combined with the path to the client library cannot |
| contain all three quote characters (', ", `) simultaneously. |
| |
| \section multi_client Multiple Clients |
| |
| DynamoRIO does support multiple clients. It is each client's |
| responsibility, however, to ensure compatibility with other clients. |
| DynamoRIO makes no attempt to force cooperation among clients. For |
| example, instruction stream modifcations made by one client are |
| visible to other clients. Systems employing multiple clients must |
| be aware of such interactions and design accordingly. |
| |
| Client registration requires users to specify the \em priority of each |
| client. DynamoRIO calls each client's |
| dr_client_main() routine sequentially according to this priority. Clients |
| with a numerically lower priority value are called first and therefore |
| given the first opportunity to register callbacks (the client with |
| priority 0 is called first). Since DynamoRIO delivers event |
| callbacks sequentially, client priority and the order of event |
| registration is important. For a given event, the \em first |
| registered callback is called \em last. This scheme gives precedence |
| to the first registered callback since that callback is given the final |
| opportunity to modify the instruction stream or influence DynamoRIO's |
| operation. |
| |
| |
| \section tool_frontend End-User Tools |
| |
| A client can be packaged up with DynamoRIO to create an end-user tool. For |
| many tools, a separate front-end executable is not necessary, and \p drrun |
| is sufficient. Using \p drrun for a tool is made simpler by the \p -t |
| option. To use the option, first create a file in the \p tools |
| subdirectory of the root of the DynamoRIO installation called \p |
| toolname.drrun32 or \p toolname.drrun64, depending on the target |
| architecture. Here, \p toolname is the desired external name of the tool. |
| This file should contain one of the following lines: |
| |
| \code |
| CLIENT_ABS=/absolute/path/to/client |
| \endcode |
| |
| or |
| |
| \code |
| CLIENT_REL=relative/path/to/client/from/DynamoRIO/root |
| \endcode |
| |
| This enables \p drrun to locate the tool's client library. |
| |
| The file can also modify the default DynamoRIO runtime options (see \ref |
| sec_options) via \p DR_OP= lines. Each line contains only one option string |
| token. For example: |
| |
| \code |
| DR_OP=-persist |
| DR_OP=-persist_dir |
| DR_OP=c:\\path with spaces\\subdir |
| \endcode |
| |
| Tool options can also be specified, but normally the defaults should be set |
| up appropriately in the client itself: |
| |
| \code |
| TOOL_OP=-custom_op1 |
| TOOL_OP=-custom_op2 |
| \endcode |
| |
| Lines beginning with \p # are considered comments. |
| |
| When \p drrun is passed the option string <tt>-t toolname</tt>, it looks |
| for <tt>tools/toolname.drrun64</tt> or <tt>tools/toolname.drrun32</tt> and |
| reads the file to determine the client library to use and the default |
| DynamoRIO options. This makes for a simpler launching command, rather than |
| the end user needing to name the exact location of the client library. For |
| example, this command: |
| |
| \code |
| bin64/drrun -t mytool -tool_option1 -tool_option2 -- myapp |
| \endcode |
| |
| can be made to expand to this equivalent command: |
| |
| \code |
| bin64/drrun -mytool_dr_option1 -mytool_dr_option2 -c tools/mytool/libmytool.so -tool_option1 -tool_option2 -- myapp |
| \endcode |
| |
| For more extensive actions on launching the tool, a custom front-end |
| executable can be created that replaces \p drrun by using \p drinjectlib, |
| \p drconfiglib, and \p drfrontendlib. These three libraries facilitate |
| creating cross-platform tools for configuring and launching applications |
| under Dr. Memory. For more information about the interfaces they provide, |
| see their header files: dr_inject.h, dr_config.h, dr_frontend.h. |
| |
| A custom front-end executable can be invoked via a \p drrun \p -t |
| configuration file using one of the following lines: |
| |
| \code |
| FRONTEND_ABS=/absolute/path/to/front-end |
| \endcode |
| |
| or |
| |
| \code |
| FRONTEND_REL=relative/path/to/front-end/from/DynamoRIO/root |
| \endcode |
| |
| This will cause \p drrun to transfer control to the specified front-end |
| executable, passing any tool arguments (including a client path, if \p |
| CLIENT_ABS or \p CLIENT_REL appears after the \p FRONTEND_* command) |
| followed by "--" and the target application command line. |
| |
| The path to the DynamoRIO install base can be included in the front-end |
| options via this line |
| |
| \code |
| TOOL_OP_DR_PATH |
| \endcode |
| |
| The DynamoRIO runtime options can be included in a single token, preceded by a prefix, |
| via this line, using "-dr_ops" as an example prefix: |
| |
| \code |
| TOOL_OP_DR_BUNDLE=-dr_ops |
| \endcode |
| |
| A warning message can be presented up front to the user with: |
| |
| \code |
| USER_NOTICE=This tool is currently experimental. Please report issues to mytool.com/issues. |
| \endcode |
| |
| **************************************************************************** |
| **************************************************************************** |
| */ |
| /* It's good to use separate C comments: we've hit some sort of doxygen |
| * internal buffering error before if one comment gets too long. |
| */ |
| /** |
| *************************************************************************** |
| *************************************************************************** |
| \page using Usage Model for DynamoRIO |
| |
| This section gives an overview of how to use DynamoRIO, divided into the |
| following sub-sections: |
| |
| \if vmsafe |
| - \ref dr_api |
| - \ref dr_modes |
| - \ref sec_events |
| - \ref sec_utils |
| - \ref sec_extlibs |
| - \ref sec_comm |
| - \ref sec_annotations |
| - \ref sec_options |
| - \ref sec_debugging |
| \else |
| - \ref sec_events |
| - \ref sec_utils |
| - \ref sec_build |
| - \ref sec_extlibs |
| - \ref sec_extensions |
| - \ref sec_comm |
| - \ref sec_annotations |
| - \ref sec_64bit_reach |
| - \ref sec_utf8 |
| - \ref sec_options |
| - \ref sec_debugging |
| \endif |
| |
| \ifnot vmsafe |
| DynamoRIO exports a rich Application Programming Interface (API) to the |
| user for building a DynamoRIO <em>client</em>. A DynamoRIO client is a |
| library that is coupled with DynamoRIO in order to jointly operate on an |
| input program binary: |
| |
| \image html client.png |
| \image rtf client.png |
| \image latex client.eps "DynamoRIO client" width=10cm |
| |
| To interact with the client, DynamoRIO provides specific events that a |
| client can intercept. Event interception functions, if supplied by a user |
| client, are called by DynamoRIO at appropriate times. |
| |
| DynamoRIO can alternatively be used as a third-party disassembly library |
| (see \ref page_standalone). |
| \endif |
| |
| \if vmsafe |
| *************************************************************************** |
| \section dr_api API |
| DynamoRIO's API is divided into the following interfaces: |
| - \ref API_security |
| <br>An interface for customizing and applying the award-winning Memory |
| Firewall security software. |
| - \ref API_probe |
| <br>A powerful probe insertion interface that can operate with the code cache |
| (\ref DR_MODE_CODE_MANIPULATION) or in a lighter-weight but more restrictive |
| mode without the code cache (\ref DR_MODE_PROBE). |
| - \ref API_BT |
| <br>The full runtime code manipulation interface. This includes the Probe |
| API, i.e., probes in the code cache. |
| \endif |
| |
| \if vmsafe |
| *************************************************************************** |
| \section dr_modes Modes |
| |
| The different modes a client can request DynamoRIO to operate in are listed |
| below. These are not to be confused with the different \ref dr_api provided by |
| DynamoRIO. Each mode of DynamoRIO's operation maps to one or more API. |
| |
| - The Memory Firewall mode (#DR_MODE_MEMORY_FIREWALL) maps exclusively to the Memory Firewall API. |
| - The Probe mode maps to the Probe API (#DR_MODE_PROBE) without code cache, i.e., a lighter-weight but restrictive mode. |
| - The Code Manipulation mode maps to the Code Manipulation API (#DR_MODE_CODE_MANIPULATION) and the Probe API (#DR_MODE_PROBE) with code cache. |
| . |
| |
| Below we describe parts of the system that are common to all modes and |
| interfaces. Each interface adds its own events and utilities, described in |
| the section for that interface. |
| \endif |
| |
| *************************************************************************** |
| \section sec_events Common Events |
| |
| A client's primary interaction with the DynamoRIO system is via a |
| set of event callbacks. These events include the following: |
| |
| - Basic block and trace creation or deletion |
| (dr_register_bb_event(), dr_register_trace_event(), dr_register_delete_event()) |
| - Process initialization and exit |
| (dr_client_main(), dr_register_exit_event()) |
| - Thread initialization and exit |
| (dr_register_thread_init_event(), dr_register_thread_exit_event()) |
| - Fork child initialization (Linux-only); meant to be used for |
| re-initialization of data structures and creation of new log files |
| (dr_register_fork_init_event()) |
| - Application library load and unload |
| (dr_register_module_load_event(), dr_register_module_unload_event()) |
| \ifnot NYI_kernel_mediated_transfer_events |
| - Application fault or exception (signal on Linux) |
| (dr_register_exception_event(), dr_register_signal_event()) |
| \else |
| - Kernel-mediated control transfers: |
| - Application fault or exception |
| - Application APC (Asynchronous Procedure Call) or callback (Windows) |
| - Application signal (Linux) |
| \endif |
| - System call interception: pre-system call, post-system call, and system |
| call filtering by number |
| (dr_register_pre_syscall_event(), dr_register_post_syscall_event(), |
| dr_register_filter_syscall_event()) |
| - Signal interception (Linux-only) |
| (dr_register_signal_event()) |
| - Nudge received - see \ref sec_comm |
| (dr_register_nudge_event()) |
| |
| Typically, a client will register for the desired events at |
| initialization in its dr_client_main() routine. DynamoRIO then calls the |
| registered functions at the appropriate times. Each event has a |
| specific registration routine (e.g., dr_register_thread_init_event(): see |
| the names in parentheses in the list above) |
| and an associated unregistration routine. The header file dr_events.h |
| contains the declarations for all registration and unregistration |
| routines. |
| |
| Note that clients are allowed to register multiple callbacks for the |
| same event. DynamoRIO also supports mutiple clients, each of which |
| can register for the same event. In this case, DynamoRIO sequences |
| event callbacks in reverse order of when they were registered. In |
| other words, the first registered callback receives event notification |
| last. This scheme gives priority to a callback registered earlier, |
| since it can override or modify the actions of clients registered |
| later. Note that DynamoRIO calls each client's dr_client_main() routine |
| according to the client's priority (see \ref multi_client and |
| dr_register_client() in the deployment API). |
| |
| Systems registering multiple callbacks for a single event should be |
| aware that client modifications are visible in subsequent callbacks. |
| DynamoRIO makes no attempt to mitigate interference among callback |
| functions. It is the responsibility of a client to ensure |
| compatibility among its callback functions and the callback functions |
| of other clients. |
| |
| Clients can also unregister a callback using the appropriate |
| unregister routine (see dr_events.h). While unusual, it is possible for |
| one callback routine to unregister another. In this case, DynamoRIO |
| still calls routines that were registered before the event. |
| Unregistration takes effect before the next event. |
| |
| On Linux, an exec (SYS_execve) does NOT result in an exit event, but it |
| WILL result in the client library being reloaded and its dr_client_main() routine |
| being called again. The system call events can be used for notification of |
| SYS_execve. |
| |
| *************************************************************************** |
| \section sec_utils Common Utilities |
| |
| DynamoRIO provides clients with a powerful library of utilities for |
| custom runtime code transformations. The interface includes explicit |
| support for creating \e transparent clients. See the section on |
| \ref transparency for a full discussion of the importance of remaining |
| transparent when operating in the same process as the application. |
| DynamoRIO provides common resources clients can use to avoid reliance on |
| shared libraries that may be in use by the application. The client should |
| only use external resources through DynamoRIO's own API, through |
| DynamoRIO Extensions (see \ref sec_extensions), through direct |
| system calls, or via an external agent in a separate process that |
| communicates with the client (see \ref sec_comm). Third-party libraries |
| can be used if they are linked statically or loaded privately and there is |
| no possibility of global resource conflicts (e.g., a third-party library's |
| memory allocation must be wrapped): see \ref sec_extlibs for more details. |
| \if vmsafe For the Probe API, these restrictions can be relaxed (see \ref |
| sec_trans_probe). \endif |
| |
| DynamoRIO's API provides: |
| |
| - Memory allocation: both thread-private (faster as it incurs no |
| synchronization costs) and thread-shared |
| - Thread-local storage |
| - Thread-local stack separate from the application stack |
| - Simple mutexes |
| - File creation, reading, and writing |
| - Address space querying |
| - Application module iterator |
| - Processor feature identification |
| - Extra thread creation |
| - Symbol lookup (currently Windows-only) |
| - Auxiliary library loading |
| |
| See dr_tools.h and dr_proc.h for specifics of each routine. |
| |
| Another class of utilities provided by DynamoRIO are structures and |
| routines for decoding, encoding, and manipulating IA-32, AMD64, ARM, and AArch64 |
| instructions. These are described in \ref sec_IR. |
| |
| \anchor subsec_forwards |
| In addition, on Windows, DynamoRIO provides a number |
| of utility functions that it fowards to a core Windows system library |
| that we believe to be safe for clients to use: |
| |
| - wcstoul |
| - wcstombs |
| - wcstol |
| - wcsstr |
| - wcsspn |
| - wcsrchr |
| - wcspbrk |
| - wcsncpy |
| - wcsncmp |
| - wcsncat |
| - wcslen |
| - wcscspn |
| - wcscpy |
| - wcscmp |
| - wcschr |
| - wcscat |
| - towupper |
| - towlower |
| - toupper |
| - tolower |
| - tan |
| - strtoul |
| - strtol |
| - strstr |
| - strspn |
| - strrchr |
| - strpbrk |
| - strncpy |
| - strncmp |
| - strncat |
| - strlen |
| - strcspn |
| - strcmp |
| - strchr |
| - sscanf |
| - sqrt |
| - sprintf |
| - sin |
| - qsort |
| - pow |
| - memset |
| - memmove |
| - memcpy |
| - memcmp |
| - memchr |
| - mbstowcs |
| - log |
| - labs |
| - isxdigit |
| - iswxdigit |
| - iswspace |
| - iswlower |
| - iswdigit |
| - iswctype |
| - iswalpha |
| - isupper |
| - isspace |
| - ispunct |
| - isprint |
| - islower |
| - isgraph |
| - isdigit |
| - iscntrl |
| - isalpha |
| - isalnum |
| - floor |
| - fabs |
| - cos |
| - ceil |
| - atol |
| - atoi |
| - atan |
| - abs |
| - _wtol |
| - _wtoi64 |
| - _wtoi |
| - _wcsupr |
| - _wcsnicmp |
| - _wcslwr |
| - _wcsicmp |
| - _vsnprintf |
| - _ultow |
| - _ultoa |
| - _ui64toa |
| - _toupper |
| - _tolower |
| - _strupr |
| - _strnicmp |
| - _strlwr |
| - _stricmp |
| - _strcmpi |
| - _snwprintf |
| - _snprintf |
| - _memicmp |
| - _memccpy |
| - _ltow |
| - _ltoa |
| - _itow |
| - _itoa |
| - _i64tow |
| - _i64toa |
| - _ftol |
| - _fltused |
| - _chkstk |
| - _aullshr |
| - _aullrem |
| - _aulldiv |
| - _atoi64 |
| - _allshr |
| - _allshl |
| - _allrem |
| - _allmul |
| - _alldiv |
| - __toascii |
| - __iscsymf |
| - __iscsym |
| - __isascii |
| |
| In general, these routines match their standard C library counterparts. However, be |
| warned that some of these may be more limited. In particular, _vsnprintf |
| and _snprintf do not support floating-point values. DynamoRIO provides |
| its own dr_snprintf() that does support floating-point values, but does |
| not support printing wide characters. When printing floating-point values |
| be sure to \ref sec_trans_floating_point |
| "save the application's floating point state" |
| so as to avoid corrupting it. |
| |
| *************************************************************************** |
| \section sec_64bit_reach 64-Bit Reachability |
| |
| To simplify reachability in a 64-bit address space, DynamoRIO guarantees |
| that all of its code caches are located within a single 2GB memory region. |
| It also places all client memory allocated through dr_thread_alloc(), |
| dr_global_alloc(), dr_nonheap_alloc(), or dr_custom_alloc() with |
| #DR_ALLOC_CACHE_REACHABLE in the same region. |
| |
| DynamoRIO loads client libraries and Extensions (but not copies of system |
| libraries) within 32-bit reachability of its code caches. Typically, the |
| code cache region is located in the low 4GB of the address space; thus, to |
| avoid relocations at client library load time, it is recommended to set a |
| preferred client library base in the low 4GB. |
| |
| The net result is that any static data or code in a client library, or any |
| data allocated using DynamoRIO's API routines (except dr_raw_mem_alloc() or |
| dr_custom_alloc()), is guaranteed to be directly reachable from code cache |
| code. However, memory allocated through system libraries (including |
| malloc, operator new, and HeapAlloc), as well as DynamoRIO's own |
| internally-used heap memory, is *not* guaranteed to be reachable: only |
| memory directly allocated via DynamoRIO's API. The \ref op_reachable_heap |
| "-reachable_heap runtime option" can be used to guarantee that all memory |
| is reachable, at the risk of running out memory due to the smaller space |
| of available memory. |
| |
| To make more space available for the code caches when running larger |
| applications, or for clients that use a lot of heap memory that is not |
| directly referenced from the cache, we recommend that dr_custom_alloc() be |
| called to obtain memory that is not guaranteed to be reachable from the |
| code cache (by not passing #DR_ALLOC_CACHE_REACHABLE). This frees up space |
| in the reachable region. |
| |
| When inserting calls, dr_insert_call() and dr_insert_clean_call() assume |
| that the call is destined for encoding into the code cache-reachable memory |
| region, when determining whether a direct or indirect call is needed. |
| An indirect call will clobber r11. Use dr_insert_clean_call_ex() |
| with #DR_CLEANCALL_INDIRECT to ensure reachability when encoding to |
| a location other than DR's regular code region, or when a clean call is not |
| needed, dr_insert_call_ex() takes in a target encode location for more |
| flexible determination of direct versus indirect. |
| |
| DynamoRIO does not guarantee that any of its memory is allocated in the |
| lower 4GB of the address space. However, it provides several features to |
| make it easier to reference addresses absolutely: |
| |
| - For directly referencing a global variable \p var in a client library, the |
| client can create an operand with the address \p &var and it will |
| auto-magically turn into a pc-relative addressing mode. |
| OPND_CREATE_ABSMEM() directly creates a pc-relative operand, while |
| opnd_create_abs_addr() will convert to a pc-relative operand when an |
| absolute reference will not encode. An opnd_create_rel_addr() operand |
| will also convert to an absolute reference when that will reach but a |
| pc-relative reference will not. |
| |
| - When using an address as an immediate, use the routines |
| instrlist_insert_mov_immed_ptrsz() or |
| instrlist_insert_push_immed_ptrsz() to conveniently insert either one or |
| two instructions depending on whether the address is in the lower 4GB or |
| not. |
| |
| - When using an \p instr_t pointer as an immediate, use the routines |
| instrlist_insert_mov_instr_addr() or instrlist_insert_push_instr_addr() |
| to conveniently insert either one or two instructions depending on |
| whether the resulting instr_t encoded address is in the lower 4GB or |
| not. |
| |
| *************************************************************************** |
| \section sec_utf8 String Encoding |
| |
| All strings in the DynamoRIO API, whether input or output parameters, are |
| encoded as UTF-8. DynamoRIO will internally convert to UTF-16 when |
| interacting with the Windows kernel. A client can use #dr_snprintf() or |
| #dr_snwprintf() with the \p S format code to convert between UTF-8 and |
| UTF-16 on its own. (The _snprintf() function forwarded to ntdll does not |
| perform that conversion.) |
| |
| *************************************************************************** |
| \section sec_build Building a Client |
| |
| To use the DynamoRIO API, a client should include the main DynamoRIO |
| header file: |
| |
| \code |
| #include "dr_api.h" |
| \endcode |
| |
| The client's target operating system and architecture must |
| be specified by setting pre-processor defines before including the |
| DynamoRIO header files. The appropriate library must then be linked |
| with. The define choices are: |
| |
| -# \p WINDOWS, \p LINUX, or (coming soon) \p MACOS |
| -# \p X86_32, \p X86_64, \p ARM_32, or \p ARM_64 |
| |
| Currently we provide a private loader for both Windows and Linux. |
| With private loading, clients use a separate copy of each library |
| from any copy used by the application. |
| |
| If the private loader is deliberately disabled, for transparency reasons |
| (see \ref transparency), clients should be |
| self-contained and should not share libraries with the application. |
| Without the private loader, 64-bit clients must take care to try and load |
| themselves within reachable range of DynamoRIO's code caches by setting a |
| preferred base address, although this may not always be honored by the |
| system loader. |
| |
| The DynamoRIO release supplies <a href="http://www.cmake.org">CMake</a> |
| configuration files to facilitate building clients with the proper |
| compiler and linker flags. CMake is a cross-platform build system that |
| generates Makefiles or other development system project files. A \p |
| DynamoRIOConfig.cmake configuration file, along with supporting files, is |
| distributed in the \p cmake/ directory. |
| |
| In its \p CMakeLists.txt file, a client should first invoke a \p |
| find_package(DynamoRIO) command. This can optionally take a version |
| parameter. This adds DynamoRIO as an imported target. If found, the |
| client should then invoke the \p configure_DynamoRIO_client() function in |
| order to configure build settings. Here is an example: |
| |
| \code |
| add_library(myclient SHARED myclient.c) |
| find_package(DynamoRIO) |
| if (NOT DynamoRIO_FOUND) |
| message(FATAL_ERROR "DynamoRIO package required to build") |
| endif(NOT DynamoRIO_FOUND) |
| configure_DynamoRIO_client(myclient) |
| \endcode |
| |
| Note that when building a 32-bit client in Linux using \p gcc, the stack |
| alignment should be 4-byte only. |
| Using the function \p configure_DynamoRIO_client() will configure the |
| build settings correctly. |
| Otherwise, appropriate options should be passed to the compiler: e.g., |
| \p -mpreferred-stack-boundary=2. |
| |
| The \p samples/CMakeLists.txt file in the release package serves as another |
| example. The top of \p DynamoRIOConfig.cmake contains detailed |
| instructions as well. |
| |
| When configuring, the \p DynamoRIO_DIR CMake variable can be passed in to |
| identify the directory that contains the \p DynamoRIOConfig.cmake file. For |
| example: |
| |
| \code |
| mkdir ../build |
| cd ../build |
| cmake -DDynamoRIO_DIR=$DYNAMORIO_HOME/cmake ../myclient |
| make |
| \endcode |
| |
| The compiler needs to be configured prior to invoking cmake. If using gcc |
| with a non-default target platform, the \p CFLAGS and \p CXXFLAGS |
| environment variables should be set prior to invoking cmake. For example, |
| to configure a 32-bit client when gcc's default is 64-bit: |
| |
| \code |
| mkdir ../build |
| cd ../build |
| CFLAGS=-m32 cmake -DDynamoRIO_DIR=$DYNAMORIO_HOME/cmake ../myclient |
| make |
| \endcode |
| |
| Note that \p CXXFLAGS should be set instead for a C++ client, and both should |
| be set when building both types of clients from the same configuration |
| (e.g., \p samples/CMakeLists.txt). |
| |
| To improve clean call performance (see \ref sec_clean_call and \ref |
| op_cleancall "-opt_cleancall"), we recommend high levels of optimization |
| when building a client. |
| |
| If a client is not using CMake, the appropriate compiler and linker flags |
| can be gleaned from \p DynamoRIOConfig.cmake. One method is to invoke CMake to |
| generate a Makefile and then build with \p VERBOSE=1. We also summarize |
| here the key flags required for 32-bit clients for \p gcc: |
| |
| \code |
| gcc -fPIC -shared -lgcc -DLINUX -DX86_32 -I$DYNAMORIO_HOME/include my-client.c |
| \endcode |
| |
| And for \p cl: |
| |
| \code |
| cl my-client.c /I$DYNAMORIO_HOME/include /GS- /DWINDOWS /DX86_32 |
| /link /libpath:$DYNAMORIO_HOME/bin dynamorio.lib /dll /out:my-client.dll |
| \endcode |
| |
| For a 64-bit client with \p cl: |
| |
| \code |
| cl my-client.c /I$DYNAMORIO_HOME/include /GS- /DWINDOWS /DX86_64 |
| /link /libpath:$DYNAMORIO_HOME/bin dynamorio.lib /dll /out:my-client.dll |
| /base:0x72000000 /fixed |
| \endcode |
| |
| For 64-bit Linux clients, setting the preferred base takes several steps. |
| Refer to \p DynamoRIOConfig.cmake for details. |
| |
| To make clean call sequences more likely to be optimized, it is recommended |
| to compile the client with optimizations, \p -O2 for gcc or \p /O2 for cl. |
| |
| |
| *************************************************************************** |
| \section sec_extensions DynamoRIO Extensions |
| |
| DynamoRIO supports extending the API presented to clients through |
| separate libraries called DynamoRIO Extensions. Extensions are meant to |
| include features that may be too costly to make available by default or |
| features contributed by third parties whose licensing requires using a |
| separate library. Extensions can be either static libraries linked with |
| clients at build time or dynamic libraries loaded at runtime. A private |
| loader is used to load dynamic Extensions. |
| |
| Current Extensions provide symbol access and container data structures. |
| Each Extension has its own documentation and has its functions and data |
| structures documented separately from the main API. |
| See the full list of Extensions here: \ref page_ext. |
| |
| Be aware that some of the DynamoRIO Extensions have LGPL licenses instead |
| of the BSD license of the rest of DynamoRIO. Such Extensions are built as |
| shared libraries, have their own license.txt files, and clearly identify |
| their license in their documentation. (We also provide static versions of |
| such libraries, but take care in using them that their LGPL licenses match |
| your requirements.) |
| |
| *************************************************************************** |
| \section sec_extlibs Using External Libraries |
| |
| Clients are free to use external libraries as long as those libraries do |
| not use any global user-mode resources that would interfere with the |
| running application, and as long as no alertable system calls are invoked |
| on Windows (see \ref sec_alertable). While most non-graphical |
| non-alertable Windows API routines are supported, native threading libraries |
| such as \p libpthread.so on Linux are known to cause problems. |
| |
| Currently we provide a private loader for both Windows and Linux. |
| Clients must either link statically to all libraries or load them using |
| our private loader, which will happen automatically for shared libraries |
| loaded in a typical manner. |
| With private loading, the client |
| uses a separate copy of each library from any copy used by the application. |
| This helps to prevent re-entrancy problems (see \ref sec_trans_resource). |
| Even with this separation, if these libraries use global resources there |
| can still be conflicts. Our private loader redirects heap |
| allocation in the main process heap to instead use DynamoRIO's internal |
| heap. The loader also attempts to isolate other global resource usage and |
| global callbacks. Please file reports on any transparency problems |
| observed when using the private loader. |
| |
| By default, all Windows clients link with libc. To instead |
| use the libc subset of routines forwarded from the DynamoRIO library to \p |
| ntdll.dll (which keeps clients more lightweight and is usually sufficient |
| for most C code), set this variable prior to invoking |
| configure_DynamoRIO_client(): |
| |
| \code |
| set(DynamoRIO_USE_LIBC OFF) |
| \endcode |
| |
| C++ clients and standalone clients link with libc by default. |
| |
| ************************************************** |
| \subsection sec_alertable Avoid Alertable System Calls |
| |
| On Windows, DynamoRIO does not support a client (or a library used by a |
| client) making alertable system calls. These are system calls that can be |
| interrupted for delivery of callbacks or asynchronous procedure calls. At |
| the Windows API layer, they include many graphical routines, any Wait |
| function invoked with \p alertable=TRUE (e.g., WaitForSingleObjectEx or |
| WaitForMultipleObjectsEx), any Windows message queue function (GetMessage, |
| SendMessage, ReplyMessage), and asynchronous i/o. In general, avoiding |
| graphical, windowing, or asynchronous i/o library or system calls is |
| advisable. DynamoRIO does not guarantee correct execution when a callback |
| arrives during client code execution. |
| |
| ************************************************** |
| \subsection sec_rpath DynamoRIO Library Search Paths |
| |
| DynamoRIO's loader searches for libraries in approximately the same manner |
| as the system loader. It also has support for automatically locating |
| Extension libraries that are packaged in the usual place in the DynamoRIO |
| file hierarchy. |
| |
| DynamoRIO supports setting DT_RPATH for ELF clients, via setting the |
| DynamoRIO_RPATH variable to ON prior to invoking |
| configure_DynamoRIO_client(). On Windows, setting that variable will |
| create a "<client_basename>.drpath" text file that contains a list of |
| paths. At runtime, DynamoRIO's loader will parse this file and add each |
| newline-separated path to its list of search paths. This file is honored |
| on Linux as well, though it is not automatically created there. This |
| allows clients a cross-platform mechanism to use third-party libraries in |
| locations of their choosing. |
| |
| ************************************************** |
| \subsection subsec_avoid_redir Deliberately Invoking Application Routines |
| |
| Sometimes, a client wishes to invoke system library routines with the |
| application context, rather than having them redirected and isolated by |
| DynamoRIO. This can be accomplished using dynamic binding rather than |
| static: dynamically looking up each desired library routine via DR's own |
| routines (such as dr_get_proc_address()). (Using \p GetProcAddress will not |
| work for this purpose as the result will be redirected.) |
| |
| ************************************************** |
| \subsection subsec_no_loader When Private Loader is Disabled |
| |
| On Linux, if the private loader is deliberately disabled, ld provides the -wrap |
| option, which allows us to override the C library's memory heap allocation |
| routines with our own. For convenience, DynamoRIO exports |
| __wrap_malloc(), __wrap_realloc(), and __wrap_free() for this purpose. |
| These routines behave like their C library counterparts, but operate on |
| DynamoRIO's global memory pool. Use the -Xlinker flag with gcc to replace |
| the libc routines with DynamoRIO's _wrap routines, e.g., |
| |
| \code |
| gcc -Xlinker -wrap=malloc -Xlinker -wrap=realloc -Xlinker -wrap=free ... |
| \endcode |
| |
| The ability to override the memory allocation routines makes it |
| convenient to develop C++ clients that use the \em new and \em delete |
| operators (as long as those operators are implemented using malloc and |
| free). In particular, heap allocation is required to use the C++ |
| Standard Template Library containers. When developing a C++ client, |
| we recommend linking statically to the C++ runtime library if not using |
| the provided private loader. |
| |
| On Linux, this is most easily accomplished by specifying the path to the |
| static version of the library on the gcc command line. gcc's |
| -print-file-name option is useful for discovering this path, e.g., |
| |
| \code |
| g++ -print-file-name=libstdc++.a |
| \endcode |
| |
| A full gcc command line for building a C++ client when disabling the |
| private loader (which is not the default) might look something like this |
| (note that this requires static versions of the standard libraries that |
| were built PIC, which is not the case in modern binary distributions and |
| often requires building from source): |
| |
| \code |
| g++ -o my-client.so -I<header dir> \ |
| -fPIC -shared -nodefaultlibs \ |
| -Xlinker -wrap=malloc -Xlinker -wrap=realloc -Xlinker -wrap=free \ |
| `g++ -print-file-name=libstdc++.a` \ |
| `g++ -print-file-name=libgcc.a` \ |
| `g++ -print-file-name=libgcc_eh.a` \ |
| my-client.cpp |
| \endcode |
| |
| ************************************************** |
| \subsection subsec_cpp C++ Clients |
| |
| The 3.0 version of DynamoRIO added experimental full support for C++ |
| clients using the STL and other libraries. |
| |
| On Windows, when using the Microsoft Visual C++ compiler, we recommend |
| using the \p /MT compiler flag to request a static C library. The client |
| will still use the \p kernel32.dll library but our private loader will load |
| a separate copy of that library and redirect heap allocation automatically. |
| Our private loader does not yet support locating SxS (side-by-side) |
| libraries, so using \p /MD will most likely not work unless using a |
| version of the Visual Studio compiler other than 2005 or 2008. |
| |
| We do not recommend that a client or its libraries invoke their own system |
| calls as this bypasses DynamoRIO's monitoring of changes to the process |
| address space and changes to threads or control flow. Such system calls |
| will also not work properly on Linux when using sysenter on some systems. |
| If you see an assert to that effect in debug build on Linux, try the \ref |
| op_sysenter "-sysenter_is_int80" option. |
| |
| *************************************************************************** |
| \section sec_comm Communication |
| |
| Due to transparency limitations (see \ref transparency), |
| DynamoRIO can only support certain communication channels in and out of the |
| target application process. These include: |
| |
| - DynamoRIO deployment control and runtime options: see \ref page_deploy |
| and \ref sec_options. In particular, the deployment API allows users to |
| pass up-front runtime information to the client. |
| - Nudges: Since polling requires extra threads, and DynamoRIO tries not |
| to create permanent extra threads (see \ref sec_trans_thread |
| "Thread Transparency"), a mechanism called \e nudges are the preferred mechanism |
| for pushing data into the process. Nudges are used to notify DynamoRIO |
| that it needs to re-read its options, or perform some other action. |
| DynamoRIO also provides a custom nudge event that can be used by |
| clients. See dr_nudge_process() and dr_register_nudge_event(). |
| - Files can be used to send data out. An external process can wait on |
| the file. |
| - Shared memory can be used for bi-directional communication. For an |
| example of this on Windows, see the stats sample (see \ref sec_drstats). |
| |
| *************************************************************************** |
| \section sec_annotations Annotations |
| |
| DynamoRIO provides a binary annotation mechanism which allows the target application to |
| communicate directly with the DynamoRIO client, or with DynamoRIO itself. A binary |
| annotation is generated from a macro that can be manually inserted into the source code of |
| the target program. When compiled, the resulting sequence of assembly instructions has no |
| effect on native execution (i.e., it is a nop, or resolves to a static default value), |
| but during execution under DynamoRIO, each annotation is detected and transformed into a |
| function call to a set of registered handlers. Currently DynamoRIO provides 2 simple |
| annotations: |
| |
| - <b>DYNAMORIO_ANNOTATE_RUNNING_ON_DYNAMORIO()</b> |
| Indicates by its return value whether the target app is running under DynamoRIO, |
| |
| - <b>DYNAMORIO_ANNOTATE_LOG(format, ...)</b> |
| Writes a message to the DynamoRIO log, when the target app is running under DynamoRIO |
| and logging is enabled. |
| |
| An annotation may be declared void, as in DYNAMORIO_ANNOTATE_LOG(), or it may have a |
| return value, as in the boolean DYNAMORIO_ANNOTATE_RUNNING_ON_DYNAMORIO(). The return |
| value can be used in a branch predicate, such that some of the target app's code only |
| executes under DynamoRIO, or it can be used for in-process communication to obtain data |
| from DynamoRIO or its client that is only available during binary translation. |
| |
| \subsection subsec_annotate_app Annotating an Application |
| |
| Adding an annotation to a target application is primarily a simple matter of invoking the |
| annotation macro at the desired program location. The macros are declared in the C header |
| file <b>include/annotations/dr_annotations.h</b>, and each macro operates syntactically |
| like a function call. An annotation having a return value can be used as an expression. |
| DynamoRIO provides a module which defines the annotations, and clients may also provide |
| modules containing custom annotations. Each compilation unit that uses annotations must be |
| statically linked with the corresponding annotation module(s). For projects using cmake, a |
| convenience function \b use_DynamoRIO_annotations(target, srcs) will configure the |
| specified \b srcs to be linked with the annotation module. |
| |
| \subsection subsec_instr_annotations Instrumenting Annotations |
| |
| When DynamoRIO encounters an annotation in the target app, it instruments that program |
| location in one of two ways: |
| |
| - Return value substitution: DynamoRIO replaces the annotation with a constant return |
| value (this instrumentation is only valid for annotations having a return value), |
| |
| - Handler invocation: DynamoRIO replaces the annotation with a call to each handler that |
| is currently registered for the annotation. For annotations having a return value, the |
| return value of the last registered handler will be the value to take effect at the |
| target program location. |
| |
| Annotation handlers are registered using API functions \b dr_annotation_register_call() |
| and \b dr_annotation_register_return(). Note that changes to handler registration will |
| have no effect on annotations that have already been translated by DynamoRIO into the |
| code cache (until the annotated basic blocks are removed from the cache and retranslated). |
| The annotation instrumentation invokes the handlers using a separate clean call for each |
| handler. The return value for an annotation can be set within a handler function using |
| the API function \b dr_annotation_set_return_value(). |
| |
| \subsection subsec_create_annotations Creating Custom Annotations |
| |
| DynamoRIO client developers may wish to create new annotations to facilitate |
| client-specific communication with the target application. For example, a client that |
| inspects memory usage may have false positives for variables in the target app that are |
| never referenced after initialization. The \ref API_tutorial_annotation1 walks |
| through the process of creating a new annotation that allows target application |
| developers to explicitly mark any variable as defined. |
| |
| *************************************************************************** |
| \section sec_options Fine-Tuning DynamoRIO: Runtime Parameters |
| |
| DynamoRIO's behavior can be fine-tuned using runtime parameters. Options |
| are specified via \c drconfig, \c drrun, or dr_register_process(). See |
| \ref page_deploy. |
| |
| - \b -no_follow_children: \anchor op_children |
| By default, DynamoRIO follows all child processes. When this option |
| is disabled via \p -no_follow_children, DynamoRIO follows only |
| into child processes for which a configuration file exists (typically |
| created by \c drconfig; see \ref page_deploy). On Linux, |
| forked children are always followed and this option only affects execve. |
| |
| To follow all children in general but exclude certain children, leave \p |
| -follow_children on (the default) and create config files that exclude |
| the desired applications by running \c drconfig with the \c -norun |
| option. |
| |
| - \b -opt_memory: \anchor op_memory |
| Reduce memory usage, but potentially at the cost of performance. This |
| option can result in memory savings as high as 20%, and usually incurs |
| no noticable performance degradation. However, it conflicts with the |
| \ref op_enable "-enable_full_api option" and cannot be used with |
| dr_unlink_flush_region(). |
| |
| - \b -opt_cleancall \e \<number\>: \anchor op_cleancall |
| Optimize (shrink or inline) the clean call sequences (see \ref sec_clean_call). |
| When DynamoRIO analyzes the callee and optimizes each clean call invocation, |
| it assumes that a client will not modify the clean call callee or application |
| instructions after the inserted clean call. |
| If a client changes application instructions after an inserted clean call, |
| the client may need to reduce the -opt_cleancall level to preserve correct |
| execution. |
| The clean call will only be optimized if it is a leaf function. |
| Currently, the callee will be inlined only if it is small, has at most |
| one argument, and has no control flow other than for the PIC base. |
| Compiling the client with optimizations makes clean call sequences more likely |
| to be optimized. |
| The optimization results (e.g. whether the inserted clean call is inlined or not, |
| and which registers were saved on each context switch) are logged. |
| Users can run DynamoRIO debug build with the runtime option |
| "-loglevel 2 -logmask 0x02000000" (the logmask is optional but reduces the |
| logfile size significantly) and grep for |
| "CLEANCALL" in the log file to retrieve the information |
| about clean call optimization. |
| There are four optimization levels. |
| By default, the clean call optimization level is 2. |
| - 0: no optimization. |
| - 1: callee register usage analysis and optimization on context switch. |
| - 2: simple callee inline optimization, callee-save register analysis, |
| and aflags usage analysis on the instruction list to be inserted. |
| - 3: more aggressive, but potentially unsafe, optimizations. |
| |
| - \b -opt_speed: \anchor op_speed |
| By default, DynamoRIO provides a more straightforward code stream to |
| clients in lieu of performance optimizations. This option attempts |
| to obtain higher performance with potential loss of client simplicity. |
| In particular, unconditional branches (both jumps and calls) and in some |
| cases indirect calls may be elided in basic blocks. See also \ref sec_limit_perf. |
| Note that dr_insert_mbr_instrumentation() is not supported when -opt_speed |
| is specified. |
| |
| - \b -stack_size \e \<number\>: \anchor op_stack_size |
| DynamoRIO's per-thread stack is limited to 56KB by default (this may |
| seem small, but this is much larger than its size when no client is |
| present). This parameter can be used to increase the size; however, |
| larger stack sizes use significantly more memory when targeting |
| applications with hundreds of threads. The parameter can take a 'K' |
| suffix, and must be a multiple of the page size (4K). This stack is |
| used \if vmsafe for probe callbacks and by the Code Manipulation |
| API \else by the \endif routines dr_insert_clean_call(), |
| dr_swap_to_clean_stack(), dr_prepare_for_call(), |
| dr_insert_call_instrumentation(), dr_insert_mbr_instrumentation(), |
| dr_insert_cbr_instrumentation(), and dr_insert_ubr_instrumentation(). |
| The stack is started fresh for each use, so <em>no persistent state may be |
| stored on it</em>. |
| \if vmsafe |
| Options available only in Code Manipulation mode and Memory Firewall mode |
| (see \ref dr_modes): |
| \endif |
| - \b -thread_private: \anchor op_thread_priv |
| By default, DynamoRIO's code caches are shared across threads. This |
| option requests code caches that are private to each thread. For |
| applications with many threads, thread-private code caches use more |
| memory. However, they can be more efficient, particularly when |
| inserting thread-specific instrumentation. |
| |
| - \b -disable_traces: |
| By default, DynamoRIO builds both a <em>basic block</em> code cache and |
| a <em>trace</em> code cache (see \ref sec_IR). This option disables |
| trace building, which can have a negative performance impact. |
| When running large, short-running applications, however, disabling |
| traces can improve performance. |
| When traces are disabled, dr_register_trace_event() has no effect. |
| DynamoRIO tries to keep traces transparent to a client who is |
| interested in all code and not only hot code, so there is rarely a |
| reason to disable traces. |
| \if internal_comment |
| if we expose -enable_traces, note that it must be specified BEFORE |
| -thread_private as today it turns on -shared_traces |
| \endif |
| |
| - \b -enable_full_api: \anchor op_enable |
| DynamoRIO's default internal options balance performance with API |
| usability. A few API functions, such as dr_unlink_flush_region(), |
| are incompatible with this default mode. Client users can gain |
| access to the entire set of API functions with -enable_full_api. |
| Note that this option may result in a small performance degradation. |
| |
| - \b -reachable_heap: \anchor op_reachable_heap |
| By default, DynamoRIO guarantees that heap allocated directly through |
| its API routines dr_thread_alloc(), dr_global_alloc(), |
| dr_nonheap_alloc(), or dr_custom_alloc() with #DR_ALLOC_CACHE_REACHABLE |
| is reachable by a 32-bit displacement from the code cache. However, it |
| does not guarantee that memory allocated through system libraries |
| (including malloc, operator new, and HeapAlloc) or DynamoRIO's own |
| internal memory is reachable. Turning this option on combines all of |
| the heap memory such that it is all guaranteed to be reachable from the |
| code cache, at the risk of running out memory due to the smaller space |
| of available memory. |
| |
| - \b -max_bb_instrs: |
| DynamoRIO stops building a basic block if it hits this application |
| instruction count limit before hitting control flow or other block |
| termination conditions. The default value is 1024; lower it if |
| extensive client instrumentation is running into code cache size |
| limit asserts. |
| |
| - \b -max_trace_bbs: |
| DynamoRIO will not build a trace with larger than this number of |
| constituent basic block. The default value is 128; lower it if |
| extensive client instrumentation is running into code cache size |
| limit asserts. |
| |
| - \b -sysenter_is_int80: \anchor op_sysenter |
| This option only applies to Linux. If sysenter is the system call |
| gateway, DynamoRIO normally hooks the vsyscall vdso page when it can. |
| This option requests that DynamoRIO convert sysenter into int 0x80 |
| instead. See \ref sec_extlibs. |
| |
| - \b -multi_thread_exit: |
| By default, DynamoRIO synchronizes with all remaining threads |
| at process exit time and the process exit event executes with only |
| one live thread. This option requests that in release build the |
| synchronization be avoided. The process exit event must be written |
| in a thread-safe manner. Note that if thread exit events are |
| registered, to avoid the synchronization the -skip_thread_exit_at_exit |
| option must also be set. These options can also be enabled |
| programmatically via dr_set_process_exit_behavior(). |
| |
| - \b -skip_thread_exit_at_exit: |
| By default, DynamoRIO synchronizes with all remaining threads at |
| process exit time in order to safely call each thread exit event. This |
| option requests that in release build the synchronization be avoided by |
| removing the invocation of thread exit events at process exit time. |
| Note that if the process exit event is registered, to avoid the |
| synchronization the -multi_thread_exit option must also be set. These |
| options can also be enabled programmatically via |
| dr_set_process_exit_behavior(). |
| |
| - \b -persist:\anchor op_persist |
| Enables persisting of code caches to disk and re-use on subsequent runs. |
| Caches are persisted in units that correspond to application libraries, |
| or sometimes smaller units. Each unit is persisted to its own file |
| in a subdirectory of the base directory specified by \p -persist_dir. |
| See \ref sec_pcache for more details. |
| |
| - \b -persist_dir \e \<path\>: |
| Sets the base directory for persistent code cache files. If unset, |
| the default base directory is the log directory. A different |
| sub-directory will be created for each user inside the specified |
| directory. |
| |
| - \b -translate_fpu_pc:\anchor op_translate_fpu_pc |
| Enables translation of the last floating-point instruction address when |
| the last floating-point instruction is not in the same basic block as |
| the instruction saving the FPU state. This is off by default as it |
| incurs significant performance penalties and few applications require |
| this feature. |
| |
| \if cache_sizing |
| FIXME: users may want control over adaptive wset cache management, |
| particularly for thread-private to avoid deletions, but also for shared if |
| they want to shrink memory usage |
| \endif |
| |
| - \b -syntax_intel: \anchor op_syntax_intel |
| This option causes DynamoRIO to output all disassembly using Intel |
| syntax rather than the default show-implicit-operands syntax. This can also be set |
| using disassemble_set_syntax(). |
| |
| - \b -syntax_att: \anchor op_syntax_att |
| This option causes DynamoRIO to output all disassembly using AT&T |
| syntax rather than the default show-implicit-operands syntax. This can also be set |
| using disassemble_set_syntax(). |
| |
| - \b -syntax_arm: \anchor op_syntax_arm |
| This option causes DynamoRIO to output all disassembly using standard |
| ARM assembler syntax rather than the default show-implicit-operands |
| syntax. This can also be set using disassemble_set_syntax(). |
| |
| - \b -disasm_mask: |
| This option sets the disassembly style to the specified bitmask of |
| dr_disasm_flags_t values. This option overlaps with -syntax_intel, |
| -syntax_att, and -syntax_arm. The style can also be set using |
| disassemble_set_syntax(). |
| |
| \ifnot vmsafe |
| - \b -tracedump_text and \b -tracedump_binary: |
| These options cause DynamoRIO to output all traces that were created |
| to the log file \e traces-shared.0.TID.html, where \e |
| TID is the thread id of the initial thread; any thread-private traces |
| (see \ref op_thread_priv "-thread_private option") produce per-thread |
| files \e traces.TID.html. |
| Traces are logged whenever they are flushed from the cache (which can |
| be during execution or at the latest at program termination). The two |
| options select either a text dump or a binary dump. The text dump |
| takes up considerable room and time to dump, while the binary dump |
| requires more effort to examine. The binary trace dump format is |
| documented in dr_tools.h, and a sample reader is provided with this |
| distribution. |
| |
| - \b -tracedump_origins |
| When selected by itself with neither -tracedump_text nor |
| -tracedump_binary, dumps only a text list of the constituent basic block |
| tags of each trace to the trace log file. When combined with either of |
| -tracedump_text or -tracedump_binary, adds a full disassembly of the |
| constituent basic blocks to the selected dump. |
| \endif |
| |
| \if profiling |
| FIXME PR 225255: profiling options |
| \endif |
| |
| Options controlling notifications from DynamoRIO: |
| |
| - \b -msgbox_mask \e 0xN: \anchor op_msgbox_mask |
| Controls whether DynamoRIO uses pop-up message boxes on Windows, |
| or waits for a key press on Linux, when presenting information. |
| The mask takes the following bitfields: |
| - INFORMATION = 0x1 |
| - WARNING = 0x2 |
| - ERROR = 0x4 |
| - CRITICAL = 0x8 |
| . |
| dr_messagebox() is not affected by -msgbox_mask. For the |
| provided Windows debug build -msgbox_mask defaults to 0xC. |
| On Linux the default is 0, as this feature reads from standard input and |
| might conflict with some applications. On Linux the pause can be |
| changed to use an infinite loop rather than reading from standard input |
| by passing the \b -pause_via_loop runtime option, which allows attaching |
| a debugger. |
| |
| \attention |
| On Vista or higher most Windows services are currently unable to display |
| message boxes (see \ref limits_vista_service_messagebox |
| "Limitations"). Since these services also don't have an associated |
| console for stderr printing, the \ref op_loglevel "-loglevel" |
| and \ref op_logmask "-logmask" options should be used |
| instead. For the messages that would be displayed by -msgbox_mask, |
| setting any bit in -logmask is sufficient for the message to be |
| included in the logfile. |
| |
| - \b -stderr_mask \e 0xN: |
| Parallel to -msgbox_mask, but controls DynamoRIO's output to standard |
| error. This option takes the same bitfields as -msgbox_mask. The API |
| routine dr_is_notify_on() can be used to determine if -stderr_mask is |
| non-zero. Messages printed to stderr will only be visible for |
| applications that have an attached console. They will not be visible |
| in the \p cmd console on Windows 7 or earlier or on any Windows version |
| when running a graphical application in \p cmd (even with dr_enable_console_printing(), |
| as that only affects clients calling dr_printf() or dr_fprintf()) but |
| the output can be viewed from \p cmd by redirecting to a file. |
| For the provided Linux |
| debug builds, -stderr_mask defaults to 0xF; for the Linux release |
| builds, its default is 0xE. The default on Windows is 0. |
| |
| \ifnot vmsafe |
| Options aiding in debugging: |
| |
| - \b -no_hide: \anchor op_no_hide |
| By default, DynamoRIO hides itself from the Windows module list, for |
| transparency. However, this makes it more difficult to debug a process |
| under DynamoRIO's control. The option -no_hide turns off this module |
| hiding. However, the client library and any libraries it imports from |
| will still be hidden. We provide a windbg script that can locate |
| DynamoRIO, the client library, and all of its dependences, so this |
| option should no longer be necessary (see \ref sec_debugging). |
| This option is for Windows only. |
| \endif |
| |
| Options available only in the debug build of DynamoRIO: |
| |
| \anchor op_loglevel |
| - \b -loglevel \e N: |
| If N is greater than 0, DynamoRIO prints out a log of its actions. |
| The greater the value of N, the more information DynamoRIO prints. |
| Useful ranges are from 1 to 6. Verbosity is set to 0 by default, i.e., |
| no log written. All log files are kept in a log directory. There is |
| one directory per address space per run. The directories are named \e |
| app.NNN, where \e app is the application name and \e NNN is a number |
| that is incremented with each directory created. On |
| Windows the directories are located by default in |
| a subdirectory \e logs of the DynamoRIO home directory as |
| specified in the dr_register_process(), \c drconfig, or \c drrun |
| configuration for the target application. |
| The runtime option \ref op_logdir "-logdir" can be used to override the |
| default directory. |
| There is one main log file per directory named |
| \e app.0.TID.html, where \e TID is the thread identifier of the initial |
| thread. There is also a log file per thread, named \e log.N.TID.html, |
| where \e N is the thread's creation ordinal and \e TID is its thread |
| identifier. The loglevel may be changed during program execution, but |
| if it began at 0 then it cannot be raised later. The -logmask |
| parameter can be used to control which DynamoRIO modules output data |
| to the log files. dr_log() allows the client to write to the above |
| logfiles. |
| |
| \anchor op_logmask |
| - \b -logmask \e 0xN: |
| Selects which DynamoRIO modules print out logging information, at the |
| -loglevel level. The mask is a combination of the LOG_ bitfields |
| listed in dr_tools.h (#LOG_ALL selects all modules). |
| |
| \anchor op_logdir |
| - \b -logdir \e \<path\>: |
| Specifies the directory to use for log files. See the documentation |
| for \ref op_loglevel "-loglevel" for a description of the default |
| log directory. |
| |
| - \b -ignore_assert_list \b '*': \anchor op_ignore_assert |
| Ignores all DynamoRIO asserts of the form "<file>:1234". * may be |
| replaced by a ; separated list of individual asserts to ignore |
| "foo.c:333;bar.c:12". |
| |
| *************************************************************************** |
| \section sec_debugging Diagnosing and Reporting Problems |
| |
| When using a complex system like DynamoRIO, problems can be challenging to |
| diagnose. This section contains some debugging tips and shows how to get |
| help. |
| |
| \subsection sec_reporting Obtaining Help and Reporting Problems |
| |
| For questions and discussion, join the <a |
| href="http://groups.google.com/group/dynamorio-users/">DynamoRIO Users |
| group</a>. |
| |
| For bug reports, use the <a |
| href="https://github.com/DynamoRIO/dynamorio/issues">Issue Tracker</a>. |
| Please include <a |
| href="https://github.com/DynamoRIO/dynamorio/wiki/Bug-Reporting">a detailed |
| description</a> of the problem (is it an application crash? a DynamoRIO |
| crash? a hang? a debug build assert?) and how to reproduce it. |
| |
| \subsection sec_diagnosing Troubleshooting |
| |
| - DynamoRIO disables itself when Windows is booted in safe mode (without |
| networking). Thus, if a crash occurs in a Windows service under |
| DynamoRIO, rebooting in safe mode will allow recovery. |
| |
| - If the client library doesn't seem to function for a given process, it is |
| likely that the client library wasn't loaded due to errors. |
| |
| \par |
| One of the common situations where this happens is when the target |
| application runs as a different user than the user who created the client |
| library. This results in the application process not having the right |
| permissions to access the client library. |
| |
| \par |
| Try running the process under the debug mode of DynamoRIO (see |
| dr_register_process()), where diagnostic messages are raised on errors like |
| client library permissions. To see all messages, set the notification |
| options like -msgbox_mask and -stderr_mask options to 0xf (see \ref |
| sec_options). This will alert you to the problem. |
| |
| - DynamoRIO asserts of the form "<file>:1234" can be suppressed with |
| the \ref op_ignore_assert "-ignore_assert_list '*'" option. * may |
| be replaced by a ; separated lists of individual asserts to |
| suppress as so "-ignore_assert_list 'foo.c:333;bar.c:12'". |
| |
| - The DynamoRIO header files have typedefs that may conflict with other |
| header files wrapped in ifndef DR_DO_NOT_DEFINE_<type> to make it |
| easier to work around such conflicts. |
| |
| \ifnot vmsafe |
| \subsection sec_using_debugger Using Debuggers |
| |
| A process under control of DynamoRIO can be executed within a debugger. |
| For debugging on Windows we recommend using windbg version 6.3.0017 (\b not |
| the newer versions, as they have problems displaying callstacks involving |
| DynamoRIO code). |
| |
| Normally, the debugger will not be aware of the DynamoRIO library or the |
| client library. We provide a windbg script that locates the DynamoRIO |
| library, the client library, and any privately-loaded dependent libraries. |
| The script is in \c bin32/load_syms.txt and \c bin64/load_syms64.txt. To |
| load it from windbg, execute the following command: |
| |
| \code |
| $><c:\path\to\DR\bin32\load_syms.txt |
| \endcode |
| When debugging often, modify the shortcut that launches windbg |
| to include this command as a -c argument. E.g.: |
| |
| \code |
| "C:\Program Files (x86)\Debugging Tools for Windows\windbg.exe" -pt 1 -c "$><c:\tools\DynamoRIO\bin32\load_syms.txt" |
| \endcode |
| |
| On Windows, the \ref op_no_hide "-no_hide" option can alternatively be |
| used so the debugger can see the DynamoRIO library, but the debugger |
| will still not be able to see the client library or any of its |
| dependent libraries. We recommend using our script. |
| |
| To attach to a process on Windows, use the \ref op_msgbox_mask |
| "-msgbox_mask" option and attach the debugger while the dialog box has |
| paused the application. On Linux, the same option can be used and |
| the debugger attached while the application waits for enter to be |
| pressed. Since this may not work for applications that themselves |
| read from standard input, we also provide the \b -pause_via_loop runtime |
| option which sits in an infinite loop rather than waiting for a keypress. |
| |
| To run an application on Linux under a debugger from process start you |
| can launch drrun under gdb as you would normally: |
| |
| \code |
| gdb --args path/to/drrun <options> -- path/to/app |
| \endcode |
| |
| Because the executable changes from drrun to the app, the app cannot be |
| re-run from gdb's prompt. |
| |
| On Linux, the main drawback of debugging from application start rather |
| than attaching is that breakpoint instructions (\c int3) inserted by |
| the debugger get copied into the code cache. This includes internal |
| debugger breakpoints automatically placed in the loader, as well as |
| user-defined breakpoints. For example, gdb puts a breakpoint on |
| __nptl_create_event, which is called by pthread_create and related |
| calls. See https://github.com/DynamoRIO/dynamorio/issues/490. |
| The debugger will handle these traps, but the user must tell it to |
| continue, which is an annoyance. For user breakpoints, consider using |
| read watchpoints on the code in question instead. |
| |
| On Windows, if an application invokes OutputDebugString() while under a |
| debugger, DynamoRIO can end up losing control of the application. |
| |
| For additional tips, check the DynamoRIO wiki page on debugging: |
| https://github.com/DynamoRIO/dynamorio/wiki/Debugging |
| |
| \endif |
| |
| **************************************************************************** |
| **************************************************************************** |
| */ |
| /* It's good to use separate C comments: we've hit some sort of doxygen |
| * internal buffering error before if one comment gets too long. |
| */ |
| /** |
| *************************************************************************** |
| *************************************************************************** |
| \ifnot vmsafe |
| \page page_standalone 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: |
| |
| - \ref sec_IR |
| - \ref sec_decode |
| |
| \section sec_standalone 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 \p 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: |
| |
| \code dr_standalone_init() \endcode |
| |
| This routine returns a dummy context that can be passed to API routines. |
| |
| When using \p drdecode, the special context \p GLOBAL_DCONTEXT should be |
| used whenever a context is required. The \p drdecode library does not |
| require initialization. |
| |
| Neither the context returned by dr_standalone_init() nor \p |
| 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 \p VENDOR_INTEL. Use |
| proc_set_vendor() to set to \p 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 \p 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 \p 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 \p drdecode. |
| |
| When using DynamoRIO's CMake support, use the configure_DynamoRIO_decoder() |
| function to set up include directories and to link with \p drdecode. The |
| next section describes how to link with the DynamoRIO shared library. |
| |
| \subsection sec_relativize 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: |
| |
| \code |
| instr_set_raw_bits_valid(instr, false) |
| \endcode |
| |
| When not in standalone mode, all branches are mangled and thus this is |
| never an issue. This should be fixed in a future release. |
| |
| |
| \section sec_standalone_shared DynamoRIO Shared Library Issues |
| |
| Since the DynamoRIO library on Windows includes or forwards |
| implementations of certain C library routines (see |
| \ref subsec_forwards "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: |
| |
| \code /link /nodefaultlib libcmt.lib dynamorio.lib \endcode |
| |
| 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 (\ref sec_ex8) 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 \ref sec_build 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. |
| |
| \endif |
| |
| */ |