You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
3.1 KiB
76 lines
3.1 KiB
// mach_override.h semver:1.2.0 |
|
// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com |
|
// Some rights reserved: http://opensource.org/licenses/mit |
|
// https://github.com/rentzsch/mach_override |
|
|
|
#ifndef _mach_override_ |
|
#define _mach_override_ |
|
|
|
#include <sys/types.h> |
|
#include <mach/error.h> |
|
|
|
#define err_cannot_override (err_local|1) |
|
|
|
__BEGIN_DECLS |
|
|
|
/**************************************************************************************** |
|
Dynamically overrides the function implementation referenced by |
|
originalFunctionAddress with the implentation pointed to by overrideFunctionAddress. |
|
Optionally returns a pointer to a "reentry island" which, if jumped to, will resume |
|
the original implementation. |
|
|
|
@param originalFunctionAddress -> Required address of the function to |
|
override (with overrideFunctionAddress). |
|
@param overrideFunctionAddress -> Required address to the overriding |
|
function. |
|
@param originalFunctionReentryIsland <- Optional pointer to pointer to the |
|
reentry island. Can be NULL. |
|
@result <- err_cannot_override if the original |
|
function's implementation begins with |
|
the 'mfctr' instruction. |
|
|
|
************************************************************************************/ |
|
|
|
mach_error_t |
|
mach_override_ptr( |
|
void *originalFunctionAddress, |
|
const void *overrideFunctionAddress, |
|
void **originalFunctionReentryIsland ); |
|
|
|
__END_DECLS |
|
|
|
/**************************************************************************************** |
|
If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping |
|
track of reentry islands and defining your override code. See test_mach_override.cp |
|
for example usage. |
|
|
|
************************************************************************************/ |
|
|
|
#ifdef __cplusplus |
|
#define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \ |
|
{ \ |
|
static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \ |
|
static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \ |
|
class mach_override_class__##ORIGINAL_FUNCTION_NAME { \ |
|
public: \ |
|
static kern_return_t override(void *originalFunctionPtr) { \ |
|
kern_return_t result = err_none; \ |
|
if (!ORIGINAL_FUNCTION_NAME##_overriden) { \ |
|
ORIGINAL_FUNCTION_NAME##_overriden = true; \ |
|
result = mach_override_ptr( (void*)originalFunctionPtr, \ |
|
(void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \ |
|
(void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \ |
|
} \ |
|
return result; \ |
|
} \ |
|
static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS { |
|
|
|
#define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \ |
|
} \ |
|
}; \ |
|
\ |
|
err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \ |
|
} |
|
#endif |
|
|
|
#endif // _mach_override_
|
|
|