| /* ********************************************************** |
| * Copyright (c) 2013 Google, Inc. All rights reserved. |
| * Copyright (c) 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. |
| */ |
| |
| #ifndef _DR_INJECT_H_ |
| #define _DR_INJECT_H_ 1 |
| |
| /* DR_API EXPORT TOFILE dr_inject.h */ |
| /* DR_API EXPORT BEGIN */ |
| /**************************************************************************** |
| * Injection API |
| */ |
| /** |
| * @file dr_inject.h |
| * @brief Injection API. Use these functions to launch processes under the |
| * control of DynamoRIO. |
| */ |
| |
| #ifndef ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE /* in VS2008+ */ |
| /** |
| * Special error code that is returned by \p dr_inject_prepare_to_exec |
| * or \p dr_inject_process_create when the target application image |
| * does not match the bitwidth of the injection front-end. |
| * The target process is still created: it is up to the caller to decide |
| * whether to abort (and if so, it should call dr_inject_process_exit()), |
| * although on Windows this is generally a fatal error with the current |
| * implementation. |
| * We use ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE in both Windows and Unix |
| * assuming no error code conflict on Unix. |
| */ |
| # define ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE 720L |
| /** |
| * Alias of ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE to indicate it is not |
| * a fatal error on Unix. |
| */ |
| # define WARN_IMAGE_MACHINE_TYPE_MISMATCH_EXE ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE |
| #endif |
| |
| DR_EXPORT |
| /** |
| * Creates a new process for the executable and command line specified. |
| * The initial thread in the process is suspended. |
| * Use dr_inject_process_inject() to inject DynamoRIO into the process |
| * (first calling dr_register_process() to configure the process, for |
| * one-time targeted configuration), dr_inject_process_run() to resume |
| * the thread, and dr_inject_process_exit() to finish and free |
| * resources. |
| * |
| * \param[in] app_name The path to the target executable. The caller |
| * must ensure this data is valid until the |
| * inject data is disposed. |
| * |
| * \param[in] app_cmdline A NULL-terminated array of strings representing |
| * the app's command line. This should match what |
| * the app will receive as \p argv in main(). The |
| * caller must ensure this data is valid until the |
| * inject data is disposed. |
| * |
| * \param[out] data An opaque pointer that should be passed to |
| * subsequent dr_inject_* routines to refer to |
| * this process. |
| * \return Returns 0 on success. On failure, returns a system error code. |
| * For a mismatched bitwidth, the code is |
| * ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE. |
| * On returning ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE on Unix, \p data |
| * will be initialized and child process created: i.e., it is merely a |
| * warning, and the caller may continue with cross arch injection. |
| * Regardless of success, caller must call dr_inject_process_exit() |
| * when finished to clean up internally-allocated resources. |
| */ |
| int |
| dr_inject_process_create(const char *app_name, const char **app_cmdline, |
| void **data); |
| |
| #ifdef UNIX |
| |
| DR_EXPORT |
| /** |
| * Prepare to exec() the provided command from the current process. Use |
| * dr_inject_process_inject() to perform the exec() under DR. |
| * |
| * \note Only available on Linux. |
| * |
| * \param[in] app_name The path to the target executable. The caller |
| * must ensure this data is valid until the |
| * inject data is disposed. |
| * |
| * \param[in] app_cmdline A NULL-terminated array of strings representing |
| * the app's command line. This should match what |
| * the app will receive as \p argv in main(). The |
| * caller must ensure this data is valid until the |
| * inject data is disposed. |
| * |
| * \param[out] data An opaque pointer that should be passed to |
| * subsequent dr_inject_* routines to refer to |
| * this process. |
| * \return Returns 0 on success. On failure, returns a system error code. |
| * For a mismatched bitwidth, the code is |
| * ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE. |
| * On returning ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE on Unix, \p data |
| * will be initialized: i.e., it is merely a warning, and the caller |
| * may continue with cross arch injection. |
| * Regardless of success, caller must call dr_inject_process_exit() |
| * when finished to clean up internally-allocated resources. |
| */ |
| int |
| dr_inject_prepare_to_exec(const char *app_name, const char **app_cmdline, |
| void **data); |
| |
| DR_EXPORT |
| /** |
| * Use the ptrace system call to inject into the targetted process. Must be |
| * called before dr_inject_process_inject(). Does not work with |
| * dr_inject_prepare_to_exec(). |
| * |
| * Newer Linux distributions restrict which processes can be ptraced. If DR |
| * fails to attach, make sure that gdb can attach to the process in question. |
| * |
| * Once in the injectee, DynamoRIO searches the $HOME directory of the user of |
| * the injector, not the user of the injectee. Normal usage of drconfig and |
| * drinjectlib will ensure that DynamoRIO finds the right config files, however |
| * users that wish to examine config files need to check the home directory of |
| * the injector's user. |
| * |
| * \warning ptrace injection is still experimental and subject to change. |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \return Whether successful. |
| */ |
| bool |
| dr_inject_prepare_to_ptrace(void *data); |
| |
| /** |
| * Put the child in a new process group. If termination is requested with |
| * dr_inject_process_exit(), the entire child process group is killed. Using |
| * this option creates a new process group, so if the process group of the |
| * injector is killed, the child will survive, which may not be desirable. |
| * This routine only operates on child process, and will fail if |
| * dr_inject_prepare_to_exec() has been called instead of |
| * dr_inject_process_create(). |
| * |
| * \note Only available on Linux. |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| */ |
| bool |
| dr_inject_prepare_new_process_group(void *data); |
| |
| #endif /* UNIX */ |
| |
| DR_EXPORT |
| /** |
| * Injects DynamoRIO into a process created by dr_inject_process_create(), or |
| * the current process if using dr_inject_prepare_to_exec() on Linux. |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \param[in] force_injection Requests injection even if the process is |
| * configured to not be run under DynamoRIO. |
| * |
| * \param[in] library_path The path to the DynamoRIO library to use. If |
| * NULL, the library that the target process is |
| * configured for will be used. |
| * |
| * \return Whether successful. |
| */ |
| bool |
| dr_inject_process_inject(void *data, bool force_injection, |
| const char *library_path); |
| |
| DR_EXPORT |
| /** |
| * Resumes the suspended thread in a process created by dr_inject_process_create(). |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \return Whether successful. |
| */ |
| bool |
| dr_inject_process_run(void *data); |
| |
| DR_EXPORT |
| /** |
| * Waits for the child process to exit with the given timeout. |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * \param[in] timeout_millis The timeout in milliseconds. Zero means wait |
| * forever. |
| * |
| * \return Return true if the child exited, and false if we timed out. |
| * |
| * \note On Linux, this sets a signal handler for SIGALRM. |
| */ |
| bool |
| dr_inject_wait_for_child(void *data, uint64 timeout_millis); |
| |
| DR_EXPORT |
| /** |
| * Frees resources used by dr_inject_process_create(). Does not wait for the |
| * child to exit, unless terminate is true. |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \param[in] terminate If true, the process is forcibly terminated. |
| * |
| * \return Returns the exit code of the process. If the caller did not wait |
| * for the process to finish before calling this, the code will be |
| * STILL_ACTIVE. |
| */ |
| int |
| dr_inject_process_exit(void *data, bool terminate); |
| |
| DR_EXPORT |
| /** |
| * Returns the process name of a process created by dr_inject_process_create(). |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \return Returns the process name of the process. This is the file name |
| * without the path, suitable for passing to dr_register_process(). |
| */ |
| char * |
| dr_inject_get_image_name(void *data); |
| |
| #ifdef WINDOWS |
| DR_EXPORT |
| /** |
| * Returns a handle to a process created by dr_inject_process_create(). |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \note Windows only. |
| * |
| * \return Returns the handle used by drinjectlib. Do not close the handle: it |
| * will be closed in dr_inject_process_exit(). |
| */ |
| HANDLE |
| dr_inject_get_process_handle(void *data); |
| #endif /* WINDOWS */ |
| |
| DR_EXPORT |
| /** |
| * Returns the pid of a process created by dr_inject_process_create(). |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \return Returns the pid of the process. |
| */ |
| process_id_t |
| dr_inject_get_process_id(void *data); |
| |
| DR_EXPORT |
| /* Deliberately not documented: not fully supported */ |
| bool |
| dr_inject_using_debug_key(void *data); |
| |
| DR_EXPORT |
| /** |
| * Prints statistics for a process created by dr_inject_process_create(). |
| * |
| * \param[in] data The pointer returned by dr_inject_process_create() |
| * |
| * \param[in] elapsed_secs Elapsed time recorded by the caller that will be |
| * printed by this routine if showstats is true. |
| * |
| * \param[in] showstats If true, elapsed_secs and resource usage is printed. |
| * |
| * \param[in] showmem If true, memory usage statistics are printed. |
| */ |
| void |
| dr_inject_print_stats(void *data, int elapsed_secs, bool showstats, bool showmem); |
| |
| /* DR_API EXPORT END */ |
| |
| #endif /* _DR_INJECT_H_ */ |