• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // mach_override.h semver:1.2.0
2 //   Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3 //   Some rights reserved: http://opensource.org/licenses/mit
4 //   https://github.com/rentzsch/mach_override
5 
6 #ifndef		_mach_override_
7 #define		_mach_override_
8 
9 #include <sys/types.h>
10 #include <mach/error.h>
11 
12 #define	err_cannot_override	(err_local|1)
13 
14 __BEGIN_DECLS
15 
16 /****************************************************************************************
17 	Dynamically overrides the function implementation referenced by
18 	originalFunctionAddress with the implentation pointed to by overrideFunctionAddress.
19 	Optionally returns a pointer to a "reentry island" which, if jumped to, will resume
20 	the original implementation.
21 
22 	@param	originalFunctionAddress			->	Required address of the function to
23 												override (with overrideFunctionAddress).
24 	@param	overrideFunctionAddress			->	Required address to the overriding
25 												function.
26 	@param	originalFunctionReentryIsland	<-	Optional pointer to pointer to the
27 												reentry island. Can be NULL.
28 	@result									<-	err_cannot_override if the original
29 												function's implementation begins with
30 												the 'mfctr' instruction.
31 
32 	************************************************************************************/
33 
34     mach_error_t
35 mach_override_ptr(
36 	void *originalFunctionAddress,
37     const void *overrideFunctionAddress,
38     void **originalFunctionReentryIsland );
39 
40 __END_DECLS
41 
42 /****************************************************************************************
43 	If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping
44 	track of reentry islands and defining your override code. See test_mach_override.cp
45 	for example usage.
46 
47 	************************************************************************************/
48 
49 #ifdef	__cplusplus
50 #define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR )		\
51 {																												\
52 	static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS;				\
53 	static bool ORIGINAL_FUNCTION_NAME##_overriden = false;														\
54 	class mach_override_class__##ORIGINAL_FUNCTION_NAME {														\
55 	public:																										\
56 		static kern_return_t override(void *originalFunctionPtr) {												\
57 			kern_return_t result = err_none;																	\
58 			if (!ORIGINAL_FUNCTION_NAME##_overriden) {															\
59 				ORIGINAL_FUNCTION_NAME##_overriden = true;														\
60 				result = mach_override_ptr( (void*)originalFunctionPtr,											\
61 											(void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement,	\
62 											(void**)&ORIGINAL_FUNCTION_NAME##_reenter );						\
63 			}																									\
64 			return result;																						\
65 		}																										\
66 		static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS {
67 
68 #define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME )																\
69 		}																										\
70 	};																											\
71 																												\
72 	err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME);				\
73 }
74 #endif
75 
76 #endif	//	_mach_override_
77