├── LICENSE ├── MGSpoof.plist ├── Makefile ├── README.md ├── Tweak.xm ├── control └── mgspoofhelper ├── MGAppPickerController.h ├── MGAppPickerController.m ├── MGKeyPickerController.h ├── MGKeyPickerController.m ├── MGSpoofHelperAppDelegate.h ├── MGSpoofHelperAppDelegate.m ├── MGSpoofHelperPrefs.h ├── MGSpoofHelperPrefs.m ├── MGSpoofHelperRootViewController.h ├── MGSpoofHelperRootViewController.m ├── Makefile ├── Resources ├── AppIcon29x29.png ├── AppIcon29x29@2x.png ├── AppIcon29x29@3x.png ├── AppIcon40x40.png ├── AppIcon40x40@2x.png ├── AppIcon40x40@3x.png ├── AppIcon50x50.png ├── AppIcon50x50@2x.png ├── AppIcon57x57.png ├── AppIcon57x57@2x.png ├── AppIcon57x57@3x.png ├── AppIcon60x60.png ├── AppIcon60x60@2x.png ├── AppIcon60x60@3x.png ├── AppIcon72x72.png ├── AppIcon72x72@2x.png ├── AppIcon76x76.png ├── AppIcon76x76@2x.png ├── Info.plist ├── LaunchImage-700-568h@2x.png ├── LaunchImage-700-Landscape@2x~ipad.png ├── LaunchImage-700-Landscape~ipad.png ├── LaunchImage-700-Portrait@2x~ipad.png ├── LaunchImage-700-Portrait~ipad.png ├── LaunchImage-800-667h@2x.png ├── LaunchImage-800-Landscape-736h@3x.png ├── LaunchImage-800-Portrait-736h@3x.png ├── LaunchImage.png └── LaunchImage@2x.png ├── ent.xml └── main.m /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tony 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MGSpoof.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.UIKit" ); }; } 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | TWEAK_NAME = MGSpoof 4 | MGSpoof_FILES = Tweak.xm 5 | MGSpoof_CFLAGS = -fobjc-arc 6 | MGSpoof_LIBRARIES = MobileGestalt 7 | 8 | include $(THEOS_MAKE_PATH)/tweak.mk 9 | 10 | after-install:: 11 | install.exec "killall -9 SpringBoard" 12 | SUBPROJECTS += mgspoofhelper 13 | include $(THEOS_MAKE_PATH)/aggregate.mk 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MGSpoofer (spoof MGCopyAnswer) 2 | 3 | #### update log 4 | 5 | _0.0.3_ (credit: **[@jakeashacks](https://twitter.com/jakeashacks)**): 6 | - iOS 13 support 7 | - checkra1n fix 8 | - bug fix 9 | - allow SpringBoard 10 | 11 | _0.0.2_: 12 | - added randomize value button (follows same format as original) 13 | - fixed names of sections for key page 14 | - fixed "Reset Prefs" button to actually reset prefs 15 | - other small fixes/improvements 16 | 17 | _0.0.1_: 18 | - initial release 19 | 20 | #### Q/A 21 | 22 | Q: What is this tweak? 23 | A: for me it was a learning project but for you it's the ability to spoof device information (udid, serial number, etc..) 24 | 25 | Q: What can I do with this tweak? 26 | A: Evade bans from certain apps, mess with people, endless posibilities 27 | 28 | Q: Where can I get this tweak: 29 | A: [repo](http://tonyk7.github.io) 30 | 31 | #### other info 32 | - update: github messed up indentation, idk why and not sure how to fix, let me know if you can help with that 33 | - feel free to make pull requests of any improvements 34 | 35 | #### Contact: 36 | if you have any questions or anything, feel free to contact me 37 | - Twitter: @TonerK7 38 | -------------------------------------------------------------------------------- /Tweak.xm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | extern "C" CFPropertyListRef MGCopyAnswer(CFStringRef); 5 | static NSDictionary *modifiedKeys; 6 | static NSArray *appsChosen; 7 | 8 | /* step64 and follow_cal functions are taken from: https://github.com/xerub/macho/blob/master/patchfinder64.c */ 9 | typedef unsigned long long addr_t; 10 | 11 | static addr_t step64(const uint8_t *buf, addr_t start, size_t length, uint32_t what, uint32_t mask) { 12 | addr_t end = start + length; 13 | while (start < end) { 14 | uint32_t x = *(uint32_t *)(buf + start); 15 | if ((x & mask) == what) { 16 | return start; 17 | } 18 | start += 4; 19 | } 20 | return 0; 21 | } 22 | 23 | // Modified version of find_call64(), replaced what/mask arguments in the function to the ones for branch instruction (0x14000000, 0xFC000000) 24 | static addr_t find_branch64(const uint8_t *buf, addr_t start, size_t length) { 25 | return step64(buf, start, length, 0x14000000, 0xFC000000); 26 | } 27 | 28 | static addr_t follow_branch64(const uint8_t *buf, addr_t branch) { 29 | long long w; 30 | w = *(uint32_t *)(buf + branch) & 0x3FFFFFF; 31 | w <<= 64 - 26; 32 | w >>= 64 - 26 - 2; 33 | return branch + w; 34 | } 35 | 36 | // Our replaced version of MGCopyAnswer_internal 37 | static CFPropertyListRef (*orig_MGCopyAnswer_internal)(CFStringRef property, uint32_t *outTypeCode); 38 | CFPropertyListRef new_MGCopyAnswer_internal(CFStringRef property, uint32_t *outTypeCode) { 39 | if (modifiedKeys[(__bridge NSString *)property]) { 40 | return (__bridge_retained CFStringRef)modifiedKeys[(__bridge NSString *)property]; 41 | } 42 | return orig_MGCopyAnswer_internal(property, outTypeCode); 43 | } 44 | 45 | 46 | static void appsChosenUpdated() { 47 | NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 48 | appsChosen = [prefs objectForKey:@"spoofApps"]; 49 | } 50 | 51 | static void modifiedKeyUpdated() { 52 | NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 53 | modifiedKeys = [prefs objectForKey:@"modifiedKeys"]; 54 | } 55 | 56 | %ctor { 57 | @autoreleasepool { 58 | appsChosenUpdated(); 59 | // don't do anything if we in an app we don't want to spoof anything 60 | if (![appsChosen containsObject:[NSBundle mainBundle].bundleIdentifier]) 61 | return; 62 | 63 | // basically dlopen libMobileGestalt 64 | MSImageRef libGestalt = MSGetImageByName("/usr/lib/libMobileGestalt.dylib"); 65 | if (libGestalt) { 66 | // Get "_MGCopyAnswer" symbol 67 | void *MGCopyAnswerFn = MSFindSymbol(libGestalt, "_MGCopyAnswer"); 68 | /* 69 | * get address of MGCopyAnswer_internal by doing symbol + offset (should be 8 bytes) 70 | * note: hex implementation of MGCopyAnswer: 01 00 80 d2 01 00 00 14 (from iOS 9+) 71 | * so address of MGCopyAnswer + offset = MGCopyAnswer_internal. MGCopyAnswer_internal *always follows MGCopyAnswer (*from what I've checked) 72 | */ 73 | const uint8_t *MGCopyAnswer_ptr = (const uint8_t *)MGCopyAnswer; 74 | addr_t branch = find_branch64(MGCopyAnswer_ptr, 0, 8); 75 | addr_t branch_offset = follow_branch64(MGCopyAnswer_ptr, branch); 76 | MSHookFunction(((void *)((const uint8_t *)MGCopyAnswerFn + branch_offset)), (void *)new_MGCopyAnswer_internal, (void **)&orig_MGCopyAnswer_internal); 77 | } 78 | 79 | CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)appsChosenUpdated, CFSTR("com.tonyk7.mgspoof/appsChosenUpdated"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); 80 | CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)modifiedKeyUpdated, CFSTR("com.tonyk7.mgspoof/modifiedKeyUpdated"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); 81 | modifiedKeyUpdated(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.tonyk7.mgspoof 2 | Name: MGSpoof 3 | Depends: mobilesubstrate 4 | Version: 0.0.4 5 | Architecture: iphoneos-arm 6 | Description: Tool that can be used to spoof MGCopyAnswer's result. (iOS 9 - 13) 7 | Maintainer: Tony 8 | Author: Tony 9 | Section: Tweaks 10 | Depiction: https://tonyk7.github.io/description.html?id=com.tonyk7.mgspoof -------------------------------------------------------------------------------- /mgspoofhelper/MGAppPickerController.h: -------------------------------------------------------------------------------- 1 | @interface MGAppPickerController : UITableViewController { 2 | NSArray *hiddenDisplayIdentifiers; 3 | } 4 | @property (nonatomic, retain) NSDictionary *applications; 5 | @property (nonatomic, retain) NSArray *appTypes; 6 | @end 7 | -------------------------------------------------------------------------------- /mgspoofhelper/MGAppPickerController.m: -------------------------------------------------------------------------------- 1 | #import "MGAppPickerController.h" 2 | #import "MGSpoofHelperPrefs.h" 3 | 4 | CFPropertyListRef MGCopyAnswer(CFStringRef); 5 | 6 | @interface UIImage (MGSpoofHelper) 7 | +(UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)arg1 format:(int)arg2 scale:(float)arg3; 8 | +(UIImage *)imageNamed:(NSString *)arg1 inBundle:(NSBundle *)arg2; 9 | @end 10 | 11 | @interface LSApplicationWorkspace : NSObject 12 | +(id)defaultWorkspace; 13 | -(NSArray *)allInstalledApplications; 14 | @end 15 | 16 | @interface LSResourceProxy : NSObject 17 | @property (nonatomic, readonly) NSDictionary *iconsDictionary; 18 | @property (nonatomic, copy) NSArray *_boundIconFileNames; // iOS 11 and up 19 | @property (nonatomic, copy) NSArray *boundIconFileNames; // iOS 10 and below 20 | @end 21 | 22 | @interface LSApplicationProxy : LSResourceProxy 23 | +(LSApplicationProxy *)applicationProxyForIdentifier:(NSString *)arg1; 24 | @property (nonatomic, readonly) NSString *applicationIdentifier; // bundle id 25 | @property (nonatomic, readonly) NSString *applicationType; // system app or user app 26 | @property(nonatomic, readonly) NSArray *appTags; 27 | -(NSString *)localizedName; // app name under icon 28 | @end 29 | 30 | @implementation MGAppPickerController 31 | 32 | // Instead of using ipc to interact with springboard and get information and use SBApplicationController to do this, decided to get info using MobileCoreServices framework 33 | -(NSArray *)apps { 34 | NSMutableArray *allInstalledApplications = [[objc_getClass("LSApplicationWorkspace") defaultWorkspace] allInstalledApplications].mutableCopy; 35 | // add springboard so user can spoof stuff in springboard 36 | [allInstalledApplications addObject:[objc_getClass("LSApplicationProxy") applicationProxyForIdentifier:@"com.apple.springboard"]]; 37 | return allInstalledApplications; 38 | } 39 | 40 | -(NSDictionary *)appsDict { 41 | NSMutableDictionary *visibleApps = [[NSMutableDictionary alloc] init]; 42 | NSArray *allApps = [self apps]; 43 | for (LSApplicationProxy *app in allApps) { 44 | visibleApps[app.applicationIdentifier] = app.localizedName; 45 | } 46 | return visibleApps; 47 | } 48 | 49 | -(NSArray *)sortArray:(NSArray *)arrayToSort { 50 | return [arrayToSort sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 51 | } 52 | 53 | // first element is array of sorted user apps bundle ids, second element is same with system apps instead 54 | -(NSArray *)splitAppTypes { 55 | NSMutableArray *systemApps = @[].mutableCopy; 56 | NSMutableArray *userApps = @[].mutableCopy; 57 | for (LSApplicationProxy *app in [self apps]) { 58 | if ([self hasIconAndVisible:app]){ 59 | if ([app.applicationType isEqualToString:@"User"]) 60 | [userApps addObject:app.applicationIdentifier]; 61 | else if ([app.applicationType isEqualToString:@"System"] || [app.applicationIdentifier isEqualToString:@"com.apple.springboard"]) 62 | [systemApps addObject:app.applicationIdentifier]; 63 | } 64 | } 65 | return @[[self sortArray:userApps], [self sortArray:systemApps]]; 66 | } 67 | 68 | /// Method to check if app is hidden taken from KBAppList here: https://github.com/kanesbetas/KBAppList/blob/8653e1ee511639d341380b603e98b4cbce556dfb/Source/kbapplist/KBAppList.mm#L109-L118 69 | -(BOOL)hasIconAndVisible:(LSApplicationProxy *)app { 70 | // so mgspoofhelper doesn't show up in list 71 | if ([app.applicationIdentifier isEqualToString:@"com.tonyk7.mgspoofhelper"]) 72 | return NO; 73 | 74 | if ([app.applicationIdentifier isEqualToString:@"com.apple.springboard"]) 75 | return YES; 76 | 77 | if (app.iconsDictionary && ![app.appTags containsObject:@"hidden"] && ![app.appTags containsObject:@"SBInternalAppTag"]) 78 | return YES; 79 | 80 | return NO; 81 | } 82 | 83 | -(void)loadView { 84 | [super loadView]; 85 | self.tableView.dataSource = self; 86 | self.tableView.allowsSelection = NO; 87 | 88 | self.navigationItem.title = @"Select apps"; 89 | 90 | UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleDone target:self action:@selector(back)]; 91 | self.navigationItem.leftBarButtonItem = backButton; 92 | UIBarButtonItem *resetPrefsButton = [[UIBarButtonItem alloc] initWithTitle:@"Reset Prefs" style:UIBarButtonItemStyleDone target:self action:@selector(resetPrefs)]; 93 | self.navigationItem.rightBarButtonItem = resetPrefsButton; 94 | 95 | self.applications = [self appsDict]; 96 | self.appTypes = [self splitAppTypes]; 97 | } 98 | 99 | -(void)back { 100 | [self dismissViewControllerAnimated:YES completion:nil]; 101 | } 102 | 103 | -(void)resetPrefs { 104 | NSUserDefaults *userDeafaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 105 | // [userDeafaults removePersistentDomainForName:[NSBundle mainBundle].bundleIdentifier]; 106 | NSDictionary *defaultsDictionary = [userDeafaults dictionaryRepresentation]; 107 | for (NSString *key in defaultsDictionary.allKeys) { 108 | [userDeafaults removeObjectForKey:key]; 109 | } 110 | [self.tableView reloadData]; // turn off all switches 111 | } 112 | 113 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 114 | return 2; 115 | } 116 | 117 | -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 118 | switch (section) { 119 | case 0: 120 | return @"User apps"; 121 | case 1: 122 | return @"System apps"; 123 | default: 124 | return @"Other"; 125 | } 126 | } 127 | 128 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 129 | return self.appTypes[section].count; 130 | } 131 | 132 | -(void)fixImageView:(UIImageView *)imageView { 133 | /* bad way to do this */ 134 | // resize image 135 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(29, 29), NO, 0.0); 136 | [imageView.image drawInRect:CGRectMake(0, 0, 29, 29)]; 137 | UIImage *fixedImage = UIGraphicsGetImageFromCurrentImageContext(); 138 | UIGraphicsEndImageContext(); 139 | imageView.image = fixedImage; 140 | // mask imageview 141 | CALayer *mask = [CALayer layer]; 142 | NSBundle *mobileIcons = [NSBundle bundleWithIdentifier:@"com.apple.mobileicons.framework"]; 143 | mask.contents = (id)[UIImage imageNamed:@"AppIconMask" inBundle:mobileIcons].CGImage; 144 | mask.frame = CGRectMake(0, 0, 29, 29); 145 | imageView.layer.mask = mask; 146 | imageView.layer.masksToBounds = YES; 147 | } 148 | 149 | 150 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 151 | NSString *cellIdentifier = [NSString stringWithFormat:@"AppPickerCellC%ldR%ld", (long)indexPath.section, (long)indexPath.row]; 152 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 153 | 154 | if (!cell) { 155 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; 156 | } 157 | 158 | UISwitch *cellSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; 159 | [cellSwitch addTarget:self action:@selector(updateSwitch:) forControlEvents:UIControlEventTouchUpInside]; 160 | cellSwitch.tag = indexPath.row; 161 | cell.accessoryView = cellSwitch; 162 | 163 | NSString *bundleID = self.appTypes[indexPath.section][indexPath.row]; 164 | cell.textLabel.text = self.applications[bundleID]; 165 | cell.detailTextLabel.text = bundleID; 166 | 167 | UIImage *image = [UIImage _applicationIconImageForBundleIdentifier:bundleID format:0 scale:[UIScreen mainScreen].scale]; 168 | if (CGSizeEqualToSize(image.size, CGSizeMake(29, 29))) 169 | cell.imageView.image = image; 170 | else { 171 | // bad way to do this but whatever 172 | cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:bundleID format:10 scale:0]; 173 | [self fixImageView:cell.imageView]; 174 | } 175 | 176 | // make uiswitch on if it should be enabled 177 | if ([objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kExists inKey:@"spoofApps" withValue:bundleID]) 178 | [cellSwitch setOn:YES animated:NO]; 179 | 180 | return cell; 181 | } 182 | 183 | -(void)updateSwitch:(UISwitch *)updatedSwitch { 184 | UITableViewCell *cell = (UITableViewCell *)updatedSwitch.superview; 185 | NSString *bundleID = cell.detailTextLabel.text; 186 | if (updatedSwitch.isOn) 187 | [objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kAdd inKey:@"spoofApps" withValue:bundleID]; 188 | else 189 | [objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kRemove inKey:@"spoofApps" withValue:bundleID]; 190 | } 191 | 192 | @end 193 | -------------------------------------------------------------------------------- /mgspoofhelper/MGKeyPickerController.h: -------------------------------------------------------------------------------- 1 | @interface MGKeyPickerController : UITableViewController { 2 | NSMutableArray *selectedItems; 3 | NSArray *allKeys; 4 | } 5 | @end -------------------------------------------------------------------------------- /mgspoofhelper/MGKeyPickerController.m: -------------------------------------------------------------------------------- 1 | #import "MGKeyPickerController.h" 2 | #import "MGSpoofHelperPrefs.h" 3 | 4 | CFPropertyListRef MGCopyAnswer(CFStringRef); 5 | 6 | @implementation MGKeyPickerController 7 | 8 | -(void)loadView { 9 | [super loadView]; 10 | 11 | self.tableView.allowsMultipleSelection = YES; 12 | 13 | self.navigationItem.title = @"Add key to modify"; 14 | UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleDone target:self action:@selector(back)]; 15 | UIBarButtonItem *confirmAddButton = [[UIBarButtonItem alloc] initWithTitle:@"Add" style:UIBarButtonItemStyleDone target:self action:@selector(addKeysToModify)]; 16 | 17 | self.navigationItem.leftBarButtonItem = backButton; 18 | self.navigationItem.rightBarButtonItem = confirmAddButton; 19 | self.navigationItem.rightBarButtonItem.enabled = NO; 20 | 21 | // lol 22 | allKeys = @[@[@"DiskUsage", @"ModelNumber", @"SIMTrayStatus", @"SerialNumber", @"MLBSerialNumber", @"UniqueDeviceID", @"UniqueDeviceIDData", @"UniqueChipID", @"InverseDeviceID", @"DiagData", @"DieId", @"CPUArchitecture", @"PartitionType", @"UserAssignedDeviceName"],@[@"BluetoothAddress"],@[@"RequiredBatteryLevelForSoftwareUpdate", @"BatteryIsFullyCharged", @"BatteryIsCharging", @"BatteryCurrentCapacity", @"ExternalPowerSourceConnected"],@[@"BasebandSerialNumber", @"BasebandCertId", @"BasebandChipId", @"BasebandFirmwareManifestData", @"BasebandFirmwareVersion", @"BasebandKeyHashInformation"],@[@"CarrierBundleInfoArray", @"CarrierInstallCapability", @"InternationalMobileEquipmentIdentity", @"MobileSubscriberCountryCode", @"MobileSubscriberNetworkCode"],@[@"ChipID", @"ComputerName", @"DeviceVariant", @"HWModelStr", @"BoardId", @"HardwarePlatform", @"DeviceName", @"DeviceColor", @"DeviceClassNumber", @"DeviceClass", @"BuildVersion", @"ProductName", @"ProductType", @"ProductVersion", @"FirmwareNonce", @"FirmwareVersion", @"FirmwarePreflightInfo", @"IntegratedCircuitCardIdentifier", @"AirplaneMode", @"AllowYouTube", @"AllowYouTubePlugin", @"MinimumSupportediTunesVersion", @"ProximitySensorCalibration", @"RegionCode", @"RegionInfo", @"RegulatoryIdentifiers", @"SBAllowSensitiveUI", @"SBCanForceDebuggingInfo", @"SDIOManufacturerTuple", @"SDIOProductInfo", @"ShouldHactivate", @"SigningFuse", @"SoftwareBehavior", @"SoftwareBundleVersion", @"SupportedDeviceFamilies", @"SupportedKeyboards", @"TotalSystemAvailable"],@[@"AllDeviceCapabilities", @"AppleInternalInstallCapability", @"ExternalChargeCapability", @"ForwardCameraCapability", @"PanoramaCameraCapability", @"RearCameraCapability", @"HasAllFeaturesCapability", @"HasBaseband", @"HasInternalSettingsBundle", @"HasSpringBoard", @"InternalBuild", @"IsSimulator", @"IsThereEnoughBatteryLevelForSoftwareUpdate", @"IsUIBuild"],@[@"RegionalBehaviorAll", @"RegionalBehaviorChinaBrick", @"RegionalBehaviorEUVolumeLimit", @"RegionalBehaviorGB18030", @"RegionalBehaviorGoogleMail", @"RegionalBehaviorNTSC", @"RegionalBehaviorNoPasscodeLocationTiles", @"RegionalBehaviorNoVOIP", @"RegionalBehaviorNoWiFi", @"RegionalBehaviorShutterClick", @"RegionalBehaviorVolumeLimit"],@[@"ActiveWirelessTechnology", @"WifiAddress", @"WifiAddressData", @"WifiVendor"],@[@"FaceTimeBitRate2G", @"FaceTimeBitRate3G", @"FaceTimeBitRateLTE", @"FaceTimeBitRateWiFi", @"FaceTimeDecodings", @"FaceTimeEncodings", @"FaceTimePreferredDecoding", @"FaceTimePreferredEncoding"],@[@"DeviceSupportsFaceTime", @"DeviceSupportsTethering", @"DeviceSupportsSimplisticRoadMesh", @"DeviceSupportsNavigation", @"DeviceSupportsLineIn", @"DeviceSupports9Pin", @"DeviceSupports720p", @"DeviceSupports4G", @"DeviceSupports3DMaps", @"DeviceSupports3DImagery", @"DeviceSupports1080p"]]; 23 | } 24 | 25 | -(void)back { 26 | [self dismissViewControllerAnimated:YES completion:nil]; 27 | } 28 | 29 | -(void)addKeysToModify { 30 | [objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kAdd inKey:@"keysChosen" withValue:selectedItems]; 31 | [self back]; 32 | } 33 | 34 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 35 | return 9; 36 | } 37 | 38 | -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 39 | switch (section) { 40 | case 0: 41 | return @"Identifying Information"; 42 | case 1: 43 | return @"Bluetooth Information"; 44 | case 2: 45 | return @"Battery Information"; 46 | case 3: 47 | return @"Baseband Information"; 48 | case 4: 49 | return @"Telephony Information"; 50 | case 5: 51 | return @"Device Information"; 52 | case 6: 53 | return @"Capability Information"; 54 | case 7: 55 | return @"Regional Behaviour"; 56 | case 8: 57 | return @"Wireless Information"; 58 | case 9: 59 | return @"FaceTime Information"; 60 | default: 61 | return @"Other"; 62 | } 63 | } 64 | 65 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 66 | return allKeys[section].count; 67 | } 68 | 69 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 70 | NSString *cellIdentifier = [NSString stringWithFormat:@"ChoicePickerCellS%ldR%ld", (long)indexPath.section, (long)indexPath.row]; 71 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 72 | 73 | if (!cell) { 74 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; 75 | } 76 | 77 | NSString *mgKey = allKeys[indexPath.section][indexPath.row]; 78 | 79 | // hide cell (we return before adding anything + give it a height of 0 in other method so not visible) 80 | if ([objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kExists inKey:@"keysChosen" withValue:mgKey]) { 81 | return cell; 82 | } 83 | 84 | cell.textLabel.text = mgKey; 85 | id mgValueResponse = (__bridge id)MGCopyAnswer((__bridge CFStringRef)mgKey); 86 | cell.detailTextLabel.text = [mgValueResponse description] ?: nil; 87 | 88 | return cell; 89 | } 90 | 91 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 92 | // hide cell 93 | if ([objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kExists inKey:@"keysChosen" withValue:allKeys[indexPath.section][indexPath.row]]) { 94 | return 0; 95 | } 96 | return tableView.rowHeight; 97 | } 98 | 99 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 100 | if (!selectedItems) 101 | selectedItems = [NSMutableArray array]; 102 | 103 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 104 | 105 | UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 106 | NSString *cellValue = cell.textLabel.text; 107 | 108 | if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { 109 | // Deselect case 110 | cell.accessoryType = UITableViewCellAccessoryNone; 111 | // remove from selectedItems arrays if needed 112 | if ([selectedItems containsObject:cellValue]) 113 | [selectedItems removeObject:cellValue]; 114 | // toggle "Add" button if needed 115 | if (selectedItems.count <= 0) 116 | self.navigationItem.rightBarButtonItem.enabled = NO; 117 | } else { 118 | // Select case 119 | cell.accessoryType = UITableViewCellAccessoryCheckmark; 120 | // add to selectedItems arrays if needed 121 | if (![selectedItems containsObject:cellValue]) 122 | [selectedItems addObject:cellValue]; 123 | // toggle "Add" button if needed 124 | if (selectedItems.count > 0) 125 | self.navigationItem.rightBarButtonItem.enabled = YES; 126 | } 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperAppDelegate.h: -------------------------------------------------------------------------------- 1 | @interface MGSpoofHelperAppDelegate : UIResponder 2 | 3 | @property (nonatomic, retain) UIWindow *window; 4 | @property (nonatomic, retain) UINavigationController *rootViewController; 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "MGSpoofHelperAppDelegate.h" 2 | #import "MGSpoofHelperRootViewController.h" 3 | 4 | @implementation MGSpoofHelperAppDelegate 5 | 6 | -(void)applicationDidFinishLaunching:(UIApplication *)application { 7 | _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 8 | _rootViewController = [[UINavigationController alloc] initWithRootViewController:[[MGSpoofHelperRootViewController alloc] init]]; 9 | _window.rootViewController = _rootViewController; 10 | [_window makeKeyAndVisible]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperPrefs.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef enum { 4 | kAdd, 5 | kRemove, 6 | kExists 7 | } prefActions; 8 | 9 | @interface MGSpoofHelperPrefs : NSObject 10 | +(BOOL)handleAppPrefsWithAction:(int)action inKey:(NSString *)key withValue:(id)value; 11 | +(id)retrieveObjectFromKey:(NSString *)key; 12 | +(void)addToKey:(NSString *)key withValue:(id)value inDictKey:(NSString *)dictKey; 13 | +(void)removeKey:(NSString *)key inDictKey:(NSString *)dictKey; 14 | @end -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperPrefs.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "MGSpoofHelperPrefs.h" 3 | 4 | @implementation MGSpoofHelperPrefs 5 | 6 | +(BOOL)handleAppPrefsWithAction:(int)action inKey:(NSString *)key withValue:(id)value { 7 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 8 | NSArray *oldArray = (NSArray *)[userDefaults objectForKey:key]; 9 | // if there is no array make it 10 | if (!oldArray) { 11 | [userDefaults setValue:@[] forKey:key]; 12 | oldArray = @[]; 13 | } 14 | NSMutableArray *tempArray = oldArray.mutableCopy; 15 | // add or remove item from remove and update array in userDefaults depending on action 16 | switch (action) { 17 | case kAdd: 18 | if ([value isKindOfClass:[NSString class]]) { 19 | if (value && ![tempArray containsObject:value]) 20 | [tempArray addObject:value]; 21 | } else if (value && [value isKindOfClass:[NSArray class]]) { 22 | tempArray = [tempArray arrayByAddingObjectsFromArray:value].mutableCopy; 23 | } 24 | break; 25 | case kRemove: 26 | if (value && [tempArray containsObject:value]) 27 | [tempArray removeObject:value]; 28 | break; 29 | case kExists: 30 | return [tempArray containsObject:value]; 31 | } 32 | // update the array in userDefaults 33 | [userDefaults setValue:tempArray forKey:key]; 34 | notify_post("com.tonyk7.mgspoof/appsChosenUpdated"); 35 | return 0; 36 | } 37 | 38 | +(void)addToKey:(NSString *)key withValue:(id)value inDictKey:(NSString *)dictKey { 39 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 40 | NSMutableDictionary *newDict = ((NSDictionary *)[userDefaults objectForKey:dictKey]).mutableCopy; 41 | if (!newDict) { 42 | [userDefaults setValue:@{} forKey:dictKey]; 43 | newDict = @{}.mutableCopy; 44 | } 45 | newDict[key] = value; 46 | [userDefaults setValue:newDict forKey:dictKey]; 47 | notify_post("com.tonyk7.mgspoof/modifiedKeyUpdated"); 48 | } 49 | 50 | +(void)removeKey:(NSString *)key inDictKey:(NSString *)dictKey { 51 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 52 | NSMutableDictionary *newDict = ((NSDictionary *)[userDefaults objectForKey:dictKey]).mutableCopy; 53 | [newDict removeObjectForKey:key]; 54 | [userDefaults setValue:newDict forKey:dictKey]; 55 | notify_post("com.tonyk7.mgspoof/modifiedKeyUpdated"); 56 | } 57 | 58 | +(id)retrieveObjectFromKey:(NSString *)key { 59 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.tonyk7.MGSpoofHelperPrefsSuite"]; 60 | return [userDefaults objectForKey:key]; 61 | } 62 | 63 | @end -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperRootViewController.h: -------------------------------------------------------------------------------- 1 | @interface MGSpoofHelperRootViewController : UITableViewController { 2 | NSMutableArray *mgKeysToModify; 3 | } 4 | @end 5 | -------------------------------------------------------------------------------- /mgspoofhelper/MGSpoofHelperRootViewController.m: -------------------------------------------------------------------------------- 1 | #import "MGSpoofHelperRootViewController.h" 2 | #import "MGSpoofHelperAppDelegate.h" 3 | #import "MGSpoofHelperPrefs.h" 4 | #import "MGKeyPickerController.h" 5 | #import "MGAppPickerController.h" 6 | 7 | CFPropertyListRef MGCopyAnswer(CFStringRef); 8 | 9 | #define mgValue(key) (__bridge NSString *)MGCopyAnswer((__bridge CFStringRef)key) 10 | #define CGRectSetWidth(rect, width) CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height); 11 | #define CGRectSetXY(rect, x, y) CGRectMake(x, y, rect.size.width, rect.size.height) 12 | #define kMgValueLabelTag 787878 // "xxx" in hex :) 13 | #define kMgValueLabelInset 5 14 | 15 | @implementation MGSpoofHelperRootViewController 16 | 17 | -(void)loadView { 18 | [super loadView]; 19 | 20 | [self updateKeysArray]; 21 | self.tableView.delegate = self; 22 | self.tableView.dataSource = self; 23 | 24 | self.title = @"MGSpoofer"; 25 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addKeys)]; 26 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Apps" style:UIBarButtonItemStyleDone target:self action:@selector(selectApps)]; 27 | 28 | [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 29 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRoated) name:UIDeviceOrientationDidChangeNotification object:nil]; 30 | } 31 | 32 | -(void)deviceRoated { 33 | [self.tableView reloadData]; 34 | } 35 | 36 | -(void)updateKeysArray { 37 | mgKeysToModify = ((NSArray *)[objc_getClass("MGSpoofHelperPrefs") retrieveObjectFromKey:@"keysChosen"]).mutableCopy; 38 | } 39 | 40 | -(void)selectApps { 41 | MGAppPickerController *appPicker = [[MGAppPickerController alloc] init]; 42 | UINavigationController *navAppPicker = [[UINavigationController alloc] initWithRootViewController:appPicker]; 43 | [self presentViewController:navAppPicker animated:YES completion:nil]; 44 | } 45 | 46 | -(void)addKeys { 47 | MGKeyPickerController *keyPicker = [[MGKeyPickerController alloc] init]; 48 | UINavigationController *navKeyPicker = [[UINavigationController alloc] initWithRootViewController:keyPicker]; 49 | [self presentViewController:navKeyPicker animated:YES completion:nil]; 50 | } 51 | 52 | -(void)viewWillAppear:(BOOL)animated { 53 | [super viewWillAppear:animated]; 54 | [self updateKeysArray]; 55 | [self.tableView reloadData]; 56 | } 57 | 58 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 59 | if ([mgKeysToModify count] > 0) { 60 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; 61 | self.tableView.backgroundView = nil; 62 | return 1; 63 | } 64 | else { 65 | UILabel *noKeysChosenLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)]; 66 | noKeysChosenLabel.text = @"Choose key(s) to modify"; 67 | noKeysChosenLabel.textColor = [UIColor blackColor]; 68 | noKeysChosenLabel.textAlignment = NSTextAlignmentCenter; 69 | self.tableView.backgroundView = noKeysChosenLabel; 70 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 71 | return 0; 72 | } 73 | } 74 | 75 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 76 | return mgKeysToModify.count; 77 | } 78 | 79 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 80 | return 60; 81 | } 82 | 83 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 84 | NSString *cellIdentifier = [NSString stringWithFormat:@"ModifyPickerCellR%ld", (long)indexPath.row]; 85 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 86 | if (!cell) { 87 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; 88 | } 89 | 90 | NSString *mgKey = mgKeysToModify[indexPath.row]; 91 | cell.textLabel.text = mgKey; 92 | NSDictionary *modifiedKeys = [objc_getClass("MGSpoofHelperPrefs") retrieveObjectFromKey:@"modifiedKeys"]; 93 | 94 | // if we have a modified one in prefs, display that value of default one 95 | id value = modifiedKeys[mgKey] ?: mgValue(mgKey); 96 | NSString *valueString = [value description] ?: nil; 97 | 98 | if (valueString) { 99 | UILabel *mgValueLabel; 100 | if (![cell viewWithTag:kMgValueLabelTag]) { 101 | mgValueLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 102 | mgValueLabel.tag = kMgValueLabelTag; 103 | } else 104 | mgValueLabel = (UILabel *)[cell viewWithTag:kMgValueLabelTag]; 105 | 106 | mgValueLabel.text = valueString; 107 | [mgValueLabel sizeToFit]; 108 | CGFloat cellWidth = [UIScreen mainScreen].bounds.size.width; 109 | if (mgValueLabel.bounds.size.width >= cellWidth/2) { 110 | // change width of label to two thirds of a cell 111 | mgValueLabel.frame = CGRectSetWidth(mgValueLabel.frame, cellWidth*2/3); 112 | mgValueLabel.adjustsFontSizeToFitWidth = YES; 113 | } 114 | CGFloat x = cellWidth - mgValueLabel.bounds.size.width - kMgValueLabelInset; 115 | CGFloat y = tableView.rowHeight + mgValueLabel.bounds.size.height*2 - kMgValueLabelInset; 116 | mgValueLabel.frame = CGRectSetXY(mgValueLabel.frame, x, y); 117 | [cell addSubview:mgValueLabel]; 118 | } 119 | return cell; 120 | } 121 | 122 | -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 123 | [objc_getClass("MGSpoofHelperPrefs") handleAppPrefsWithAction:kRemove inKey:@"keysChosen" withValue:mgKeysToModify[indexPath.row]]; 124 | [objc_getClass("MGSpoofHelperPrefs") removeKey:mgKeysToModify[indexPath.row] inDictKey:@"modifiedKeys"]; 125 | [mgKeysToModify removeObjectAtIndex:indexPath.row]; 126 | if ([tableView numberOfRowsInSection:[indexPath section]] == 1) 127 | [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade]; 128 | else 129 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 130 | } 131 | 132 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 133 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 134 | NSString *mgKey = mgKeysToModify[indexPath.row]; 135 | 136 | UIAlertController *setValueAlertController = [UIAlertController alertControllerWithTitle:mgKey message:[NSString stringWithFormat:@"Original value: %@", mgValue(mgKey)] preferredStyle:UIAlertControllerStyleAlert]; 137 | [setValueAlertController addTextFieldWithConfigurationHandler:^(UITextField *_Nonnull textField) { 138 | textField.placeholder = @"New value"; 139 | BOOL shouldUseNumbePad = [mgValue(mgKey) isKindOfClass:[NSNumber class]]; 140 | if (shouldUseNumbePad) 141 | textField.keyboardType = UIKeyboardTypeNumberPad; 142 | [textField addTarget:self action:@selector(userEditedTextfield:) forControlEvents:UIControlEventEditingChanged]; 143 | }]; 144 | UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"Confirm" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 145 | NSNumber *numberForm; 146 | NSString *textInput = [setValueAlertController textFields][0].text; 147 | if ([textInput isKindOfClass:[NSNumber class]]) 148 | numberForm = @([textInput integerValue]); 149 | [objc_getClass("MGSpoofHelperPrefs") addToKey:mgKey withValue:(numberForm ?: textInput) inDictKey:@"modifiedKeys"]; 150 | [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 151 | }]; 152 | UIAlertAction *randomizeAction = [UIAlertAction actionWithTitle:@"Randomize" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 153 | int lengthNeeded = [mgValue(mgKey) description].length; 154 | if ([mgValue(mgKey) isKindOfClass:[NSNumber class]]) { 155 | // randomize number 156 | NSMutableString *randomNumberString = [NSMutableString stringWithCapacity:lengthNeeded]; 157 | // make sure first number not 0 158 | [randomNumberString appendString:@(arc4random_uniform(9)+1).stringValue]; 159 | for (int idx = 1; idx < lengthNeeded; idx++) { 160 | [randomNumberString appendString:@(arc4random_uniform(10)).stringValue]; 161 | } 162 | [objc_getClass("MGSpoofHelperPrefs") addToKey:mgKey withValue:@(randomNumberString.longLongValue) inDictKey:@"modifiedKeys"]; 163 | } 164 | else { 165 | // generates random string following same format as original (cap sensitive, numbers where they need to be, etc..) 166 | NSMutableString *randomString = [NSMutableString stringWithCapacity:lengthNeeded]; 167 | NSString *value = [mgValue(mgKey) description]; 168 | for (int idx = 0; idx < lengthNeeded; idx++) { 169 | unichar character = [value characterAtIndex:idx]; 170 | // for mac address 171 | if (character == 58) { // 58 = ":" 172 | [randomString appendString:@":"]; 173 | continue; 174 | } 175 | if (isdigit(character)) 176 | [randomString appendString:@(arc4random_uniform(10)).stringValue]; 177 | else { 178 | if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:character]) 179 | [randomString appendFormat:@"%c", (unichar)('A' + arc4random_uniform(26))]; 180 | else 181 | [randomString appendFormat:@"%c", (unichar)('a' + arc4random_uniform(26))]; 182 | } 183 | } 184 | [objc_getClass("MGSpoofHelperPrefs") addToKey:mgKey withValue:randomString inDictKey:@"modifiedKeys"]; 185 | } 186 | [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 187 | }]; 188 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; 189 | confirmAction.enabled = NO; 190 | [setValueAlertController addAction:randomizeAction]; 191 | [setValueAlertController addAction:confirmAction]; 192 | [setValueAlertController addAction:cancelAction]; 193 | [self presentViewController:setValueAlertController animated:YES completion:nil]; 194 | } 195 | 196 | -(void)userEditedTextfield:(UITextField *)textField { 197 | UIAlertController *setValueAlertController = (UIAlertController *)self.presentedViewController; 198 | BOOL hasValue = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length > 0; 199 | if (setValueAlertController) { 200 | UIAlertAction *okAction = setValueAlertController.actions[1]; // confirm button 201 | okAction.enabled = hasValue; 202 | } 203 | } 204 | 205 | @end 206 | -------------------------------------------------------------------------------- /mgspoofhelper/Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | APPLICATION_NAME = MGSpoofHelper 4 | MGSpoofHelper_FILES = $(wildcard *.m) 5 | MGSpoofHelper_FRAMEWORKS = UIKit CoreGraphics 6 | MGSpoofHelper_LIBRARIES = MobileGestalt 7 | MGSpoofHelper_CFLAGS = -fobjc-arc 8 | MGSpoofHelper_CODESIGN_FLAGS = -Sent.xml 9 | 10 | include $(THEOS_MAKE_PATH)/application.mk 11 | 12 | after-install:: 13 | install.exec "killall \"MGSpoofHelper\"" || true 14 | -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon29x29.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon29x29@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon29x29@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon40x40.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon40x40@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon40x40@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon50x50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon50x50.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon50x50@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon57x57.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon57x57@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon57x57@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon57x57@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon60x60.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon60x60@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon60x60@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon72x72.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon72x72@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon76x76.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/AppIcon76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/AppIcon76x76@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | MGSpoofHelper 7 | CFBundleIcons 8 | 9 | CFBundlePrimaryIcon 10 | 11 | CFBundleIconFiles 12 | 13 | AppIcon29x29 14 | AppIcon40x40 15 | AppIcon57x57 16 | AppIcon60x60 17 | 18 | UIPrerenderedIcon 19 | 20 | 21 | 22 | CFBundleIcons~ipad 23 | 24 | CFBundlePrimaryIcon 25 | 26 | CFBundleIconFiles 27 | 28 | AppIcon29x29 29 | AppIcon40x40 30 | AppIcon57x57 31 | AppIcon60x60 32 | AppIcon50x50 33 | AppIcon72x72 34 | AppIcon76x76 35 | 36 | UIPrerenderedIcon 37 | 38 | 39 | 40 | CFBundleIdentifier 41 | com.tonyk7.mgspoofhelper 42 | CFBundleInfoDictionaryVersion 43 | 6.0 44 | CFBundlePackageType 45 | APPL 46 | CFBundleSignature 47 | ???? 48 | CFBundleSupportedPlatforms 49 | 50 | iPhoneOS 51 | 52 | CFBundleVersion 53 | 1.0 54 | LSRequiresIPhoneOS 55 | 56 | UIDeviceFamily 57 | 58 | 1 59 | 2 60 | 61 | UIRequiredDeviceCapabilities 62 | 63 | armv7 64 | 65 | UILaunchImageFile 66 | LaunchImage 67 | UILaunchImages 68 | 69 | 70 | UILaunchImageMinimumOSVersion 71 | 7.0 72 | UILaunchImageName 73 | LaunchImage 74 | UILaunchImageOrientation 75 | Portrait 76 | UILaunchImageSize 77 | {320, 480} 78 | 79 | 80 | UILaunchImageMinimumOSVersion 81 | 7.0 82 | UILaunchImageName 83 | LaunchImage-700-568h 84 | UILaunchImageOrientation 85 | Portrait 86 | UILaunchImageSize 87 | {320, 568} 88 | 89 | 90 | UILaunchImageMinimumOSVersion 91 | 7.0 92 | UILaunchImageName 93 | LaunchImage-Portrait 94 | UILaunchImageOrientation 95 | Portrait 96 | UILaunchImageSize 97 | {768, 1024} 98 | 99 | 100 | UILaunchImageMinimumOSVersion 101 | 7.0 102 | UILaunchImageName 103 | LaunchImage-Landscape 104 | UILaunchImageOrientation 105 | Landscape 106 | UILaunchImageSize 107 | {768, 1024} 108 | 109 | 110 | UILaunchImageMinimumOSVersion 111 | 8.0 112 | UILaunchImageName 113 | LaunchImage-800-667h 114 | UILaunchImageOrientation 115 | Portrait 116 | UILaunchImageSize 117 | {375, 667} 118 | 119 | 120 | UILaunchImageMinimumOSVersion 121 | 8.0 122 | UILaunchImageName 123 | LaunchImage-800-Portrait-736h 124 | UILaunchImageOrientation 125 | Portrait 126 | UILaunchImageSize 127 | {414, 736} 128 | 129 | 130 | UILaunchImageMinimumOSVersion 131 | 8.0 132 | UILaunchImageName 133 | LaunchImage-800-Landscape-736h 134 | UILaunchImageOrientation 135 | Landscape 136 | UILaunchImageSize 137 | {414, 736} 138 | 139 | 140 | UISupportedInterfaceOrientations 141 | 142 | UIInterfaceOrientationPortrait 143 | UIInterfaceOrientationLandscapeLeft 144 | UIInterfaceOrientationLandscapeRight 145 | 146 | UISupportedInterfaceOrientations~ipad 147 | 148 | UIInterfaceOrientationPortrait 149 | UIInterfaceOrientationPortraitUpsideDown 150 | UIInterfaceOrientationLandscapeLeft 151 | UIInterfaceOrientationLandscapeRight 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-700-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-700-568h@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-700-Landscape@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-700-Landscape@2x~ipad.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-700-Landscape~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-700-Landscape~ipad.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-700-Portrait@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-700-Portrait@2x~ipad.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-700-Portrait~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-700-Portrait~ipad.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-800-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-800-667h@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-800-Landscape-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-800-Landscape-736h@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage-800-Portrait-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage-800-Portrait-736h@3x.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage.png -------------------------------------------------------------------------------- /mgspoofhelper/Resources/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tonyk7/MGSpoof/b9b62efc72ef4d3865950893be770860a6b68d80/mgspoofhelper/Resources/LaunchImage@2x.png -------------------------------------------------------------------------------- /mgspoofhelper/ent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.private.security.no-container 6 | 7 | com.apple.private.skip-library-validation 8 | 9 | platform-application 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /mgspoofhelper/main.m: -------------------------------------------------------------------------------- 1 | #import "MGSpoofHelperAppDelegate.h" 2 | 3 | int main(int argc, char *argv[]) { 4 | @autoreleasepool { 5 | return UIApplicationMain(argc, argv, nil, NSStringFromClass(MGSpoofHelperAppDelegate.class)); 6 | } 7 | } 8 | --------------------------------------------------------------------------------