forked from Tonyk7/MGSpoof
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tweak.xm
83 lines (71 loc) · 3.45 KB
/
Tweak.xm
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
#import <substrate.h>
#import <stdint.h>
extern "C" CFPropertyListRef MGCopyAnswer(CFStringRef);
static NSDictionary *modifiedKeys;
static NSArray *appsChosen;
/* step64 and follow_cal functions are taken from: https://github.com/xerub/macho/blob/master/patchfinder64.c */
typedef unsigned long long addr_t;
static addr_t step64(const uint8_t *buf, addr_t start, size_t length, uint32_t what, uint32_t mask) {
addr_t end = start + length;
while (start < end) {
uint32_t x = *(uint32_t *)(buf + start);
if ((x & mask) == what) {
return start;
}
start += 4;
}
return 0;
}
// Modified version of find_call64(), replaced what/mask arguments in the function to the ones for branch instruction (0x14000000, 0xFC000000)
static addr_t find_branch64(const uint8_t *buf, addr_t start, size_t length) {
return step64(buf, start, length, 0x14000000, 0xFC000000);
}
static addr_t follow_branch64(const uint8_t *buf, addr_t branch) {
long long w;
w = *(uint32_t *)(buf + branch) & 0x3FFFFFF;
w <<= 64 - 26;
w >>= 64 - 26 - 2;
return branch + w;
}
// Our replaced version of MGCopyAnswer_internal
static CFPropertyListRef (*orig_MGCopyAnswer_internal)(CFStringRef property, uint32_t *outTypeCode);
CFPropertyListRef new_MGCopyAnswer_internal(CFStringRef property, uint32_t *outTypeCode) {
if (modifiedKeys[(__bridge NSString *)property]) {
return (__bridge_retained CFStringRef)modifiedKeys[(__bridge NSString *)property];
}
return orig_MGCopyAnswer_internal(property, outTypeCode);
}
static void appsChosenUpdated() {
NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"];
appsChosen = [prefs objectForKey:@"spoofApps"];
}
static void modifiedKeyUpdated() {
NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"];
modifiedKeys = [prefs objectForKey:@"modifiedKeys"];
}
%ctor {
@autoreleasepool {
appsChosenUpdated();
// don't do anything if we in an app we don't want to spoof anything
if (![appsChosen containsObject:[NSBundle mainBundle].bundleIdentifier])
return;
// basically dlopen libMobileGestalt
MSImageRef libGestalt = MSGetImageByName("/usr/lib/libMobileGestalt.dylib");
if (libGestalt) {
// Get "_MGCopyAnswer" symbol
void *MGCopyAnswerFn = MSFindSymbol(libGestalt, "_MGCopyAnswer");
/*
* get address of MGCopyAnswer_internal by doing symbol + offset (should be 8 bytes)
* note: hex implementation of MGCopyAnswer: 01 00 80 d2 01 00 00 14 (from iOS 9+)
* so address of MGCopyAnswer + offset = MGCopyAnswer_internal. MGCopyAnswer_internal *always follows MGCopyAnswer (*from what I've checked)
*/
const uint8_t *MGCopyAnswer_ptr = (const uint8_t *)MGCopyAnswer;
addr_t branch = find_branch64(MGCopyAnswer_ptr, 0, 8);
addr_t branch_offset = follow_branch64(MGCopyAnswer_ptr, branch);
MSHookFunction(((void *)((const uint8_t *)MGCopyAnswerFn + branch_offset)), (void *)new_MGCopyAnswer_internal, (void **)&orig_MGCopyAnswer_internal);
}
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)appsChosenUpdated, CFSTR("com.tonyk7.mgspoof/appsChosenUpdated"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)modifiedKeyUpdated, CFSTR("com.tonyk7.mgspoof/modifiedKeyUpdated"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
modifiedKeyUpdated();
}
}