pub unsafe extern "C" fn drwrap_replace_native(
original: app_pc,
replacement: app_pc,
at_entry: bool_,
stack_adjust: uint,
user_data: *mut c_void,
override_: bool_,
) -> bool_Expand description
\warning This interface is in flux and is subject to change in the next release. Consider it experimental in this release.
Replaces the application function that starts at the address \p original with the natively-executed (i.e., as the client) code at the address \p replacement. The replacement should either be the function entry point or a call site for the function, indicated by the \p at_entry parameter. For a call site, only that particular call will be replaced, rather than every call to \p replacement.
The replacement function must call drwrap_replace_native_fini() prior to returning. If it fails to do so, control will be lost and subsequent application code will not be under DynamoRIO control. The fini routine sets up a continuation function that is used rather than a direct return. This continuation strategy enables the replacement function to use application locks (if they are marked with dr_mark_safe_to_suspend()) safely, as there is no code cache return point.
The replacement function should use the same calling convention as the original with respect to argument access. In order to match the calling convention return for conventions in which the callee cleans up arguments on the stack, use the \p stack_adjust parameter to request a return that adjusts the stack. This return will be executed as a regular basic block and thus a stack-tracking client will not observe any missing stack adjustments. The \p stack_adjust parameter must be a multiple of sizeof(void*).
If \p user_data != NULL, it is stored in a scratch slot for access by \p replacement by calling dr_read_saved_reg() and passing DRWRAP_REPLACE_NATIVE_DATA_SLOT.
Only one replacement is supported per target address. If a replacement already exists for \p original, this function fails unless \p override is true, in which case it replaces the prior replacement. To remove a replacement, pass NULL for \p replacement and \b true for \p override. When removing or replacing a prior replacement, existing replaced code in the code cache will be flushed lazily: i.e., there may be some execution in other threads after this call is made.
Non-native replacements take precedence over native. I.e., if a drwrap_replace() replacement exists for \p original, then a native replacement request for \p original will never take effect.
Only the first target replacement address in a basic block will be honored. All code after that address is removed.
When replacing a function, it is up to the user to ensure that the replacement mirrors the calling convention and other semantics of the original function.
The replacement code will be executed as client code, NOT as application code. However, it will use the application stack and other machine state. Usually it is good practice to call dr_switch_to_app_state() inside the replacement code, and then dr_switch_to_dr_state() before returning, in particular on Windows. To additionally use a clean DR stack, consider using dr_call_on_clean_stack() from the initial replacement layer (which allows the outer layer to handle stdcall, which dr_call_on_clean_stack does not support).
The replacement code is not allowed to invoke dr_flush_region() or dr_delete_fragment() as it has no #dr_mcontext_t with which to invoke dr_redirect_execution(): it must return to the call-out point in the code cache. If the replacement code does not return to its return address, DR will lose control of the application and not continue executing it properly.
@param[in] original The address of either the application function entry point (in which case \p at_entry must be true) or of a call site (the actual call or tailcall/inter-library jump) (in which case \p at_entry must be false). @param[in] replacement The function entry to use instead. @param[in] at_entry Indicates whether \p original is the function entry point or a call site. @param[in] stack_adjust The stack adjustment performed at return for the calling convention used by \p original. On ARM, this must be zero. @param[in] user_data Data made available when \p replacement is executed. @param[in] override Whether to replace any existing replacement for \p original.
\note The mechanism used for a native replacement results in a \p ret instruction appearing in the code stream with an application address that is different from an execution without a native replacement. The return address will be identical, however, assuming \p original does not replace its own return address.
\note The application stack address at which its return address is stored is available by calling dr_read_saved_reg() and passing DRWRAP_REPLACE_NATIVE_SP_SLOT.
\note The priority of the app2app pass used here is DRMGR_PRIORITY_APP2APP_DRWRAP and its name is DRMGR_PRIORITY_NAME_DRWRAP.
\note Far calls are not supported.
\note Not supported if #DRWRAP_INVERT_CONTROL is set.
\return whether successful.