-
Notifications
You must be signed in to change notification settings - Fork 88
/
test_mach_override.cp
108 lines (83 loc) · 3.41 KB
/
test_mach_override.cp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <CoreServices/CoreServices.h>
#include "mach_override.h"
#define assertStrEqual( EXPECTED, ACTUAL ) if( strcmp( (EXPECTED), (ACTUAL) ) != 0 ) { printf( "EXPECTED: %s\nACTUAL: %s\n", (EXPECTED), (ACTUAL)); assert( strcmp( (EXPECTED), (ACTUAL) ) == 0 ); }
#define assertIntEqual( EXPECTED, ACTUAL ) if( (EXPECTED) != (ACTUAL) ) { printf( "EXPECTED: %d\nACTUAL: %d\n", (EXPECTED), (ACTUAL)); assert( (EXPECTED) == (ACTUAL) ); }
//------------------------------------------------------------------------------
#pragma mark Test Local Override by Pointer
const char* localFunction() {
asm("nop;nop;nop;nop;");
return __FUNCTION__;
}
const char* (*localOriginalPtr)() = localFunction;
void testLocalFunctionOverrideByPointer() {
// Test original.
assertStrEqual( "localFunction", localOriginalPtr() );
// Override local function by pointer.
kern_return_t err;
MACH_OVERRIDE( const char*, localFunction, (), err ) {
// Test calling through the reentry island back into the original
// implementation.
assertStrEqual( "localFunction", localFunction_reenter() );
return "localFunctionOverride";
} END_MACH_OVERRIDE(localFunction);
assert( !err );
// Test override took effect.
assertStrEqual( "localFunctionOverride", localOriginalPtr() );
}
//------------------------------------------------------------------------------
#pragma mark Test System Override by Pointer
char* (*strerrorPtr)(int) = strerror;
const char* strerrReturnValue = "Unknown error: 0";
void testSystemFunctionOverrideByPointer() {
SInt32 sysv;
if (Gestalt( gestaltSystemVersion, &sysv ) == noErr && sysv >= 0x1070)
strerrReturnValue = "Undefined error: 0";
// Test original.
assertStrEqual( strerrReturnValue, strerrorPtr( 0 ) );
// Override system function by pointer.
kern_return_t err;
MACH_OVERRIDE( char*, strerror, (int errnum), err ) {
// Test calling through the reentry island back into the original
// implementation.
assertStrEqual( strerrReturnValue, strerror_reenter( 0 ) );
return (char *)"strerrorOverride";
} END_MACH_OVERRIDE(strerror);
assert( !err );
// Test override took effect.
assertStrEqual( "strerrorOverride", strerrorPtr( 0 ) );
}
//------------------------------------------------------------------------------
#pragma mark Test System Override by Name
/* The following is commented out because it does not compile.
int strerror_rOverride( int errnum, char *strerrbuf, size_t buflen );
int (*strerror_rPtr)( int, char*, size_t ) = strerror_r;
int (*gReentry_strerror_r)( int, char*, size_t );
void testSystemFunctionOverrideByName() {
// Test original.
assertIntEqual( ERANGE, strerror_rPtr( 0, NULL, 0 ) );
// Override local function by pointer.
kern_return_t err = mach_override( (char*)"_strerror_r",
NULL,
(void*)&strerror_rOverride,
(void**)&gReentry_strerror_r );
// Test override took effect.
assertIntEqual( 0, strerror_rPtr( 0, NULL, 0 ) );
}
int strerror_rOverride( int errnum, char *strerrbuf, size_t buflen ) {
assertIntEqual( ERANGE, gReentry_strerror_r( 0, NULL, 0 ) );
return 0;
}
*/
//------------------------------------------------------------------------------
#pragma mark main
int main( int argc, const char *argv[] ) {
testLocalFunctionOverrideByPointer();
testSystemFunctionOverrideByPointer();
//testSystemFunctionOverrideByName();
printf( "success\n" );
return 0;
}