forked from opa334/libSandy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libSandy.m
96 lines (82 loc) · 3.35 KB
/
libSandy.m
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
#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#import <xpc/xpc.h>
#import "sandbox.h"
#import "HBLogWeak.h"
#import "libSandy.h"
extern char*** _NSGetArgv();
static NSString* safe_getExecutablePath()
{
char* executablePathC = **_NSGetArgv();
return [NSString stringWithUTF8String:executablePathC];
}
// calling libSandy functions from inside MobileGestaltHelper itself locks the system up so we need to prevent it
static BOOL isRunningInsideMobileGestaltHelper()
{
static BOOL isMgh;
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
isMgh = [safe_getExecutablePath().lastPathComponent isEqualToString:@"MobileGestaltHelper"];
});
return isMgh;
}
int libSandy_applyProfile(const char* profileName)
{
if(isRunningInsideMobileGestaltHelper()) return 0;
__block int retcode = kLibSandyErrorXPCFailure;
HBLogDebugWeak(@"[libSandy libSandy_applyProfile] attempting to apply profile %s", profileName);
xpc_connection_t mgConnection = xpc_connection_create_mach_service("com.apple.mobilegestalt.xpc", 0, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
xpc_connection_set_event_handler(mgConnection, ^(xpc_object_t object){});
xpc_connection_resume(mgConnection);
xpc_object_t getExtensionsMessage = xpc_dictionary_create(NULL,NULL,0);
xpc_dictionary_set_bool(getExtensionsMessage, "libSandy_isProfileMessage", YES);
xpc_dictionary_set_string(getExtensionsMessage, "profile", profileName);
xpc_object_t reply = xpc_connection_send_message_with_reply_sync(mgConnection, getExtensionsMessage);
if(reply)
{
xpc_type_t replyType = xpc_get_type(reply);
HBLogDebugWeak(@"[libSandy libSandy_applyProfile] got reply %s", xpc_copy_description(reply));
if(replyType == XPC_TYPE_DICTIONARY)
{
xpc_object_t extensions = xpc_dictionary_get_value(reply, "extensions");
xpc_type_t extensionsType = xpc_get_type(extensions);
if(extensionsType == XPC_TYPE_ARRAY)
{
HBLogDebugWeak(@"[libSandy libSandy_applyProfile] got extensions %s", xpc_copy_description(extensions));
retcode = kLibSandyErrorRestricted;
xpc_array_apply(extensions, ^bool(size_t index, xpc_object_t value)
{
if(xpc_get_type(value) == XPC_TYPE_STRING)
{
retcode = kLibSandySuccess; // if returned extensions has one or more tokens: SUCCESS
const char* ext = xpc_string_get_string_ptr(value);
__unused int64_t suc = sandbox_extension_consume(ext);
HBLogDebugWeak(@"[libSandy libSandy_applyProfile] Consumed extension (%s) -> %lld", ext, suc);
}
return true;
});
}
}
}
HBLogDebugWeak(@"[libSandy libSandy_applyProfile] applied profile %s => %d", profileName, retcode);
return retcode;
}
bool libSandy_works()
{
if(isRunningInsideMobileGestaltHelper()) return YES;
xpc_connection_t mgConnection = xpc_connection_create_mach_service("com.apple.mobilegestalt.xpc", 0, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
xpc_connection_set_event_handler(mgConnection, ^(xpc_object_t object){});
xpc_connection_resume(mgConnection);
xpc_object_t testMessage = xpc_dictionary_create(NULL,NULL,0);
xpc_dictionary_set_bool(testMessage, "libSandy_isTestMessage", YES);
xpc_object_t reply = xpc_connection_send_message_with_reply_sync(mgConnection, testMessage);
if(reply)
{
xpc_type_t replyType = xpc_get_type(reply);
if(replyType == XPC_TYPE_DICTIONARY)
{
return xpc_dictionary_get_bool(reply, "works");
}
}
return false;
}