├── .gitattributes ├── .gitignore ├── Bootstrap.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcuserdata │ │ └── admin.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── admin.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Bootstrap ├── AppDelegate.h ├── AppDelegate.m ├── AppEnabler.m ├── AppList.h ├── AppList.m ├── AppViewController.h ├── AppViewController.m ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon-1024.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-38@2x.png │ │ ├── icon-38@3x.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-64@2x.png │ │ ├── icon-64@3x.png │ │ ├── icon-68@2x.png │ │ ├── icon-76@2x.png │ │ └── icon-83.5@2x.png │ ├── AppIcon.appiconset1 │ │ ├── Contents.json │ │ ├── icon-1024.png │ │ ├── icon-20@2x.png │ │ ├── icon-20@3x.png │ │ ├── icon-29@2x.png │ │ ├── icon-29@3x.png │ │ ├── icon-38@2x.png │ │ ├── icon-38@3x.png │ │ ├── icon-40@2x.png │ │ ├── icon-40@3x.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-64@2x.png │ │ ├── icon-64@3x.png │ │ ├── icon-68@2x.png │ │ ├── icon-76@2x.png │ │ └── icon-83.5@2x.png │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Frameworks │ └── MobileContainerManager.framework │ │ └── MobileContainerManager.tbd ├── Info.plist ├── LICENSE ├── MBProgressHUD.framework │ ├── Headers │ │ └── MBProgressHUD.h │ ├── Info.plist │ ├── MBProgressHUD │ └── Modules │ │ └── module.modulemap ├── NSUserDefaults+appDefaults.h ├── NSUserDefaults+appDefaults.m ├── SceneDelegate.h ├── SceneDelegate.m ├── ViewController.h ├── ViewController.m ├── basebin │ ├── bootstrap.dylib │ ├── bootstrap.entitlements │ ├── bootstrapd │ ├── devtest │ ├── entitlements │ │ ├── com.apple.mobilesafari.extra │ │ ├── com.apple.mobilesafari.strip │ │ ├── com.apple.mobileslideshow.extra │ │ └── com.apple.mobileslideshow.photo-picker.extra │ ├── fastPathSign │ ├── ldid │ ├── nickchan.entitlements │ ├── preload │ ├── preload.dylib │ ├── rebuildapp │ ├── rebuildapps.sh │ ├── test.sh │ └── uicache ├── bootstrap.h ├── bootstrap.m ├── common.h ├── credits.h ├── envbuf.c ├── envbuf.h ├── main.m ├── seh.h ├── sources.h ├── syslog.h ├── utils.h ├── utils.m └── zstd_wrapper.m ├── LICENSE ├── Makefile ├── README.md ├── control ├── entitlements.plist ├── libkrw0-dummy.deb ├── sileo.deb ├── strapfiles ├── bootstrap-1800.tar.zst ├── bootstrap-1900.tar.zst └── bootstrap-2000.tar.zst ├── suid.rtf ├── tar └── zebra.deb /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/ 2 | packages/ 3 | .DS_Store 4 | /basebin/ 5 | /layout/ 6 | *.xcuserstate 7 | Bootstrap.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate 8 | Bootstrap.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate 9 | *.xcuserstate 10 | -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "zstd", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/facebook/zstd.git", 7 | "state" : { 8 | "branch" : "dev", 9 | "revision" : "126ec2669c927b24acd38ea903a211c1b5416588" 10 | } 11 | } 12 | ], 13 | "version" : 2 14 | } 15 | -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Bootstrap.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Bootstrap.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Bootstrap/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef APPDELEGATE_H 2 | #define APPDELEGATE_H 3 | 4 | #import 5 | 6 | @interface AppDelegate : UIResponder 7 | 8 | +(void)showHudMsg:(NSString*)msg; 9 | +(void)showHudMsg:(NSString*)msg detail:(NSString*)info; 10 | +(void)dismissHud; 11 | 12 | + (void)showAlert:(UIAlertController*)alert; 13 | + (void)showMesage:(NSString*)msg title:(NSString*)title; 14 | 15 | + (void)addLogText:(NSString*)text; 16 | + (void)registerLogView:(UITextView*)view; 17 | 18 | @end 19 | 20 | #endif //APPDELEGATE_H 21 | -------------------------------------------------------------------------------- /Bootstrap/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #include "common.h" 3 | 4 | #include 5 | 6 | @interface AppDelegate () 7 | @end 8 | 9 | @implementation AppDelegate 10 | 11 | UITextView* logView=nil; 12 | 13 | + (void)registerLogView:(UITextView*)view 14 | { 15 | dispatch_async(dispatch_get_main_queue(), ^{ 16 | logView = view; 17 | logView.layoutManager.allowsNonContiguousLayout = NO; 18 | }); 19 | } 20 | 21 | + (void)addLogText:(NSString*)text 22 | { 23 | dispatch_async(dispatch_get_main_queue(), ^{ 24 | [logView setText:[logView.text stringByAppendingString:[NSString stringWithFormat:@"%@\n",text]]]; 25 | if(logView.contentSize.height >= logView.bounds.size.height) 26 | [logView setContentOffset:CGPointMake(0, logView.contentSize.height - logView.bounds.size.height) animated:YES]; 27 | }); 28 | } 29 | 30 | MBProgressHUD *switchHud=nil; 31 | 32 | +(void)showHudMsg:(NSString*)msg 33 | { 34 | dispatch_async(dispatch_get_main_queue(), ^{ 35 | switchHud = [MBProgressHUD showHUDAddedTo:UIApplication.sharedApplication.keyWindow animated:YES]; 36 | [switchHud showAnimated:YES]; 37 | switchHud.label.text = msg; 38 | }); 39 | } 40 | 41 | +(void)showHudMsg:(NSString*)msg detail:(NSString*)info 42 | { 43 | dispatch_async(dispatch_get_main_queue(), ^{ 44 | switchHud = [MBProgressHUD showHUDAddedTo:UIApplication.sharedApplication.keyWindow animated:YES]; 45 | [switchHud showAnimated:YES]; 46 | switchHud.label.text = msg; 47 | switchHud.detailsLabel.text = info; 48 | }); 49 | } 50 | 51 | +(void)dismissHud { 52 | dispatch_async(dispatch_get_main_queue(), ^{ 53 | [switchHud hideAnimated:YES]; 54 | }); 55 | } 56 | 57 | + (void)showAlert:(UIAlertController*)alert { 58 | 59 | static dispatch_queue_t alertQueue = nil; 60 | 61 | static dispatch_once_t oncetoken; 62 | dispatch_once(&oncetoken, ^{ 63 | alertQueue = dispatch_queue_create("alertQueue", DISPATCH_QUEUE_SERIAL); 64 | }); 65 | 66 | dispatch_async(alertQueue, ^{ 67 | __block BOOL presented = NO; 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | UIViewController* vc = UIApplication.sharedApplication.keyWindow.rootViewController; 70 | while(vc.presentedViewController) vc = vc.presentedViewController; 71 | [vc presentViewController:alert animated:YES completion:^{ presented=YES; }]; 72 | }); 73 | 74 | while(!presented) usleep(100*1000); 75 | }); 76 | } 77 | 78 | + (void)showMesage:(NSString*)msg title:(NSString*)title { 79 | 80 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert]; 81 | [alert addAction:[UIAlertAction actionWithTitle:Localized(@"OK") style:UIAlertActionStyleDefault handler:nil]]; 82 | [self showAlert:alert]; 83 | } 84 | 85 | 86 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 87 | // Override point for customization after application launch. 88 | return YES; 89 | } 90 | 91 | 92 | #pragma mark - UISceneSession lifecycle 93 | 94 | 95 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 96 | // Called when a new scene session is being created. 97 | // Use this method to select a configuration to create the new scene with. 98 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 99 | } 100 | 101 | 102 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 103 | // Called when the user discards a scene session. 104 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 105 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 106 | } 107 | 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /Bootstrap/AppEnabler.m: -------------------------------------------------------------------------------- 1 | #import 2 | #include "AppList.h" 3 | #include "common.h" 4 | 5 | NSString * relativize(NSURL * to, NSURL * from, BOOL fromIsDir) { 6 | NSString * toString = [[to path] stringByStandardizingPath]; 7 | NSMutableArray * toPieces = [NSMutableArray arrayWithArray:[toString pathComponents]]; 8 | 9 | NSString * fromString = [[from path] stringByStandardizingPath]; 10 | NSMutableArray * fromPieces = [NSMutableArray arrayWithArray:[fromString pathComponents]]; 11 | 12 | NSMutableString * relPath = [NSMutableString string]; 13 | 14 | NSString * toTrimmed = toString; 15 | NSString * toPiece = NULL; 16 | NSString * fromTrimmed = fromString; 17 | NSString * fromPiece = NULL; 18 | 19 | NSMutableArray * parents = [NSMutableArray array]; 20 | NSMutableArray * pieces = [NSMutableArray array]; 21 | 22 | if(toPieces.count >= fromPieces.count) { 23 | NSUInteger toCount = toPieces.count; 24 | while(toCount > fromPieces.count) { 25 | toPiece = [toTrimmed lastPathComponent]; 26 | toTrimmed = [toTrimmed stringByDeletingLastPathComponent]; 27 | [pieces insertObject:toPiece atIndex:0]; 28 | toCount--; 29 | } 30 | 31 | while(![fromTrimmed isEqualToString:toTrimmed]) { 32 | toPiece = [toTrimmed lastPathComponent]; 33 | toTrimmed = [toTrimmed stringByDeletingLastPathComponent]; 34 | fromPiece = [fromTrimmed lastPathComponent]; 35 | fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent]; 36 | if(![toPiece isEqualToString:fromPiece]) { 37 | if(![fromPiece isEqualToString:[fromPiece lastPathComponent]] || fromIsDir) { 38 | [parents addObject:@".."]; 39 | } 40 | [pieces insertObject:toPiece atIndex:0]; 41 | } 42 | } 43 | 44 | } else { 45 | NSUInteger fromCount = fromPieces.count; 46 | 47 | while(fromCount > toPieces.count) { 48 | fromPiece = [fromTrimmed lastPathComponent]; 49 | fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent]; 50 | if(![fromPiece isEqualToString:[fromString lastPathComponent]] || fromIsDir) { 51 | [parents addObject:@".."]; 52 | } 53 | fromCount--; 54 | } 55 | 56 | while(![toTrimmed isEqualToString:fromTrimmed]) { 57 | toPiece = [toTrimmed lastPathComponent]; 58 | toTrimmed = [toTrimmed stringByDeletingLastPathComponent]; 59 | fromPiece = [fromTrimmed lastPathComponent]; 60 | fromTrimmed = [fromTrimmed stringByDeletingLastPathComponent]; 61 | [parents addObject:@".."]; 62 | [pieces insertObject:toPiece atIndex:0]; 63 | } 64 | 65 | } 66 | 67 | [relPath appendString:[parents componentsJoinedByString:@"/"]]; 68 | if(parents.count > 0) [relPath appendString:@"/"]; 69 | else [relPath appendString:@"./"]; 70 | [relPath appendString:[pieces componentsJoinedByString:@"/"]]; 71 | 72 | return relPath; 73 | } 74 | 75 | NSArray* appBackupFileNames = @[ 76 | @"Info.plist", 77 | @"_CodeSignature", 78 | @"SC_Info", 79 | ]; 80 | 81 | //will skip empty dir 82 | int backupApp(NSString* bundlePath) 83 | { 84 | NSFileManager* fm = NSFileManager.defaultManager; 85 | 86 | NSString* backup = [bundlePath stringByAppendingPathExtension:@"appbackup"]; 87 | 88 | if([fm fileExistsAtPath:backup]) { 89 | ASSERT(![fm fileExistsAtPath:[backup.stringByDeletingLastPathComponent stringByAppendingPathComponent:@".appbackup"]]); 90 | ASSERT([fm removeItemAtPath:backup error:nil]); 91 | } 92 | 93 | NSString *resolvedPath = [[bundlePath stringByResolvingSymlinksInPath] stringByStandardizingPath]; 94 | NSDirectoryEnumerator *directoryEnumerator = [fm enumeratorAtURL:[NSURL fileURLWithPath:resolvedPath isDirectory:YES] includingPropertiesForKeys:@[NSURLIsRegularFileKey] options:0 errorHandler:nil]; 95 | 96 | int backupFileCount=0; 97 | for (NSURL *enumURL in directoryEnumerator) { @autoreleasepool { 98 | NSNumber *isFile=nil; 99 | ASSERT([enumURL getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil] && isFile!=nil); 100 | if (![isFile boolValue]) continue; 101 | 102 | FILE *fp = fopen(enumURL.fileSystemRepresentation, "rb"); 103 | ASSERT(fp != NULL); 104 | 105 | bool ismacho=false, islib=false; 106 | machoGetInfo(fp, &ismacho, &islib); 107 | 108 | fclose(fp); 109 | 110 | //bundlePath should be a real-path 111 | NSString* subPath = relativize(enumURL, [NSURL fileURLWithPath:bundlePath], YES); 112 | NSString* backupPath = [backup stringByAppendingPathComponent:subPath]; 113 | 114 | if(![fm fileExistsAtPath:backupPath.stringByDeletingLastPathComponent]) 115 | ASSERT([fm createDirectoryAtPath:backupPath.stringByDeletingLastPathComponent withIntermediateDirectories:YES attributes:nil error:nil]); 116 | 117 | if(ismacho || [appBackupFileNames containsObject:enumURL.path.lastPathComponent]) 118 | { 119 | NSError* err=nil; 120 | ASSERT([fm copyItemAtPath:enumURL.path toPath:backupPath error:&err]); 121 | SYSLOG("copied %@ => %@", enumURL.path, backupPath); 122 | 123 | backupFileCount++; 124 | } 125 | else { 126 | ASSERT(link(enumURL.path.UTF8String, backupPath.UTF8String)==0); 127 | } 128 | 129 | } } 130 | 131 | ASSERT(backupFileCount > 0); 132 | 133 | ASSERT([[NSString new] writeToFile:[backup.stringByDeletingLastPathComponent stringByAppendingPathComponent:@".appbackup"] atomically:YES encoding:NSUTF8StringEncoding error:nil]); 134 | 135 | return 0; 136 | } 137 | 138 | int restoreApp(NSString* bundlePath) 139 | { 140 | SYSLOG("restoreApp=%@", bundlePath); 141 | NSFileManager* fm = NSFileManager.defaultManager; 142 | 143 | NSString* backup = [bundlePath stringByAppendingPathExtension:@"appbackup"]; 144 | 145 | ASSERT([fm fileExistsAtPath:backup]); 146 | ASSERT([fm fileExistsAtPath:[backup.stringByDeletingLastPathComponent stringByAppendingPathComponent:@".appbackup"]]); 147 | 148 | NSString *resolvedPath = [[backup stringByResolvingSymlinksInPath] stringByStandardizingPath]; 149 | NSDirectoryEnumerator *directoryEnumerator = [fm enumeratorAtURL:[NSURL fileURLWithPath:resolvedPath isDirectory:YES] includingPropertiesForKeys:@[NSURLIsRegularFileKey] options:0 errorHandler:nil]; 150 | 151 | int restoreFileCount=0; 152 | for (NSURL *enumURL in directoryEnumerator) { @autoreleasepool { 153 | NSNumber *isFile=nil; 154 | ASSERT([enumURL getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil] && isFile!=nil); 155 | if (![isFile boolValue]) continue; 156 | 157 | //bundlePath should be a real-path 158 | NSString* subPath = relativize(enumURL, [NSURL fileURLWithPath:backup], YES); 159 | NSString* restorePath = [bundlePath stringByAppendingPathComponent:subPath]; 160 | 161 | SYSLOG("restore %@ => %@", enumURL.path, restorePath); 162 | 163 | if([fm fileExistsAtPath:restorePath]) 164 | ASSERT([fm removeItemAtPath:restorePath error:nil]); 165 | 166 | NSError* err=nil; 167 | if(![fm moveItemAtPath:enumURL.path toPath:restorePath error:&err]) { 168 | SYSLOG("move failed %@", err); 169 | ABORT(); 170 | } 171 | 172 | restoreFileCount++; 173 | 174 | } } 175 | 176 | ASSERT(restoreFileCount > 0); 177 | 178 | ASSERT([fm removeItemAtPath:backup error:nil]); 179 | ASSERT([fm removeItemAtPath:[backup.stringByDeletingLastPathComponent stringByAppendingPathComponent:@".appbackup"] error:nil]); 180 | 181 | return 0; 182 | } 183 | 184 | 185 | int enableForApp(NSString* bundlePath) 186 | { 187 | SYSLOG("enableForApp %@", bundlePath); 188 | 189 | NSFileManager* fm = NSFileManager.defaultManager; 190 | 191 | NSDictionary* appInfo = [NSDictionary dictionaryWithContentsOfFile:[bundlePath stringByAppendingPathComponent:@"Info.plist"]]; 192 | if(!appInfo) return -1; 193 | 194 | if([bundlePath hasPrefix:@"/Applications/"]) 195 | { 196 | if([fm fileExistsAtPath:jbroot(bundlePath)]) 197 | ASSERT([fm removeItemAtPath:jbroot(bundlePath) error:nil]); 198 | 199 | ASSERT([fm copyItemAtPath:bundlePath toPath:jbroot(bundlePath) error:nil]); 200 | 201 | ASSERT([fm createSymbolicLinkAtPath:[jbroot(bundlePath) stringByAppendingString:@"/.jbroot"] withDestinationPath:jbroot(@"/") error:nil]); 202 | 203 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-p", bundlePath.UTF8String, NULL}, nil, nil) == 0); 204 | } 205 | else if([appInfo[@"CFBundleIdentifier"] hasPrefix:@"com.apple."] 206 | || [NSFileManager.defaultManager fileExistsAtPath:[bundlePath stringByAppendingString:@"/../_TrollStore"]]) 207 | { 208 | ASSERT(backupApp(bundlePath) == 0); 209 | 210 | ASSERT([fm createSymbolicLinkAtPath:[bundlePath stringByAppendingString:@"/.jbroot"] withDestinationPath:jbroot(@"/") error:nil]); 211 | 212 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-s","-p", rootfsPrefix(bundlePath).UTF8String, NULL}, nil, nil) == 0); 213 | } 214 | else 215 | { 216 | ASSERT(backupApp(bundlePath) == 0); 217 | 218 | ASSERT([fm createSymbolicLinkAtPath:[bundlePath stringByAppendingString:@"/.jbroot"] withDestinationPath:jbroot(@"/") error:nil]); 219 | 220 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-s","-p", rootfsPrefix(bundlePath).UTF8String, NULL}, nil, nil) == 0); 221 | } 222 | 223 | return 0; 224 | } 225 | 226 | int disableForApp(NSString* bundlePath) 227 | { 228 | SYSLOG("disalbeForApp %@", bundlePath); 229 | 230 | NSFileManager* fm = NSFileManager.defaultManager; 231 | 232 | NSDictionary* appInfo = [NSDictionary dictionaryWithContentsOfFile:[bundlePath stringByAppendingPathComponent:@"Info.plist"]]; 233 | if(!appInfo) return -1; 234 | 235 | if(![bundlePath hasPrefix:@"/Applications/"] && [bundlePath containsString:@"/Applications/"]) 236 | { 237 | ASSERT([fm removeItemAtPath:bundlePath error:nil]); 238 | 239 | NSString* sysPath = [@"/Applications/" stringByAppendingString:bundlePath.lastPathComponent]; 240 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-p", rootfsPrefix(sysPath).UTF8String, NULL}, nil, nil) == 0); 241 | } 242 | else if([appInfo[@"CFBundleIdentifier"] hasPrefix:@"com.apple."] 243 | || [NSFileManager.defaultManager fileExistsAtPath:[bundlePath stringByAppendingString:@"/../_TrollStore"]]) 244 | { 245 | ASSERT(restoreApp(bundlePath) == 0); 246 | ASSERT([fm removeItemAtPath:[bundlePath stringByAppendingString:@"/.jbroot"] error:nil]); 247 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-s","-p", rootfsPrefix(bundlePath).UTF8String, NULL}, nil, nil) == 0); 248 | } 249 | else 250 | { 251 | //should be an appstored app 252 | 253 | ASSERT(restoreApp(bundlePath) == 0); 254 | 255 | ASSERT([fm removeItemAtPath:[bundlePath stringByAppendingString:@"/.jbroot"] error:nil]); 256 | 257 | //unregister or respring to keep app's icon on home screen 258 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-u", rootfsPrefix(bundlePath).UTF8String, NULL}, nil, nil) == 0); 259 | //come back 260 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache","-p", rootfsPrefix(bundlePath).UTF8String, NULL}, nil, nil) == 0); 261 | } 262 | 263 | return 0; 264 | } 265 | -------------------------------------------------------------------------------- /Bootstrap/AppList.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @interface AppList : NSObject 5 | @property (nonatomic, strong) NSString *infoPlistPath; 6 | 7 | @property (nonatomic, readonly) NSString* bundleIdentifier; 8 | @property (nonatomic, readonly) NSString* name; 9 | @property (nonatomic, readonly) UIImage* icon; 10 | @property (nonatomic, readonly) NSURL *bundleURL; 11 | @property (nonatomic, readonly) NSURL *containerURL; 12 | 13 | @property (nonatomic, readonly) NSString *applicationDSID; 14 | @property (nonatomic, readonly) NSString *applicationIdentifier; 15 | @property (nonatomic, readonly) NSString *applicationType; 16 | @property (nonatomic, readonly) NSNumber *dynamicDiskUsage; 17 | 18 | @property (nonatomic, readonly) NSArray *groupIdentifiers; 19 | @property (nonatomic, readonly) NSNumber *itemID; 20 | @property (nonatomic, readonly) NSString *itemName; 21 | @property (nonatomic, readonly) NSString *minimumSystemVersion; 22 | @property (nonatomic, readonly) NSArray *requiredDeviceCapabilities; 23 | @property (nonatomic, readonly) NSString *roleIdentifier; 24 | @property (nonatomic, readonly) NSString *sdkVersion; 25 | @property (nonatomic, readonly) NSString *shortVersionString; 26 | @property (nonatomic, readonly) NSString *sourceAppIdentifier; 27 | @property (nonatomic, readonly) NSNumber *staticDiskUsage; 28 | @property (nonatomic, readonly) NSString *teamID; 29 | @property (nonatomic, readonly) NSString *vendorName; 30 | 31 | @property (nonatomic, readonly) BOOL isHiddenApp; 32 | 33 | + (instancetype)appWithPrivateProxy:(id)privateProxy; 34 | + (instancetype)appWithBundleIdentifier:(NSString*)bundleIdentifier; 35 | 36 | @end 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Bootstrap/AppList.m: -------------------------------------------------------------------------------- 1 | // https://github.com/wujianguo/iOSAppsInfo 2 | // modified by Shadow- 3 | 4 | #import "AppList.h" 5 | #import 6 | 7 | @interface UIImage () 8 | + (id)_iconForResourceProxy:(id)arg1 variant:(int)arg2 variantsScale:(float)arg3; 9 | + (id)_applicationIconImageForBundleIdentifier:(id)arg1 format:(int)arg2 scale:(double)arg3; 10 | @end 11 | 12 | #pragma mark - 13 | 14 | @interface PrivateApi_LSApplicationProxy 15 | 16 | + (instancetype)applicationProxyForIdentifier:(NSString*)identifier; 17 | @property (nonatomic, readonly) NSString* localizedShortName; 18 | @property (nonatomic, readonly) NSString* localizedName; 19 | @property (nonatomic, readonly) NSString* bundleIdentifier; 20 | @property (nonatomic, readonly) NSArray* appTags; 21 | 22 | @property (nonatomic, readonly) NSString *applicationDSID; 23 | @property (nonatomic, readonly) NSString *applicationIdentifier; 24 | @property (nonatomic, readonly) NSString *applicationType; 25 | @property (nonatomic, readonly) NSNumber *dynamicDiskUsage; 26 | @property (nonatomic, readonly) NSURL *bundleURL; 27 | @property (nonatomic, readonly) NSURL *containerURL; 28 | 29 | @property (nonatomic, readonly) NSArray *groupIdentifiers; 30 | @property (nonatomic, readonly) NSNumber *itemID; 31 | @property (nonatomic, readonly) NSString *itemName; 32 | @property (nonatomic, readonly) NSString *minimumSystemVersion; 33 | @property (nonatomic, readonly) NSArray *requiredDeviceCapabilities; 34 | @property (nonatomic, readonly) NSString *roleIdentifier; 35 | @property (nonatomic, readonly) NSString *sdkVersion; 36 | @property (nonatomic, readonly) NSString *shortVersionString; 37 | @property (nonatomic, readonly) NSString *sourceAppIdentifier; 38 | @property (nonatomic, readonly) NSNumber *staticDiskUsage; 39 | @property (nonatomic, readonly) NSString *teamID; 40 | @property (nonatomic, readonly) NSString *vendorName; 41 | 42 | @end 43 | 44 | 45 | @implementation AppList 46 | { 47 | PrivateApi_LSApplicationProxy* _applicationProxy; 48 | UIImage* _icon; 49 | } 50 | 51 | - (NSString*)name 52 | { 53 | NSString *languageCode = [[NSLocale preferredLanguages] firstObject]; 54 | NSRange range = [languageCode rangeOfString:@"-" options:NSBackwardsSearch]; 55 | if (range.location != NSNotFound) { 56 | languageCode = [languageCode substringToIndex:range.location]; 57 | } 58 | 59 | NSString *infoPlistPath = [_applicationProxy.bundleURL.path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.lproj/InfoPlist.strings", languageCode]]; 60 | NSFileManager *fileManager = [NSFileManager defaultManager]; 61 | if ([fileManager fileExistsAtPath:infoPlistPath]) { 62 | NSDictionary *plistDict = [[NSDictionary alloc] initWithContentsOfFile:infoPlistPath]; 63 | NSString* displayName = [plistDict objectForKey:@"CFBundleDisplayName"]; 64 | if (displayName) { 65 | return displayName; 66 | } 67 | } 68 | 69 | return _applicationProxy.localizedName ?: _applicationProxy.localizedShortName; 70 | } 71 | 72 | - (NSString*)bundleIdentifier 73 | { 74 | return [_applicationProxy bundleIdentifier]; 75 | } 76 | 77 | - (UIImage*)icon 78 | { 79 | if(nil == _icon) 80 | { 81 | _icon = [UIImage _applicationIconImageForBundleIdentifier:self.bundleIdentifier format:10 scale:UIScreen.mainScreen.scale]; 82 | } 83 | 84 | return _icon; 85 | } 86 | 87 | - (NSString*)applicationDSID 88 | { 89 | return _applicationProxy.applicationDSID; 90 | } 91 | - (NSURL*)bundleURL 92 | { 93 | return _applicationProxy.bundleURL; 94 | } 95 | - (NSURL*)containerURL 96 | { 97 | return _applicationProxy.containerURL; 98 | } 99 | - (NSString*)applicationIdentifier 100 | { 101 | return _applicationProxy.applicationIdentifier; 102 | } 103 | 104 | - (NSString*)applicationType 105 | { 106 | return _applicationProxy.applicationType; 107 | } 108 | 109 | - (NSArray*)groupIdentifiers 110 | { 111 | return _applicationProxy.groupIdentifiers; 112 | } 113 | 114 | - (NSNumber*)itemID 115 | { 116 | return _applicationProxy.itemID; 117 | } 118 | 119 | - (NSString*)itemName 120 | { 121 | return _applicationProxy.itemName; 122 | } 123 | 124 | - (NSString*)minimumSystemVersion 125 | { 126 | return _applicationProxy.minimumSystemVersion; 127 | } 128 | 129 | - (NSArray*)requiredDeviceCapabilities 130 | { 131 | return _applicationProxy.requiredDeviceCapabilities; 132 | } 133 | 134 | - (NSString*)sdkVersion 135 | { 136 | return _applicationProxy.sdkVersion; 137 | } 138 | 139 | - (NSString*)shortVersionString 140 | { 141 | return _applicationProxy.shortVersionString; 142 | } 143 | 144 | - (NSNumber*)staticDiskUsage 145 | { 146 | return _applicationProxy.staticDiskUsage; 147 | } 148 | 149 | - (NSString*)teamID 150 | { 151 | return _applicationProxy.teamID; 152 | } 153 | 154 | - (NSString*)vendorName 155 | { 156 | return _applicationProxy.vendorName; 157 | } 158 | 159 | - (BOOL)isHiddenApp 160 | { 161 | return [[_applicationProxy appTags] indexOfObject:@"hidden"] != NSNotFound; 162 | } 163 | 164 | - (id)initWithPrivateProxy:(id)privateProxy 165 | { 166 | self = [super init]; 167 | if(self != nil) 168 | { 169 | _applicationProxy = (PrivateApi_LSApplicationProxy*)privateProxy; 170 | } 171 | 172 | return self; 173 | } 174 | 175 | - (instancetype)initWithBundleIdentifier:(NSString*)bundleIdentifier 176 | { 177 | self = [super init]; 178 | if(self != nil) 179 | { 180 | _applicationProxy = [NSClassFromString(@"LSApplicationProxy") applicationProxyForIdentifier:bundleIdentifier]; 181 | } 182 | 183 | return self; 184 | } 185 | 186 | + (instancetype)appWithPrivateProxy:(id)privateProxy 187 | { 188 | return [[self alloc] initWithPrivateProxy:privateProxy]; 189 | } 190 | 191 | + (instancetype)appWithBundleIdentifier:(NSString*)bundleIdentifier 192 | { 193 | return [[self alloc] initWithBundleIdentifier:bundleIdentifier]; 194 | } 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /Bootstrap/AppViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface AppViewController : UITableViewController 6 | 7 | + (instancetype)sharedInstance; 8 | 9 | @end 10 | 11 | NS_ASSUME_NONNULL_END 12 | -------------------------------------------------------------------------------- /Bootstrap/AppViewController.m: -------------------------------------------------------------------------------- 1 | // ref https://github.com/XsF1re/FlyJB-App 2 | 3 | #import "AppViewController.h" 4 | #include "AppDelegate.h" 5 | #import "AppList.h" 6 | #include "common.h" 7 | #include "AppDelegate.h" 8 | #include 9 | 10 | @interface PrivateApi_LSApplicationWorkspace 11 | - (NSArray*)allInstalledApplications; 12 | - (BOOL)openApplicationWithBundleID:(id)arg1; 13 | - (NSArray*)privateURLSchemes; 14 | - (NSArray*)publicURLSchemes; 15 | - (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 16 | internal:(BOOL)arg2 17 | user:(BOOL)arg3; 18 | @end 19 | 20 | @interface AppViewController () { 21 | UISearchController *searchController; 22 | NSArray *appsArray; 23 | 24 | NSMutableArray* filteredApps; 25 | BOOL isFiltered; 26 | } 27 | 28 | @end 29 | 30 | @implementation AppViewController 31 | 32 | + (instancetype)sharedInstance { 33 | static AppViewController* sharedInstance = nil; 34 | static dispatch_once_t onceToken; 35 | dispatch_once(&onceToken, ^{ 36 | sharedInstance = [[self alloc] init]; 37 | }); 38 | return sharedInstance; 39 | } 40 | 41 | -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { 42 | [searchBar resignFirstResponder]; 43 | } 44 | - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 45 | isFiltered = false; 46 | [self.tableView reloadData]; 47 | } 48 | 49 | -(void)reloadSearch { 50 | NSString* searchText = searchController.searchBar.text; 51 | if(searchText.length == 0) { 52 | isFiltered = false; 53 | } else { 54 | isFiltered = true; 55 | filteredApps = [[NSMutableArray alloc] init]; 56 | searchText = searchText.lowercaseString; 57 | for (AppList* app in appsArray) { 58 | NSRange nameRange = [app.name.lowercaseString rangeOfString:searchText options:NSCaseInsensitiveSearch]; 59 | NSRange bundleIdRange = [app.bundleIdentifier.lowercaseString rangeOfString:searchText options:NSCaseInsensitiveSearch]; 60 | if(nameRange.location != NSNotFound || bundleIdRange.location != NSNotFound) { 61 | [filteredApps addObject:app]; 62 | } 63 | } 64 | } 65 | } 66 | 67 | -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { 68 | [self reloadSearch]; 69 | [self.tableView reloadData]; 70 | } 71 | 72 | 73 | - (void)viewDidLoad { 74 | [super viewDidLoad]; 75 | self.navigationController.navigationBar.hidden = NO; 76 | self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleInsetGrouped]; 77 | self.tableView.tableFooterView = [[UIView alloc] init]; 78 | 79 | [self setTitle:Localized(@"Tweak Enabler")]; 80 | 81 | isFiltered = false; 82 | 83 | searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; 84 | searchController.searchBar.delegate = self; 85 | searchController.searchBar.placeholder = Localized(@"name or identifier"); 86 | searchController.searchBar.barTintColor = [UIColor whiteColor]; 87 | searchController.searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin; 88 | self.navigationItem.searchController = searchController; 89 | self.navigationItem.hidesSearchBarWhenScrolling = NO; 90 | 91 | UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; 92 | refreshControl.tintColor = [UIColor grayColor]; 93 | [refreshControl addTarget:self action:@selector(startRefresh) forControlEvents:UIControlEventValueChanged]; 94 | self.tableView.refreshControl = refreshControl; 95 | 96 | [self updateData:YES]; 97 | 98 | [[NSNotificationCenter defaultCenter] addObserver:self 99 | selector:@selector(startRefresh2) 100 | name:UIApplicationWillEnterForegroundNotification 101 | object:nil]; 102 | } 103 | 104 | - (void)startRefresh { 105 | [self.tableView.refreshControl beginRefreshing]; 106 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 107 | [self updateData:YES]; 108 | dispatch_async(dispatch_get_main_queue(), ^{ 109 | [self.tableView.refreshControl endRefreshing]; 110 | }); 111 | }); 112 | } 113 | 114 | - (void)startRefresh2 { 115 | [self.tableView.refreshControl beginRefreshing]; 116 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 117 | [self updateData:NO]; 118 | dispatch_async(dispatch_get_main_queue(), ^{ 119 | [self.tableView.refreshControl endRefreshing]; 120 | }); 121 | }); 122 | } 123 | 124 | - (void)viewWillAppear:(BOOL)animated { 125 | [super viewWillAppear:animated]; 126 | [self.tableView.refreshControl beginRefreshing]; 127 | [self.tableView.refreshControl endRefreshing]; 128 | } 129 | 130 | - (void)updateData:(BOOL)sort { 131 | NSMutableArray* applications = [NSMutableArray new]; 132 | PrivateApi_LSApplicationWorkspace* _workspace = [NSClassFromString(@"LSApplicationWorkspace") new]; 133 | NSArray* allInstalledApplications = [_workspace allInstalledApplications]; 134 | 135 | for(id proxy in allInstalledApplications) 136 | { 137 | AppList* app = [AppList appWithPrivateProxy:proxy]; 138 | 139 | // if(app.isHiddenApp) continue; 140 | 141 | if(![app.bundleURL.path hasPrefix:@"/Applications/"] && !isDefaultInstallationPath(app.bundleURL.path)) { 142 | //sysapp installed as jailbreak apps 143 | NSString* sysPath = [@"/Applications/" stringByAppendingPathComponent:app.bundleURL.path.lastPathComponent]; 144 | if(![NSFileManager.defaultManager fileExistsAtPath:sysPath]) 145 | continue; 146 | } 147 | 148 | if([app.applicationType isEqualToString:@"User"]) { 149 | NSArray* allowedBundleIds = [NSArray arrayWithContentsOfFile:jbroot(@"/.showcase.plist")]; 150 | if(allowedBundleIds && ![allowedBundleIds containsObject:app.bundleIdentifier]) 151 | continue; 152 | } 153 | 154 | if([NSFileManager.defaultManager fileExistsAtPath: 155 | [app.bundleURL.path stringByAppendingString:@"/.TrollStorePresistenceHelper"]]) 156 | continue; 157 | 158 | if([app.bundleURL.path.lastPathComponent isEqualToString:@"TrollStore.app"]) 159 | continue; 160 | 161 | if([app.bundleURL.path.lastPathComponent isEqualToString:@"Bootstrap.app"]) 162 | continue; 163 | 164 | [applications addObject:app]; 165 | } 166 | 167 | if(sort) 168 | { 169 | NSArray *appsSortedByName = [applications sortedArrayUsingComparator:^NSComparisonResult(AppList *app1, AppList *app2) { 170 | struct stat st; 171 | BOOL enabled1 = lstat([app1.bundleURL.path stringByAppendingPathComponent:@".jbroot"].fileSystemRepresentation, &st)==0; 172 | BOOL enabled2 = lstat([app2.bundleURL.path stringByAppendingPathComponent:@".jbroot"].fileSystemRepresentation, &st)==0; 173 | if(enabled1 || enabled2) { 174 | return [@(enabled2) compare:@(enabled1)]; 175 | } 176 | 177 | if(app1.isHiddenApp || app2.isHiddenApp) { 178 | return [@(app1.isHiddenApp) compare:@(app2.isHiddenApp)]; 179 | } 180 | 181 | return [app1.name localizedStandardCompare:app2.name]; 182 | }]; 183 | 184 | self->appsArray = appsSortedByName; 185 | } 186 | else 187 | { 188 | NSMutableArray *newapps = [NSMutableArray array]; 189 | [applications enumerateObjectsUsingBlock:^(AppList *newobj, NSUInteger idx, BOOL * _Nonnull stop) { 190 | __block BOOL hasBeenContained = NO; 191 | [self->appsArray enumerateObjectsUsingBlock:^(AppList *obj, NSUInteger idx, BOOL * _Nonnull stop) { 192 | if ([obj.bundleIdentifier isEqualToString:newobj.bundleIdentifier]) { 193 | hasBeenContained = YES; 194 | *stop = YES; 195 | } 196 | }]; 197 | if (!hasBeenContained) { 198 | [newapps addObject:newobj]; 199 | } 200 | }]; 201 | 202 | NSMutableArray *tmpArray = [NSMutableArray array]; 203 | [self->appsArray enumerateObjectsUsingBlock:^(AppList *obj, NSUInteger idx, BOOL * _Nonnull stop) { 204 | [applications enumerateObjectsUsingBlock:^(AppList *newobj, NSUInteger idx, BOOL * _Nonnull stop) { 205 | if ([obj.bundleIdentifier isEqualToString:newobj.bundleIdentifier]) { 206 | [tmpArray addObject:newobj]; 207 | *stop = YES; 208 | } 209 | }]; 210 | }]; 211 | 212 | [tmpArray addObjectsFromArray:newapps]; 213 | self->appsArray = tmpArray.copy; 214 | } 215 | 216 | dispatch_async(dispatch_get_main_queue(), ^{ 217 | [self reloadSearch]; 218 | [self.tableView reloadData]; 219 | }); 220 | } 221 | 222 | #pragma mark - Table view data source 223 | 224 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 225 | return 1; 226 | } 227 | 228 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 229 | return isFiltered? filteredApps.count : appsArray.count; 230 | } 231 | 232 | - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 233 | return @"Applist"; 234 | } 235 | 236 | - (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 237 | return [[UIView alloc] init]; 238 | } 239 | - (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 240 | return [[UIView alloc] init]; 241 | } 242 | 243 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 244 | [tableView deselectRowAtIndexPath:indexPath animated:YES];// 245 | } 246 | 247 | - (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize { 248 | UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); 249 | [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; 250 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 251 | UIGraphicsEndImageContext(); 252 | return newImage; 253 | } 254 | 255 | NSArray* unsupportedBundleIDs = @[ 256 | // @"com.apple.mobileslideshow", 257 | // @"com.apple.mobilesafari", 258 | ]; 259 | 260 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 261 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"]; 262 | 263 | AppList* app = isFiltered? filteredApps[indexPath.row] : appsArray[indexPath.row]; 264 | 265 | if(!app.isHiddenApp) { 266 | UIImage *image = app.icon; 267 | cell.imageView.image = [self imageWithImage:image scaledToSize:CGSizeMake(40, 40)]; 268 | cell.textLabel.text = app.name; 269 | } else { 270 | cell.textLabel.text = app.bundleIdentifier; 271 | } 272 | 273 | cell.detailTextLabel.text = app.bundleIdentifier; 274 | 275 | UISwitch *theSwitch = [[UISwitch alloc] init]; 276 | 277 | if([unsupportedBundleIDs containsObject:app.bundleIdentifier]) 278 | theSwitch.enabled = NO; 279 | 280 | struct stat st; 281 | BOOL enabled = lstat([app.bundleURL.path stringByAppendingPathComponent:@".jbroot"].fileSystemRepresentation, &st)==0; 282 | [theSwitch setOn:enabled]; 283 | [theSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 284 | 285 | cell.accessoryView = theSwitch; 286 | 287 | UILongPressGestureRecognizer *gest = [[UILongPressGestureRecognizer alloc] 288 | initWithTarget:self action:@selector(cellLongPress:)]; 289 | [cell.contentView addGestureRecognizer:gest]; 290 | gest.view.tag = indexPath.row | indexPath.section<<32; 291 | gest.minimumPressDuration = 1; 292 | 293 | return cell; 294 | } 295 | 296 | - (void)switchChanged:(id)sender { 297 | // https://stackoverflow.com/questions/31063571/getting-indexpath-from-switch-on-uitableview 298 | UISwitch *switchInCell = (UISwitch *)sender; 299 | CGPoint pos = [switchInCell convertPoint:switchInCell.bounds.origin toView:self.tableView]; 300 | NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pos]; 301 | BOOL enabled = switchInCell.on; 302 | AppList* app = isFiltered? filteredApps[indexPath.row] : appsArray[indexPath.row]; 303 | 304 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 305 | [AppDelegate showHudMsg:Localized(@"Applying")]; 306 | 307 | killAllForApp(app.bundleURL.path.UTF8String); 308 | 309 | int status; 310 | NSString* log=nil; 311 | NSString* err=nil; 312 | if(enabled) { 313 | status = spawnRoot(NSBundle.mainBundle.executablePath, @[@"enableapp",app.bundleURL.path], &log, &err); 314 | } else { 315 | status = spawnRoot(NSBundle.mainBundle.executablePath, @[@"disableapp",app.bundleURL.path], &log, &err); 316 | } 317 | 318 | if(status != 0) { 319 | [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 320 | } 321 | 322 | killAllForApp(app.bundleURL.path.UTF8String); 323 | 324 | //refresh app cache list 325 | [self updateData:NO]; 326 | 327 | [AppDelegate dismissHud]; 328 | 329 | }); 330 | } 331 | 332 | - (void)cellLongPress:(UIGestureRecognizer *)recognizer 333 | { 334 | if (recognizer.state == UIGestureRecognizerStateBegan) 335 | { 336 | long tag = recognizer.view.tag; 337 | NSIndexPath* indexPath = [NSIndexPath indexPathForRow:tag&0xFFFFFFFF inSection:tag>>32]; 338 | 339 | AppList* app = isFiltered? filteredApps[indexPath.row] : appsArray[indexPath.row]; 340 | 341 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 342 | PrivateApi_LSApplicationWorkspace* _workspace = [NSClassFromString(@"LSApplicationWorkspace") new]; 343 | [_workspace openApplicationWithBundleID:app.bundleIdentifier]; 344 | }); 345 | } 346 | } 347 | @end 348 | -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "20x20", 5 | "idiom": "universal", 6 | "filename": "icon-20@2x.png", 7 | "scale": "2x", 8 | "platform": "ios" 9 | }, 10 | { 11 | "size": "20x20", 12 | "idiom": "universal", 13 | "filename": "icon-20@3x.png", 14 | "scale": "3x", 15 | "platform": "ios" 16 | }, 17 | { 18 | "size": "29x29", 19 | "idiom": "universal", 20 | "filename": "icon-29@2x.png", 21 | "scale": "2x", 22 | "platform": "ios" 23 | }, 24 | { 25 | "size": "29x29", 26 | "idiom": "universal", 27 | "filename": "icon-29@3x.png", 28 | "scale": "3x", 29 | "platform": "ios" 30 | }, 31 | { 32 | "size": "38x38", 33 | "idiom": "universal", 34 | "filename": "icon-38@2x.png", 35 | "scale": "2x", 36 | "platform": "ios" 37 | }, 38 | { 39 | "size": "38x38", 40 | "idiom": "universal", 41 | "filename": "icon-38@3x.png", 42 | "scale": "3x", 43 | "platform": "ios" 44 | }, 45 | { 46 | "size": "40x40", 47 | "idiom": "universal", 48 | "filename": "icon-40@2x.png", 49 | "scale": "2x", 50 | "platform": "ios" 51 | }, 52 | { 53 | "size": "40x40", 54 | "idiom": "universal", 55 | "filename": "icon-40@3x.png", 56 | "scale": "3x", 57 | "platform": "ios" 58 | }, 59 | { 60 | "size": "60x60", 61 | "idiom": "universal", 62 | "filename": "icon-60@2x.png", 63 | "scale": "2x", 64 | "platform": "ios" 65 | }, 66 | { 67 | "size": "60x60", 68 | "idiom": "universal", 69 | "filename": "icon-60@3x.png", 70 | "scale": "3x", 71 | "platform": "ios" 72 | }, 73 | { 74 | "size": "64x64", 75 | "idiom": "universal", 76 | "filename": "icon-64@2x.png", 77 | "scale": "2x", 78 | "platform": "ios" 79 | }, 80 | { 81 | "size": "64x64", 82 | "idiom": "universal", 83 | "filename": "icon-64@3x.png", 84 | "scale": "3x", 85 | "platform": "ios" 86 | }, 87 | { 88 | "size": "68x68", 89 | "idiom": "universal", 90 | "filename": "icon-68@2x.png", 91 | "scale": "2x", 92 | "platform": "ios" 93 | }, 94 | { 95 | "size": "76x76", 96 | "idiom": "universal", 97 | "filename": "icon-76@2x.png", 98 | "scale": "2x", 99 | "platform": "ios" 100 | }, 101 | { 102 | "size": "83.5x83.5", 103 | "idiom": "universal", 104 | "filename": "icon-83.5@2x.png", 105 | "scale": "2x", 106 | "platform": "ios" 107 | }, 108 | { 109 | "size": "1024x1024", 110 | "idiom": "universal", 111 | "filename": "icon-1024.png", 112 | "scale": "1x", 113 | "platform": "ios" 114 | } 115 | ], 116 | "info": { 117 | "version": 1, 118 | "author": "icon.wuruihong.com" 119 | } 120 | } -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "size": "20x20", 5 | "idiom": "universal", 6 | "filename": "icon-20@2x.png", 7 | "scale": "2x", 8 | "platform": "ios" 9 | }, 10 | { 11 | "size": "20x20", 12 | "idiom": "universal", 13 | "filename": "icon-20@3x.png", 14 | "scale": "3x", 15 | "platform": "ios" 16 | }, 17 | { 18 | "size": "29x29", 19 | "idiom": "universal", 20 | "filename": "icon-29@2x.png", 21 | "scale": "2x", 22 | "platform": "ios" 23 | }, 24 | { 25 | "size": "29x29", 26 | "idiom": "universal", 27 | "filename": "icon-29@3x.png", 28 | "scale": "3x", 29 | "platform": "ios" 30 | }, 31 | { 32 | "size": "38x38", 33 | "idiom": "universal", 34 | "filename": "icon-38@2x.png", 35 | "scale": "2x", 36 | "platform": "ios" 37 | }, 38 | { 39 | "size": "38x38", 40 | "idiom": "universal", 41 | "filename": "icon-38@3x.png", 42 | "scale": "3x", 43 | "platform": "ios" 44 | }, 45 | { 46 | "size": "40x40", 47 | "idiom": "universal", 48 | "filename": "icon-40@2x.png", 49 | "scale": "2x", 50 | "platform": "ios" 51 | }, 52 | { 53 | "size": "40x40", 54 | "idiom": "universal", 55 | "filename": "icon-40@3x.png", 56 | "scale": "3x", 57 | "platform": "ios" 58 | }, 59 | { 60 | "size": "60x60", 61 | "idiom": "universal", 62 | "filename": "icon-60@2x.png", 63 | "scale": "2x", 64 | "platform": "ios" 65 | }, 66 | { 67 | "size": "60x60", 68 | "idiom": "universal", 69 | "filename": "icon-60@3x.png", 70 | "scale": "3x", 71 | "platform": "ios" 72 | }, 73 | { 74 | "size": "64x64", 75 | "idiom": "universal", 76 | "filename": "icon-64@2x.png", 77 | "scale": "2x", 78 | "platform": "ios" 79 | }, 80 | { 81 | "size": "64x64", 82 | "idiom": "universal", 83 | "filename": "icon-64@3x.png", 84 | "scale": "3x", 85 | "platform": "ios" 86 | }, 87 | { 88 | "size": "68x68", 89 | "idiom": "universal", 90 | "filename": "icon-68@2x.png", 91 | "scale": "2x", 92 | "platform": "ios" 93 | }, 94 | { 95 | "size": "76x76", 96 | "idiom": "universal", 97 | "filename": "icon-76@2x.png", 98 | "scale": "2x", 99 | "platform": "ios" 100 | }, 101 | { 102 | "size": "83.5x83.5", 103 | "idiom": "universal", 104 | "filename": "icon-83.5@2x.png", 105 | "scale": "2x", 106 | "platform": "ios" 107 | }, 108 | { 109 | "size": "1024x1024", 110 | "idiom": "universal", 111 | "filename": "icon-1024.png", 112 | "scale": "1x", 113 | "platform": "ios" 114 | } 115 | ], 116 | "info": { 117 | "version": 1, 118 | "author": "icon.wuruihong.com" 119 | } 120 | } -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-1024.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-20@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-20@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-29@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-29@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-38@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-38@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-38@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-38@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-40@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-40@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-60@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-60@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-64@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-64@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-64@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-64@3x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-68@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-68@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-76@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/Assets.xcassets/AppIcon.appiconset1/icon-83.5@2x.png -------------------------------------------------------------------------------- /Bootstrap/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Bootstrap/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Bootstrap/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 69 | 70 | 71 | 72 | 73 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 92 | 100 | 108 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /Bootstrap/Frameworks/MobileContainerManager.framework/MobileContainerManager.tbd: -------------------------------------------------------------------------------- 1 | --- !tapi-tbd-v3 2 | archs: [ armv7, armv7s, arm64, arm64e ] 3 | platform: ios 4 | flags: [ flat_namespace ] 5 | install-name: /System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager 6 | current-version: 1 7 | compatibility-version: 1 8 | objc-constraint: retain_release 9 | exports: 10 | - archs: [ armv7, armv7s, arm64, arm64e ] 11 | symbols: [ _MCMErrorDomain, _MCMFunctionNameErrorKey, 12 | _MCMPathArgumentErrorKey, _MCMSourceFileLineErrorKey, 13 | _kMCMACLFailureError, _kMCMBadInitializerValuesError, 14 | _kMCMBadReplyContentsError, 15 | _kMCMBundleOwnerMigrationFailError, 16 | _kMCMCacheAddError, _kMCMCacheFailedToRebuildError, 17 | _kMCMCacheInconsistencyError, 18 | _kMCMCacheInvalidDataError, _kMCMCacheRemoveError, 19 | _kMCMContainerNotFoundError, 20 | _kMCMContainersWithClassInitError, 21 | _kMCMCreateBaseDirectoryError, 22 | _kMCMCreateContainerClassDirectoryError, 23 | _kMCMCreateDeathRowDirectoryError, 24 | _kMCMCreateReplaceDirectoryError, 25 | _kMCMCreateStagingDirectoryError, 26 | _kMCMCreateSubDirectoryError, 27 | _kMCMCreateTempDirectoryError, 28 | _kMCMDataProtectionFailLockedError, 29 | _kMCMDestroyContainerError, _kMCMExceptionError, 30 | _kMCMExistingContainerReplaceError, 31 | _kMCMFailureToGetErrorReply, 32 | _kMCMGetMetadataErrorError, 33 | _kMCMIdentifierNotFoundInDbError, 34 | _kMCMInvalidCommandError, 35 | _kMCMInvalidContainerObjectError, 36 | _kMCMInvalidEntitlementInfoError, 37 | _kMCMInvalidMetadataError, 38 | _kMCMInvalidMetadataURLMismatchError, 39 | _kMCMInvalidParametersError, _kMCMInvalidReplyError, 40 | _kMCMInvalidURLError, 41 | _kMCMMismatchedClassReplaceError, 42 | _kMCMMismatchedUserReplaceError, 43 | _kMCMMoveStagingToLiveError, 44 | _kMCMMoveToDeathRowError, _kMCMNilIdentifierError, 45 | _kMCMNotEntitledForOperationError, 46 | _kMCMPathNotFoundError, 47 | _kMCMPendingUpdateNoLongerValidError, 48 | _kMCMReadEntitlementFileError, 49 | _kMCMReadMetadataError, _kMCMRegenerateUUIDMoveError, 50 | _kMCMRemoveIndividualStagingDirectoryError, 51 | _kMCMRemoveLegacyDirectoryError, 52 | _kMCMRemoveStagingDirectoryError, 53 | _kMCMRemoveTempContainerError, 54 | _kMCMReplaceContainerError, 55 | _kMCMReplaceMoveToTempError, 56 | _kMCMReplaceRecoverError, _kMCMReplaceRemoveError, 57 | _kMCMReplaceURLError, _kMCMRestoreContainerError, 58 | _kMCMRestorePathExistsError, _kMCMSQLiteError, 59 | _kMCMSQLiteUnexpectedNumChangesError, 60 | _kMCMSameContainerReplaceError, 61 | _kMCMSetSandboxMappingError, _kMCMSetupProxyError, 62 | _kMCMStageForDeleteError, 63 | _kMCMStageSharedContentFailureError, _kMCMSuccess, 64 | _kMCMUndefinedContainerClassError, 65 | _kMCMUnknownSubdirectoriesForClassError, 66 | _kMCMValueNotFoundForKeyError, 67 | _kMCMWriteEntitlementFileError, 68 | _kMCMWriteMetadataDictionaryError, 69 | _kMCMXPCInterruptedReplyError, 70 | _kMCMXPCInvalidReplyError, _kMCMXPCSetupError, 71 | _kMCMXPCUnknownReplyError ] 72 | objc-classes: [ MCMAppContainer, MCMAppDataContainer, MCMContainer, 73 | MCMContainerManager, MCMDataContainer, 74 | MCMFrameworkContainer, 75 | MCMInternalDaemonDataContainer, MCMLazyDescription, 76 | MCMPluginKitPluginContainer, 77 | MCMPluginKitPluginDataContainer, 78 | MCMSharedDataContainer, MCMSharedSystemDataContainer, 79 | MCMSystemDataContainer, MCMTempDirDataContainer, 80 | MCMVPNPluginContainer, MCMVPNPluginDataContainer, 81 | MCMXPCServiceDataContainer ] 82 | objc-ivars: [ MCMContainer._containerClass, 83 | MCMContainer._identifier, 84 | MCMContainer._personaUniqueString, 85 | MCMContainer._thisContainer, MCMContainer._uuid, 86 | MCMLazyDescription._block, MCMLazyDescription._value ] 87 | ... 88 | -------------------------------------------------------------------------------- /Bootstrap/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 RootHide 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 | -------------------------------------------------------------------------------- /Bootstrap/MBProgressHUD.framework/Headers/MBProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // MBProgressHUD.h 3 | // Version 1.2.0 4 | // Created by Matej Bukovinski on 2.4.09. 5 | // 6 | 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | 9 | // Copyright © 2009-2020 Matej Bukovinski 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | #import 31 | #import 32 | 33 | @class MBBackgroundView; 34 | @protocol MBProgressHUDDelegate; 35 | 36 | 37 | extern CGFloat const MBProgressMaxOffset; 38 | 39 | typedef NS_ENUM(NSInteger, MBProgressHUDMode) { 40 | /// UIActivityIndicatorView. 41 | MBProgressHUDModeIndeterminate, 42 | /// A round, pie-chart like, progress view. 43 | MBProgressHUDModeDeterminate, 44 | /// Horizontal progress bar. 45 | MBProgressHUDModeDeterminateHorizontalBar, 46 | /// Ring-shaped progress view. 47 | MBProgressHUDModeAnnularDeterminate, 48 | /// Shows a custom view. 49 | MBProgressHUDModeCustomView, 50 | /// Shows only labels. 51 | MBProgressHUDModeText 52 | }; 53 | 54 | typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) { 55 | /// Opacity animation 56 | MBProgressHUDAnimationFade, 57 | /// Opacity + scale animation (zoom in when appearing zoom out when disappearing) 58 | MBProgressHUDAnimationZoom, 59 | /// Opacity + scale animation (zoom out style) 60 | MBProgressHUDAnimationZoomOut, 61 | /// Opacity + scale animation (zoom in style) 62 | MBProgressHUDAnimationZoomIn 63 | }; 64 | 65 | typedef NS_ENUM(NSInteger, MBProgressHUDBackgroundStyle) { 66 | /// Solid color background 67 | MBProgressHUDBackgroundStyleSolidColor, 68 | /// UIVisualEffectView or UIToolbar.layer background view 69 | MBProgressHUDBackgroundStyleBlur 70 | }; 71 | 72 | typedef void (^MBProgressHUDCompletionBlock)(void); 73 | 74 | 75 | NS_ASSUME_NONNULL_BEGIN 76 | 77 | 78 | /** 79 | * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. 80 | * 81 | * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class. 82 | * The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all 83 | * user input on this region, thereby preventing the user operations on components below the view. 84 | * 85 | * @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO. 86 | * @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread. 87 | */ 88 | @interface MBProgressHUD : UIView 89 | 90 | /** 91 | * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. 92 | * 93 | * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. 94 | * 95 | * @param view The view that the HUD will be added to 96 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use 97 | * animations while appearing. 98 | * @return A reference to the created HUD. 99 | * 100 | * @see hideHUDForView:animated: 101 | * @see animationType 102 | */ 103 | + (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; 104 | 105 | /// @name Showing and hiding 106 | 107 | /** 108 | * Finds the top-most HUD subview that hasn't finished and hides it. The counterpart to this method is showHUDAddedTo:animated:. 109 | * 110 | * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. 111 | * 112 | * @param view The view that is going to be searched for a HUD subview. 113 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 114 | * animations while disappearing. 115 | * @return YES if a HUD was found and removed, NO otherwise. 116 | * 117 | * @see showHUDAddedTo:animated: 118 | * @see animationType 119 | */ 120 | + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; 121 | 122 | /** 123 | * Finds the top-most HUD subview that hasn't finished and returns it. 124 | * 125 | * @param view The view that is going to be searched. 126 | * @return A reference to the last HUD subview discovered. 127 | */ 128 | + (nullable MBProgressHUD *)HUDForView:(UIView *)view NS_SWIFT_NAME(forView(_:)); 129 | 130 | /** 131 | * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with 132 | * view.bounds as the parameter. 133 | * 134 | * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as 135 | * the HUD's superview (i.e., the view that the HUD will be added to). 136 | */ 137 | - (instancetype)initWithView:(UIView *)view; 138 | 139 | /** 140 | * Displays the HUD. 141 | * 142 | * @note You need to make sure that the main thread completes its run loop soon after this method call so that 143 | * the user interface can be updated. Call this method when your task is already set up to be executed in a new thread 144 | * (e.g., when using something like NSOperation or making an asynchronous call like NSURLRequest). 145 | * 146 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use 147 | * animations while appearing. 148 | * 149 | * @see animationType 150 | */ 151 | - (void)showAnimated:(BOOL)animated; 152 | 153 | /** 154 | * Hides the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to 155 | * hide the HUD when your task completes. 156 | * 157 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 158 | * animations while disappearing. 159 | * 160 | * @see animationType 161 | */ 162 | - (void)hideAnimated:(BOOL)animated; 163 | 164 | /** 165 | * Hides the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to 166 | * hide the HUD when your task completes. 167 | * 168 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 169 | * animations while disappearing. 170 | * @param delay Delay in seconds until the HUD is hidden. 171 | * 172 | * @see animationType 173 | */ 174 | - (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay; 175 | 176 | /** 177 | * The HUD delegate object. Receives HUD state notifications. 178 | */ 179 | @property (weak, nonatomic) id delegate; 180 | 181 | /** 182 | * Called after the HUD is hidden. 183 | */ 184 | @property (copy, nullable) MBProgressHUDCompletionBlock completionBlock; 185 | 186 | /** 187 | * Grace period is the time (in seconds) that the invoked method may be run without 188 | * showing the HUD. If the task finishes before the grace time runs out, the HUD will 189 | * not be shown at all. 190 | * This may be used to prevent HUD display for very short tasks. 191 | * Defaults to 0 (no grace time). 192 | * @note The graceTime needs to be set before the hud is shown. You thus can't use `showHUDAddedTo:animated:`, 193 | * but instead need to alloc / init the HUD, configure the grace time and than show it manually. 194 | */ 195 | @property (assign, nonatomic) NSTimeInterval graceTime; 196 | 197 | /** 198 | * The minimum time (in seconds) that the HUD is shown. 199 | * This avoids the problem of the HUD being shown and than instantly hidden. 200 | * Defaults to 0 (no minimum show time). 201 | */ 202 | @property (assign, nonatomic) NSTimeInterval minShowTime; 203 | 204 | /** 205 | * Removes the HUD from its parent view when hidden. 206 | * Defaults to NO. 207 | */ 208 | @property (assign, nonatomic) BOOL removeFromSuperViewOnHide; 209 | 210 | /// @name Appearance 211 | 212 | /** 213 | * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate. 214 | */ 215 | @property (assign, nonatomic) MBProgressHUDMode mode; 216 | 217 | /** 218 | * A color that gets forwarded to all labels and supported indicators. Also sets the tintColor 219 | * for custom views on iOS 7+. Set to nil to manage color individually. 220 | * Defaults to semi-translucent black on iOS 7 and later and white on earlier iOS versions. 221 | */ 222 | @property (strong, nonatomic, nullable) UIColor *contentColor UI_APPEARANCE_SELECTOR; 223 | 224 | /** 225 | * The animation type that should be used when the HUD is shown and hidden. 226 | */ 227 | @property (assign, nonatomic) MBProgressHUDAnimation animationType UI_APPEARANCE_SELECTOR; 228 | 229 | /** 230 | * The bezel offset relative to the center of the view. You can use MBProgressMaxOffset 231 | * and -MBProgressMaxOffset to move the HUD all the way to the screen edge in each direction. 232 | * E.g., CGPointMake(0.f, MBProgressMaxOffset) would position the HUD centered on the bottom edge. 233 | */ 234 | @property (assign, nonatomic) CGPoint offset UI_APPEARANCE_SELECTOR; 235 | 236 | /** 237 | * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views). 238 | * This also represents the minimum bezel distance to the edge of the HUD view. 239 | * Defaults to 20.f 240 | */ 241 | @property (assign, nonatomic) CGFloat margin UI_APPEARANCE_SELECTOR; 242 | 243 | /** 244 | * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size). 245 | */ 246 | @property (assign, nonatomic) CGSize minSize UI_APPEARANCE_SELECTOR; 247 | 248 | /** 249 | * Force the HUD dimensions to be equal if possible. 250 | */ 251 | @property (assign, nonatomic, getter = isSquare) BOOL square UI_APPEARANCE_SELECTOR; 252 | 253 | /** 254 | * When enabled, the bezel center gets slightly affected by the device accelerometer data. 255 | * Defaults to NO. 256 | * 257 | * @note This can cause main thread checker assertions on certain devices. https://github.com/jdg/MBProgressHUD/issues/552 258 | */ 259 | @property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled UI_APPEARANCE_SELECTOR; 260 | 261 | /// @name Progress 262 | 263 | /** 264 | * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. 265 | */ 266 | @property (assign, nonatomic) float progress; 267 | 268 | /// @name ProgressObject 269 | 270 | /** 271 | * The NSProgress object feeding the progress information to the progress indicator. 272 | */ 273 | @property (strong, nonatomic, nullable) NSProgress *progressObject; 274 | 275 | /// @name Views 276 | 277 | /** 278 | * The view containing the labels and indicator (or customView). 279 | */ 280 | @property (strong, nonatomic, readonly) MBBackgroundView *bezelView; 281 | 282 | /** 283 | * View covering the entire HUD area, placed behind bezelView. 284 | */ 285 | @property (strong, nonatomic, readonly) MBBackgroundView *backgroundView; 286 | 287 | /** 288 | * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView. 289 | * The view should implement intrinsicContentSize for proper sizing. For best results use approximately 37 by 37 pixels. 290 | */ 291 | @property (strong, nonatomic, nullable) UIView *customView; 292 | 293 | /** 294 | * A label that holds an optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit 295 | * the entire text. 296 | */ 297 | @property (strong, nonatomic, readonly) UILabel *label; 298 | 299 | /** 300 | * A label that holds an optional details message displayed below the labelText message. The details text can span multiple lines. 301 | */ 302 | @property (strong, nonatomic, readonly) UILabel *detailsLabel; 303 | 304 | /** 305 | * A button that is placed below the labels. Visible only if a target / action is added and a title is assigned.. 306 | */ 307 | @property (strong, nonatomic, readonly) UIButton *button; 308 | 309 | @end 310 | 311 | 312 | @protocol MBProgressHUDDelegate 313 | 314 | @optional 315 | 316 | /** 317 | * Called after the HUD was fully hidden from the screen. 318 | */ 319 | - (void)hudWasHidden:(MBProgressHUD *)hud; 320 | 321 | @end 322 | 323 | 324 | /** 325 | * A progress view for showing definite progress by filling up a circle (pie chart). 326 | */ 327 | @interface MBRoundProgressView : UIView 328 | 329 | /** 330 | * Progress (0.0 to 1.0) 331 | */ 332 | @property (nonatomic, assign) float progress; 333 | 334 | /** 335 | * Indicator progress color. 336 | * Defaults to white [UIColor whiteColor]. 337 | */ 338 | @property (nonatomic, strong) UIColor *progressTintColor; 339 | 340 | /** 341 | * Indicator background (non-progress) color. 342 | * Only applicable on iOS versions older than iOS 7. 343 | * Defaults to translucent white (alpha 0.1). 344 | */ 345 | @property (nonatomic, strong) UIColor *backgroundTintColor; 346 | 347 | /* 348 | * Display mode - NO = round or YES = annular. Defaults to round. 349 | */ 350 | @property (nonatomic, assign, getter = isAnnular) BOOL annular; 351 | 352 | @end 353 | 354 | 355 | /** 356 | * A flat bar progress view. 357 | */ 358 | @interface MBBarProgressView : UIView 359 | 360 | /** 361 | * Progress (0.0 to 1.0) 362 | */ 363 | @property (nonatomic, assign) float progress; 364 | 365 | /** 366 | * Bar border line color. 367 | * Defaults to white [UIColor whiteColor]. 368 | */ 369 | @property (nonatomic, strong) UIColor *lineColor; 370 | 371 | /** 372 | * Bar background color. 373 | * Defaults to clear [UIColor clearColor]; 374 | */ 375 | @property (nonatomic, strong) UIColor *progressRemainingColor; 376 | 377 | /** 378 | * Bar progress color. 379 | * Defaults to white [UIColor whiteColor]. 380 | */ 381 | @property (nonatomic, strong) UIColor *progressColor; 382 | 383 | @end 384 | 385 | 386 | @interface MBBackgroundView : UIView 387 | 388 | /** 389 | * The background style. 390 | * Defaults to MBProgressHUDBackgroundStyleBlur. 391 | */ 392 | @property (nonatomic) MBProgressHUDBackgroundStyle style; 393 | 394 | /** 395 | * The blur effect style, when using MBProgressHUDBackgroundStyleBlur. 396 | * Defaults to UIBlurEffectStyleLight. 397 | */ 398 | @property (nonatomic) UIBlurEffectStyle blurEffectStyle; 399 | 400 | /** 401 | * The background color or the blur tint color. 402 | * 403 | * Defaults to nil on iOS 13 and later and 404 | * `[UIColor colorWithWhite:0.8f alpha:0.6f]` 405 | * on older systems. 406 | */ 407 | @property (nonatomic, strong, nullable) UIColor *color; 408 | 409 | @end 410 | 411 | NS_ASSUME_NONNULL_END 412 | -------------------------------------------------------------------------------- /Bootstrap/MBProgressHUD.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/MBProgressHUD.framework/Info.plist -------------------------------------------------------------------------------- /Bootstrap/MBProgressHUD.framework/MBProgressHUD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/MBProgressHUD.framework/MBProgressHUD -------------------------------------------------------------------------------- /Bootstrap/MBProgressHUD.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module MBProgressHUD { 2 | umbrella header "MBProgressHUD.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Bootstrap/NSUserDefaults+appDefaults.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface NSUserDefaults (appDefaults) 6 | +(NSUserDefaults*)appDefaults; 7 | @end 8 | 9 | NS_ASSUME_NONNULL_END 10 | -------------------------------------------------------------------------------- /Bootstrap/NSUserDefaults+appDefaults.m: -------------------------------------------------------------------------------- 1 | #import "NSUserDefaults+appDefaults.h" 2 | #include "common.h" 3 | 4 | @interface MCMContainer : NSObject 5 | - (NSURL *)url; 6 | + (instancetype)containerWithIdentifier:(NSString *)identifier 7 | createIfNecessary:(BOOL)createIfNecessary 8 | existed:(BOOL *)existed 9 | error:(NSError **)error; 10 | @end 11 | 12 | @interface MCMAppDataContainer : MCMContainer 13 | @end 14 | 15 | @implementation NSUserDefaults (appDefaults) 16 | 17 | static NSUserDefaults* _appDefaults=nil; 18 | 19 | //+(NSUserDefaults*)appDefaults { 20 | // static dispatch_once_t once; 21 | // dispatch_once (&once, ^{ 22 | // /* initWithSuiteName does not accept AppBundleIdentifier as SuiteName, and preferences cannot be shared between processes with different uid. */ 23 | // _appDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.roothide.Bootstrap.shared"]; 24 | // [_appDefaults registerDefaults:@{}]; 25 | // }); 26 | // return _appDefaults; 27 | //} 28 | 29 | +(NSUserDefaults*)appDefaults { 30 | static dispatch_once_t once; 31 | dispatch_once (&once, ^{ 32 | MCMAppDataContainer* container = [MCMAppDataContainer containerWithIdentifier:NSBundle.mainBundle.bundleIdentifier createIfNecessary:YES existed:nil error:nil]; 33 | NSString* path = [NSString stringWithFormat:@"%@/Library/Preferences/%@.plist", container.url.path, NSBundle.mainBundle.bundleIdentifier]; 34 | SYSLOG("appDefaults=%@", path); 35 | _appDefaults = [[NSUserDefaults alloc] initWithSuiteName:path]; 36 | [_appDefaults registerDefaults:@{}]; 37 | }); 38 | return _appDefaults; 39 | } 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Bootstrap/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface SceneDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow * window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /Bootstrap/SceneDelegate.m: -------------------------------------------------------------------------------- 1 | #import "SceneDelegate.h" 2 | 3 | @interface SceneDelegate () 4 | 5 | @end 6 | 7 | @implementation SceneDelegate 8 | 9 | 10 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 11 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 12 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 13 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 14 | } 15 | 16 | 17 | - (void)sceneDidDisconnect:(UIScene *)scene { 18 | // Called as the scene is being released by the system. 19 | // This occurs shortly after the scene enters the background, or when its session is discarded. 20 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 21 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 22 | } 23 | 24 | 25 | - (void)sceneDidBecomeActive:(UIScene *)scene { 26 | // Called when the scene has moved from an inactive state to an active state. 27 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 28 | } 29 | 30 | 31 | - (void)sceneWillResignActive:(UIScene *)scene { 32 | // Called when the scene will move from an active state to an inactive state. 33 | // This may occur due to temporary interruptions (ex. an incoming phone call). 34 | } 35 | 36 | 37 | - (void)sceneWillEnterForeground:(UIScene *)scene { 38 | // Called as the scene transitions from the background to the foreground. 39 | // Use this method to undo the changes made on entering the background. 40 | } 41 | 42 | 43 | - (void)sceneDidEnterBackground:(UIScene *)scene { 44 | // Called as the scene transitions from the foreground to the background. 45 | // Use this method to save data, release shared resources, and store enough scene-specific state information 46 | // to restore the scene back to its current state. 47 | } 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Bootstrap/ViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface ViewController : UIViewController 4 | 5 | 6 | @end 7 | 8 | -------------------------------------------------------------------------------- /Bootstrap/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | #include "NSUserDefaults+appDefaults.h" 3 | #include "common.h" 4 | #include "AppDelegate.h" 5 | #include "AppViewController.h" 6 | #include "bootstrap.h" 7 | #include "credits.h" 8 | #include "AppList.h" 9 | #import 10 | #include 11 | 12 | #include 13 | #include 14 | typedef struct CF_BRIDGED_TYPE(id) __SecCode const* SecStaticCodeRef; /* code on disk */ 15 | typedef enum { kSecCSDefaultFlags=0, kSecCSSigningInformation = 1 << 1 } SecCSFlags; 16 | OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes, SecStaticCodeRef* CF_RETURNS_RETAINED staticCode); 17 | OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags, CFDictionaryRef* __nonnull CF_RETURNS_RETAINED information); 18 | 19 | 20 | @interface ViewController () 21 | @property (weak, nonatomic) IBOutlet UITextView *logView; 22 | @property (weak, nonatomic) IBOutlet UIButton *bootstraBtn; 23 | @property (weak, nonatomic) IBOutlet UIButton *unbootstrapBtn; 24 | @property (weak, nonatomic) IBOutlet UISwitch *opensshState; 25 | @property (weak, nonatomic) IBOutlet UIButton *appEnablerBtn; 26 | @property (weak, nonatomic) IBOutlet UIButton *respringBtn; 27 | @property (weak, nonatomic) IBOutlet UIButton *uninstallBtn; 28 | @property (weak, nonatomic) IBOutlet UIButton *rebuildappsBtn; 29 | @property (weak, nonatomic) IBOutlet UIButton *rebuildIconCacheBtn; 30 | @property (weak, nonatomic) IBOutlet UIButton *reinstallPackageManagerBtn; 31 | @property (weak, nonatomic) IBOutlet UILabel *opensshLabel; 32 | 33 | @end 34 | 35 | @implementation ViewController 36 | 37 | - (BOOL)checkTSVersion { 38 | 39 | CFURLRef binaryURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)NSBundle.mainBundle.executablePath, kCFURLPOSIXPathStyle, false); 40 | if(binaryURL == NULL) return NO; 41 | 42 | SecStaticCodeRef codeRef = NULL; 43 | OSStatus result = SecStaticCodeCreateWithPathAndAttributes(binaryURL, kSecCSDefaultFlags, NULL, &codeRef); 44 | if(result != errSecSuccess) return NO; 45 | 46 | CFDictionaryRef signingInfo = NULL; 47 | result = SecCodeCopySigningInformation(codeRef, kSecCSSigningInformation, &signingInfo); 48 | if(result != errSecSuccess) return NO; 49 | 50 | NSString* teamID = (NSString*)CFDictionaryGetValue(signingInfo, CFSTR("teamid")); 51 | SYSLOG("teamID in trollstore: %@", teamID); 52 | 53 | return [teamID isEqualToString:@"T8ALTGMVXN"]; 54 | } 55 | 56 | - (void)viewDidLoad { 57 | [super viewDidLoad]; 58 | // Do any additional setup after loading the view. 59 | 60 | self.logView.text = nil; 61 | self.logView.layer.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.01].CGColor; 62 | self.logView.layer.borderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.01].CGColor; 63 | self.logView.layer.borderWidth = 1.0; 64 | self.logView.layer.cornerRadius = 5.0; 65 | 66 | [AppDelegate registerLogView:self.logView]; 67 | 68 | if(isSystemBootstrapped()) 69 | { 70 | self.bootstraBtn.enabled = NO; 71 | [self.bootstraBtn setTitle:Localized(@"Bootstrapped") forState:UIControlStateDisabled]; 72 | 73 | self.respringBtn.enabled = YES; 74 | self.appEnablerBtn.enabled = YES; 75 | self.rebuildappsBtn.enabled = YES; 76 | self.rebuildIconCacheBtn.enabled = YES; 77 | self.reinstallPackageManagerBtn.enabled = YES; 78 | self.uninstallBtn.enabled = NO; 79 | self.uninstallBtn.hidden = NO; 80 | 81 | if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/basebin/.rebuildiconcache")]) { 82 | [NSFileManager.defaultManager removeItemAtPath:jbroot(@"/basebin/.rebuildiconcache") error:nil]; 83 | 84 | [AppDelegate showHudMsg:Localized(@"Rebuilding")]; 85 | } 86 | 87 | if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/basebin/.launchctl_support")]) { 88 | self.opensshState.hidden = YES; 89 | self.opensshLabel.hidden = YES; 90 | } 91 | } 92 | else if(isBootstrapInstalled()) 93 | { 94 | 95 | self.bootstraBtn.enabled = YES; 96 | [self.bootstraBtn setTitle:Localized(@"Bootstrap") forState:UIControlStateNormal]; 97 | 98 | self.respringBtn.enabled = NO; 99 | self.appEnablerBtn.enabled = NO; 100 | self.rebuildappsBtn.enabled = NO; 101 | self.rebuildIconCacheBtn.enabled = NO; 102 | self.reinstallPackageManagerBtn.enabled = NO; 103 | self.uninstallBtn.hidden = NO; 104 | } 105 | else if(NSProcessInfo.processInfo.operatingSystemVersion.majorVersion>=15) 106 | { 107 | self.bootstraBtn.enabled = YES; 108 | [self.bootstraBtn setTitle:Localized(@"Install") forState:UIControlStateNormal]; 109 | 110 | self.respringBtn.enabled = NO; 111 | self.appEnablerBtn.enabled = NO; 112 | self.rebuildappsBtn.enabled = NO; 113 | self.rebuildIconCacheBtn.enabled = NO; 114 | self.reinstallPackageManagerBtn.enabled = NO; 115 | self.uninstallBtn.hidden = YES; 116 | } else { 117 | self.bootstraBtn.enabled = NO; 118 | [self.bootstraBtn setTitle:Localized(@"Unsupported") forState:UIControlStateDisabled]; 119 | 120 | self.respringBtn.enabled = NO; 121 | self.appEnablerBtn.enabled = NO; 122 | self.rebuildappsBtn.enabled = NO; 123 | self.rebuildIconCacheBtn.enabled = NO; 124 | self.reinstallPackageManagerBtn.enabled = NO; 125 | self.uninstallBtn.hidden = YES; 126 | 127 | [AppDelegate showMesage:Localized(@"the current ios version is not supported yet, we may add support in a future version.") title:Localized(@"Unsupported")]; 128 | } 129 | 130 | 131 | [AppDelegate addLogText:[NSString stringWithFormat:@"ios-version: %@",UIDevice.currentDevice.systemVersion]]; 132 | 133 | struct utsname systemInfo; 134 | uname(&systemInfo); 135 | [AppDelegate addLogText:[NSString stringWithFormat:@"device-model: %s",systemInfo.machine]]; 136 | 137 | [AppDelegate addLogText:[NSString stringWithFormat:@"app-version: %@/%@",NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"],NSBundle.mainBundle.infoDictionary[@"CFBundleShortVersionString"]]]; 138 | 139 | [AppDelegate addLogText:[NSString stringWithFormat:@"boot-session: %@",getBootSession()]]; 140 | 141 | [AppDelegate addLogText: isBootstrapInstalled()? @"bootstrap installed":@"bootstrap not installed"]; 142 | [AppDelegate addLogText: isSystemBootstrapped()? @"system bootstrapped":@"system not bootstrapped"]; 143 | 144 | if(!isBootstrapInstalled()) dispatch_async(dispatch_get_global_queue(0, 0), ^{ 145 | usleep(1000*500); 146 | [AppDelegate addLogText:@"\n:::Credits:::\n"]; 147 | usleep(1000*500); 148 | for(NSString* name in CREDITS) { 149 | usleep(1000*50); 150 | [AppDelegate addLogText:[NSString stringWithFormat:@"%@ - %@\n",name,CREDITS[name]]]; 151 | } 152 | sleep(1); 153 | [AppDelegate addLogText:Localized(@"\nthanks to these guys, we couldn't have completed this project without their help!")]; 154 | 155 | }); 156 | 157 | SYSLOG("locale=%@", NSLocale.currentLocale.countryCode); 158 | SYSLOG("locale=%@", [NSUserDefaults.appDefaults valueForKey:@"locale"]); 159 | [NSUserDefaults.appDefaults setValue:NSLocale.currentLocale.countryCode forKey:@"locale"]; 160 | [NSUserDefaults.appDefaults synchronize]; 161 | SYSLOG("locale=%@", [NSUserDefaults.appDefaults valueForKey:@"locale"]); 162 | 163 | if(isSystemBootstrapped()) 164 | { 165 | [self checkServer]; 166 | 167 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkServer) 168 | name:UIApplicationWillEnterForegroundNotification object:nil]; 169 | } 170 | } 171 | 172 | -(void)checkServer 173 | { 174 | static bool alerted = false; 175 | if(alerted) return; 176 | 177 | if(spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"check"], nil, nil) != 0) 178 | { 179 | alerted = true; 180 | 181 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:Localized(@"Server Not Running") message:Localized(@"for unknown reasons the bootstrap server is not running, the only thing we can do is to restart it now.") preferredStyle:UIAlertControllerStyleAlert]; 182 | [alert addAction:[UIAlertAction actionWithTitle:Localized(@"Restart Server") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ 183 | 184 | alerted = false; 185 | 186 | NSString* log=nil; 187 | NSString* err=nil; 188 | if(spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"daemon",@"-f"], &log, &err)==0) { 189 | [AppDelegate addLogText:Localized(@"bootstrap server restart successful")]; 190 | [self updateOpensshStatus]; 191 | } else { 192 | [AppDelegate showMesage:[NSString stringWithFormat:@"%@\nERR:%@"] title:Localized(@"Error")]; 193 | } 194 | 195 | }]]; 196 | 197 | [AppDelegate showAlert:alert]; 198 | } else { 199 | [AppDelegate addLogText:Localized(@"bootstrap server check successful")]; 200 | [self updateOpensshStatus]; 201 | } 202 | } 203 | 204 | -(void)updateOpensshStatus { 205 | dispatch_async(dispatch_get_main_queue(), ^{ 206 | if(isSystemBootstrapped()) { 207 | self.opensshState.on = spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"openssh",@"check"], nil, nil)==0; 208 | } else { 209 | self.opensshState.on = [NSUserDefaults.appDefaults boolForKey:@"openssh"]; 210 | } 211 | }); 212 | } 213 | 214 | - (IBAction)respring:(id)sender { 215 | 216 | NSString* log=nil; 217 | NSString* err=nil; 218 | int status = spawnBootstrap((char*[]){"/usr/bin/sbreload", NULL}, &log, &err); 219 | if(status!=0) [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 220 | } 221 | 222 | - (IBAction)rebuildapps:(id)sender { 223 | [AppDelegate addLogText:@"Status: Rebuilding Apps"]; 224 | 225 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 226 | [AppDelegate showHudMsg:Localized(@"Applying")]; 227 | 228 | NSString* log=nil; 229 | NSString* err=nil; 230 | int status = spawnBootstrap((char*[]){"/bin/sh", "/basebin/rebuildapps.sh", NULL}, nil, nil); 231 | if(status==0) { 232 | killAllForApp("/usr/libexec/backboardd"); 233 | } else { 234 | [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 235 | } 236 | [AppDelegate dismissHud]; 237 | }); 238 | } 239 | 240 | - (IBAction)reinstallPackageManager:(id)sender { 241 | 242 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 243 | [AppDelegate showHudMsg:Localized(@"Applying")]; 244 | 245 | NSString* log=nil; 246 | NSString* err=nil; 247 | 248 | BOOL success=YES; 249 | 250 | [AppDelegate addLogText:@"Status: Reinstalling Sileo"]; 251 | NSString* sileoDeb = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"sileo.deb"]; 252 | if(spawnBootstrap((char*[]){"/usr/bin/dpkg", "-i", rootfsPrefix(sileoDeb).fileSystemRepresentation, NULL}, &log, &err) != 0) { 253 | [AppDelegate addLogText:[NSString stringWithFormat:@"failed:%@\nERR:%@", log, err]]; 254 | success = NO; 255 | } 256 | 257 | if(spawnBootstrap((char*[]){"/usr/bin/uicache", "-p", "/Applications/Sileo.app", NULL}, &log, &err) != 0) { 258 | [AppDelegate addLogText:[NSString stringWithFormat:@"failed:%@\nERR:%@", log, err]]; 259 | success = NO; 260 | } 261 | 262 | [AppDelegate addLogText:@"Status: Reinstalling Zebra"]; 263 | NSString* zebraDeb = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"zebra.deb"]; 264 | if(spawnBootstrap((char*[]){"/usr/bin/dpkg", "-i", rootfsPrefix(zebraDeb).fileSystemRepresentation, NULL}, nil, nil) != 0) { 265 | [AppDelegate addLogText:[NSString stringWithFormat:@"failed:%@\nERR:%@", log, err]]; 266 | success = NO; 267 | } 268 | 269 | if(spawnBootstrap((char*[]){"/usr/bin/uicache", "-p", "/Applications/Zebra.app", NULL}, &log, &err) != 0) { 270 | [AppDelegate addLogText:[NSString stringWithFormat:@"failed:%@\nERR:%@", log, err]]; 271 | success = NO; 272 | } 273 | 274 | if(success) { 275 | [AppDelegate showMesage:@"Sileo and Zebra reinstalled!" title:@""]; 276 | } 277 | [AppDelegate dismissHud]; 278 | }); 279 | } 280 | 281 | int rebuildIconCache() 282 | { 283 | AppList* tsapp = [AppList appWithBundleIdentifier:@"com.opa334.TrollStore"]; 284 | if(!tsapp) { 285 | STRAPLOG("trollstore not found!"); 286 | return -1; 287 | } 288 | 289 | STRAPLOG("rebuild icon cache..."); 290 | ASSERT([LSApplicationWorkspace.defaultWorkspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES]); 291 | 292 | NSString* log=nil; 293 | NSString* err=nil; 294 | 295 | if(spawnRoot([tsapp.bundleURL.path stringByAppendingPathComponent:@"trollstorehelper"], @[@"refresh"], &log, &err) != 0) { 296 | STRAPLOG("refresh tsapps failed:%@\nERR:%@", log, err); 297 | return -1; 298 | } 299 | 300 | [[NSString new] writeToFile:jbroot(@"/basebin/.rebuildiconcache") atomically:YES encoding:NSUTF8StringEncoding error:nil]; 301 | [LSApplicationWorkspace.defaultWorkspace openApplicationWithBundleID:NSBundle.mainBundle.bundleIdentifier]; 302 | 303 | int status = spawnBootstrap((char*[]){"/bin/sh", "/basebin/rebuildapps.sh", NULL}, &log, &err); 304 | if(status==0) { 305 | killAllForApp("/usr/libexec/backboardd"); 306 | } else { 307 | STRAPLOG("rebuildapps failed:%@\nERR:\n%@",log,err); 308 | } 309 | 310 | if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/basebin/.rebuildiconcache")]) { 311 | [NSFileManager.defaultManager removeItemAtPath:jbroot(@"/basebin/.rebuildiconcache") error:nil]; 312 | } 313 | 314 | return status; 315 | } 316 | 317 | - (IBAction)rebuildIconCache:(id)sender { 318 | [AppDelegate addLogText:@"Status: Rebuilding Icon Cache"]; 319 | 320 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 321 | [AppDelegate showHudMsg:Localized(@"Rebuilding") detail:Localized(@"Don't exit Bootstrap app until show the lock screen.")]; 322 | 323 | NSString* log=nil; 324 | NSString* err=nil; 325 | int status = spawnRoot(NSBundle.mainBundle.executablePath, @[@"rebuildiconcache"], &log, &err); 326 | if(status != 0) { 327 | [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 328 | } 329 | 330 | [AppDelegate dismissHud]; 331 | }); 332 | } 333 | 334 | - (IBAction)appenabler:(id)sender { 335 | 336 | AppViewController *vc = [[AppViewController alloc] init]; 337 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc]; 338 | [self presentViewController:navigationController animated:YES completion:^{}]; 339 | } 340 | 341 | - (IBAction)openssh:(id)sender { 342 | UISwitch* enabled = (UISwitch*)sender; 343 | 344 | if(!isSystemBootstrapped()) { 345 | [NSUserDefaults.appDefaults setValue:@(enabled.on) forKey:@"openssh"]; 346 | [NSUserDefaults.appDefaults synchronize]; 347 | return; 348 | } 349 | 350 | if(![NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/usr/libexec/sshd-keygen-wrapper")]) { 351 | [AppDelegate showMesage:Localized(@"openssh package is not installed") title:Localized(@"Developer")]; 352 | enabled.on = NO; 353 | return; 354 | } 355 | 356 | NSString* log=nil; 357 | NSString* err=nil; 358 | int status = spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"openssh",enabled.on?@"start":@"stop"], &log, &err); 359 | 360 | //try 361 | if(!enabled.on) spawnBootstrap((char*[]){"/usr/bin/killall","-9","sshd",NULL}, nil, nil); 362 | 363 | if(status==0) 364 | { 365 | [NSUserDefaults.appDefaults setValue:@(enabled.on) forKey:@"openssh"]; 366 | [NSUserDefaults.appDefaults synchronize]; 367 | } 368 | else 369 | { 370 | [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 371 | if(enabled.on) [enabled setOn:NO]; 372 | } 373 | } 374 | 375 | - (IBAction)bootstrap:(id)sender { 376 | if(![self checkTSVersion]) { 377 | [AppDelegate showMesage:Localized(@"Your trollstore version is too old, Bootstrap only supports trollstore>=2.0") title:Localized(@"Error")]; 378 | return; 379 | } 380 | 381 | if(spawnRoot([NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"basebin/devtest"], nil, nil, nil) != 0) { 382 | [AppDelegate showMesage:Localized(@"Your device does not seem to have developer mode enabled.\n\nPlease enable developer mode in Settings->[Privacy&Security] and reboot your device.") title:Localized(@"Error")]; 383 | return; 384 | } 385 | 386 | UIImpactFeedbackGenerator* generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleSoft]; 387 | generator.impactOccurred; 388 | 389 | if(find_jbroot()) //make sure jbroot() function available 390 | { 391 | if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/.installed_dopamine")]) { 392 | [AppDelegate showMesage:Localized(@"roothide dopamine has been installed on this device, now install this bootstrap may break it!") title:Localized(@"Error")]; 393 | return; 394 | } 395 | 396 | if([NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/.bootstrapped")]) { 397 | NSString* strappedVersion = [NSString stringWithContentsOfFile:jbroot(@"/.bootstrapped") encoding:NSUTF8StringEncoding error:nil]; 398 | if(strappedVersion.intValue != BOOTSTRAP_VERSION) { 399 | [AppDelegate showMesage:Localized(@"You have installed an old beta version, please disable all app tweaks and reboot the device to uninstall it so that you can install the new version bootstrap.") title:Localized(@"Error")]; 400 | return; 401 | } 402 | } 403 | } 404 | 405 | [(UIButton*)sender setEnabled:NO]; 406 | 407 | [AppDelegate showHudMsg:Localized(@"Bootstrapping")]; 408 | 409 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 410 | 411 | const char* argv[] = {NSBundle.mainBundle.executablePath.fileSystemRepresentation, "bootstrap", NULL}; 412 | int status = spawn(argv[0], argv, environ, ^(char* outstr){ 413 | [AppDelegate addLogText:@(outstr)]; 414 | }, ^(char* errstr){ 415 | [AppDelegate addLogText:[NSString stringWithFormat:@"ERR: %s\n",errstr]]; 416 | }); 417 | 418 | [AppDelegate dismissHud]; 419 | 420 | if(status != 0) 421 | { 422 | [AppDelegate showMesage:@"" title:[NSString stringWithFormat:@"code(%d)",status]]; 423 | return; 424 | } 425 | 426 | NSString* log=nil; 427 | NSString* err=nil; 428 | 429 | if([NSUserDefaults.appDefaults boolForKey:@"openssh"] && [NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/usr/libexec/sshd-keygen-wrapper")]) 430 | { 431 | NSString* log=nil; 432 | NSString* err=nil; 433 | status = spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"openssh",@"start"], &log, &err); 434 | if(status==0) 435 | [AppDelegate addLogText:@"openssh launch successful"]; 436 | else 437 | [AppDelegate addLogText:[NSString stringWithFormat:@"openssh launch faild(%d):\n%@\n%@", status, log, err]]; 438 | } 439 | 440 | [AppDelegate addLogText:@"respring now..."]; sleep(1); 441 | 442 | status = spawnBootstrap((char*[]){"/usr/bin/sbreload", NULL}, &log, &err); 443 | if(status!=0) [AppDelegate showMesage:[NSString stringWithFormat:@"%@\n\nstderr:\n%@",log,err] title:[NSString stringWithFormat:@"code(%d)",status]]; 444 | 445 | }); 446 | } 447 | 448 | - (IBAction)unbootstrap:(id)sender { 449 | 450 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:Localized(@"Warnning") message:Localized(@"Are you sure to uninstall bootstrap?\n\nPlease make sure you have disabled tweak for all apps before uninstalling.") preferredStyle:UIAlertControllerStyleAlert]; 451 | [alert addAction:[UIAlertAction actionWithTitle:Localized(@"Cancel") style:UIAlertActionStyleDefault handler:nil]]; 452 | [alert addAction:[UIAlertAction actionWithTitle:Localized(@"Uninstall") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){ 453 | 454 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 455 | [AppDelegate showHudMsg:Localized(@"Uninstalling")]; 456 | 457 | NSString* log=nil; 458 | NSString* err=nil; 459 | int status = spawnRoot(NSBundle.mainBundle.executablePath, @[@"unbootstrap"], &log, &err); 460 | 461 | [AppDelegate dismissHud]; 462 | 463 | NSString* msg = (status==0) ? @"bootstrap uninstalled" : [NSString stringWithFormat:@"code(%d)\n%@\n\nstderr:\n%@",status,log,err]; 464 | 465 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:msg preferredStyle:UIAlertControllerStyleAlert]; 466 | [alert addAction:[UIAlertAction actionWithTitle:Localized(@"OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ 467 | exit(0); 468 | }]]; 469 | 470 | [AppDelegate showAlert:alert]; 471 | 472 | }); 473 | 474 | }]]; 475 | [AppDelegate showAlert:alert]; 476 | 477 | } 478 | 479 | 480 | @end 481 | -------------------------------------------------------------------------------- /Bootstrap/basebin/bootstrap.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/bootstrap.dylib -------------------------------------------------------------------------------- /Bootstrap/basebin/bootstrap.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | platform-application 14 | 15 | get-task-allow 16 | 17 | com.apple.private.persona-mgmt 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Bootstrap/basebin/bootstrapd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/bootstrapd -------------------------------------------------------------------------------- /Bootstrap/basebin/devtest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/devtest -------------------------------------------------------------------------------- /Bootstrap/basebin/entitlements/com.apple.mobilesafari.extra: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | 10 | com.apple.private.security.no-sandbox 11 | 12 | com.apple.private.security.storage.AppBundles 13 | 14 | com.apple.private.security.storage.AppDataContainers 15 | 16 | com.apple.security.iokit-user-client-class 17 | 18 | IOUserClient 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Bootstrap/basebin/entitlements/com.apple.mobilesafari.strip: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.private.security.container-required 6 | 7 | 8 | -------------------------------------------------------------------------------- /Bootstrap/basebin/entitlements/com.apple.mobileslideshow.extra: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | com.apple.private.security.storage.AppDataContainers 10 | 11 | com.apple.private.security.no-sandbox 12 | 13 | 14 | com.apple.security.exception.process-info 15 | 16 | com.apple.security.temporary-exception.process-info 17 | 18 | com.apple.security.exception.sysctl.read-write 19 | 20 | com.apple.private.security.storage.AppBundles 21 | 22 | com.apple.security.exception.mobile-preferences-read-write 23 | 24 | user-preference-write 25 | 26 | seatbelt-profiles 27 | 28 | com.apple.security.iokit-user-client-class 29 | 30 | IOUserClient 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Bootstrap/basebin/entitlements/com.apple.mobileslideshow.photo-picker.extra: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | com.apple.private.security.storage.AppDataContainers 10 | 11 | com.apple.private.security.no-sandbox 12 | 13 | 14 | com.apple.security.exception.process-info 15 | 16 | com.apple.security.temporary-exception.process-info 17 | 18 | com.apple.security.exception.sysctl.read-write 19 | 20 | com.apple.private.security.storage.AppBundles 21 | 22 | com.apple.security.exception.mobile-preferences-read-write 23 | 24 | user-preference-write 25 | 26 | seatbelt-profiles 27 | 28 | com.apple.security.iokit-user-client-class 29 | 30 | IOUserClient 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Bootstrap/basebin/fastPathSign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/fastPathSign -------------------------------------------------------------------------------- /Bootstrap/basebin/ldid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/ldid -------------------------------------------------------------------------------- /Bootstrap/basebin/nickchan.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | get-task-allow 8 | 9 | com.apple.private.persona-mgmt 10 | 11 | 12 | 16 | com.apple.private.security.storage.adprivacyd 17 | 18 | com.apple.private.security.storage.amfid 19 | 20 | com.apple.private.security.storage.AppBundles 21 | 22 | com.apple.private.security.storage.AppDataContainers 23 | 24 | com.apple.private.security.storage.automation-mode 25 | 26 | com.apple.private.security.storage.Biome 27 | 28 | com.apple.private.security.storage.Calendar 29 | 30 | com.apple.private.security.storage.CallHistory 31 | 32 | com.apple.private.security.storage.CarrierBundles 33 | 34 | com.apple.private.security.storage.chronod 35 | 36 | com.apple.private.security.storage.CloudDocsDB 37 | 38 | com.apple.private.security.storage.CloudKit 39 | 40 | com.apple.private.security.storage.containers 41 | 42 | com.apple.private.security.storage.CoreFollowUp 43 | 44 | com.apple.private.security.storage.CoreKnowledge 45 | 46 | com.apple.private.security.storage.Cryptex 47 | 48 | com.apple.private.security.storage.demo_backup 49 | 50 | com.apple.private.security.storage.DocumentRevisions 51 | 52 | com.apple.private.security.storage.DumpPanic 53 | 54 | com.apple.private.security.storage.ExposureNotification 55 | 56 | com.apple.private.security.storage.FaceTime 57 | 58 | com.apple.private.security.storage.familycircled 59 | 60 | com.apple.private.security.storage.FindMy 61 | 62 | com.apple.private.security.storage.fpsd 63 | 64 | com.apple.private.security.storage.Health 65 | 66 | com.apple.private.security.storage.HomeAI 67 | 68 | com.apple.private.security.storage.HomeKit 69 | 70 | com.apple.private.security.storage.iCloudDrive 71 | 72 | com.apple.private.security.storage.idcredd 73 | 74 | com.apple.private.security.storage.IdentityServices 75 | 76 | com.apple.private.security.storage.kbd 77 | 78 | com.apple.private.security.storage.Keychains 79 | 80 | com.apple.private.security.storage.Lockdown 81 | 82 | com.apple.private.security.storage.Mail 83 | 84 | com.apple.private.security.storage.Messages 85 | 86 | com.apple.private.security.storage.MessagesMetaData 87 | 88 | com.apple.private.security.storage.MobileContainerManager 89 | 90 | com.apple.private.security.storage.MobileDocuments 91 | 92 | com.apple.private.security.storage.MobileIdentityService 93 | 94 | com.apple.private.security.storage.mobilesync 95 | 96 | com.apple.private.security.storage.multimodalsearchd 97 | 98 | com.apple.private.security.storage.NanoTimeKit.FaceSupport 99 | 100 | com.apple.private.security.storage.News 101 | 102 | com.apple.private.security.storage.Notes 103 | 104 | com.apple.private.security.storage.Photos 105 | 106 | com.apple.private.security.storage.PhotosLibraries 107 | 108 | com.apple.private.security.storage.pipelined 109 | 110 | com.apple.private.security.storage.preferences 111 | 112 | com.apple.private.security.storage.PrivacyAccounting 113 | 114 | com.apple.private.security.storage.Safari 115 | 116 | com.apple.private.security.storage.SearchParty 117 | 118 | com.apple.private.security.storage.SecureElementService 119 | 120 | com.apple.private.security.storage.SensorKit 121 | 122 | com.apple.private.security.storage.SFAnalytics 123 | 124 | com.apple.private.security.storage.SiriInference 125 | 126 | com.apple.private.security.storage.SiriReferenceResolution 127 | 128 | com.apple.private.security.storage.SiriVocabulary 129 | 130 | com.apple.private.security.storage.SoC 131 | 132 | com.apple.private.security.storage.SpeechPersonalizedLM 133 | 134 | com.apple.private.security.storage.Spotlight 135 | 136 | com.apple.private.security.storage.StatusKit 137 | 138 | com.apple.private.security.storage.Stocks 139 | 140 | com.apple.private.security.storage.Suggestions 141 | 142 | com.apple.private.security.storage.SymptomFramework 143 | 144 | com.apple.private.security.storage.sysdagnose.ScreenshotServicesService 145 | 146 | com.apple.private.security.storage.TCC 147 | 148 | com.apple.private.security.storage.TimeMachine 149 | 150 | com.apple.private.security.storage.triald 151 | 152 | com.apple.private.security.storage.trustd 153 | 154 | com.apple.private.security.storage.trustd-private 155 | 156 | com.apple.private.security.storage.universalaccess 157 | 158 | com.apple.private.security.storage.Voicemail 159 | 160 | com.apple.private.security.storage.Wireless 161 | 162 | com.apple.private.security.disk-device-access 163 | 164 | com.apple.rootless.storage.ane_model_cache 165 | 166 | com.apple.rootless.storage.apfs_boot_mount 167 | 168 | com.apple.rootless.storage.clientScripter 169 | 170 | com.apple.rootless.storage.com.apple.mediaanalysisd 171 | 172 | com.apple.rootless.storage.com.apple.MobileAsset.CarPlayAppBlacklist 173 | 174 | com.apple.rootless.storage.com.apple.MobileAsset.DeviceCheck 175 | 176 | com.apple.rootless.storage.com.apple.MobileAsset.DictionaryServices.dictionary2 177 | 178 | com.apple.rootless.storage.com.apple.MobileAsset.DuetExpertCenterAsset 179 | 180 | com.apple.rootless.storage.com.apple.MobileAsset.EmbeddedNL 181 | 182 | com.apple.rootless.storage.com.apple.MobileAsset.Font5 183 | 184 | com.apple.rootless.storage.com.apple.MobileAsset.Font6 185 | 186 | com.apple.rootless.storage.com.apple.MobileAsset.HealthKt.FeatureAvailability 187 | 188 | com.apple.rootless.storage.com.apple.MobileAsset.HomeKit 189 | 190 | com.apple.rootless.storage.com.apple.MobileAsset.MacinTalkVoiceAssets 191 | 192 | com.apple.rootless.storage.com.apple.MobileAsset.MailDynamicData 193 | 194 | com.apple.rootless.storage.com.apple.MobileAsset.MXLongFormVideoApps 195 | 196 | com.apple.rootless.storage.com.apple.MobileAsset.network.networknomicon 197 | 198 | com.apple.rootless.storage.com.apple.MobileAsset.PKITrustSupplementals 199 | 200 | com.apple.rootless.storage.com.apple.MobileAsset.SharingDeviceAssets 201 | 202 | com.apple.rootless.storage.com.apple.MobileAsset.SiriShortcutsMobileAsset 203 | 204 | com.apple.rootless.storage.com.apple.MobileAsset.TimeZoneUpdate 205 | 206 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices 207 | 208 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.CustomVoice 209 | 210 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.GryphonVoice 211 | 212 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceServicesVocalizerVoice 213 | 214 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.VoiceResources 215 | 216 | com.apple.rootless.storage.com.apple.MobileAsset.VoiceTriggerAssets 217 | 218 | com.apple.rootless.storage.CoreAnalytics 219 | 220 | com.apple.rootless.storage.coreduet_knowledge_store 221 | 222 | com.apple.rootless.storage.coreidvd 223 | 224 | com.apple.rootless.storage.coreknowledge 225 | 226 | com.apple.rootless.storage.CoreRoutine 227 | 228 | com.apple.rootless.storage.CoreSpeech 229 | 230 | com.apple.rootless.storage.dmd 231 | 232 | com.apple.rootless.storage.dprivacyd_storage 233 | 234 | com.apple.rootless.storage.ExtensibleSSO 235 | 236 | com.apple.rootless.storage.facekit 237 | 238 | com.apple.rootless.storage.fpsd 239 | 240 | com.apple.rootless.storage.MobileStorageMounter 241 | 242 | com.apple.rootless.storage.MusicApp 243 | 244 | com.apple.rootless.storage.nsurlsessiond 245 | 246 | com.apple.rootless.storage.pearl-field-diagnostics 247 | 248 | com.apple.rootless.storage.proactivepredictions 249 | 250 | com.apple.rootless.storage.QLThumbnailCache 251 | 252 | com.apple.rootless.storage.remotemanagementd 253 | 254 | com.apple.rootless.storage.RoleAccountStaging 255 | 256 | com.apple.rootless.storage.sensorkit 257 | 258 | com.apple.rootless.storage.shortcuts 259 | 260 | com.apple.rootless.storage.siriremembers 261 | 262 | com.apple.rootless.storage.timezone 263 | 264 | com.apple.rootless.storage.triald 265 | 266 | com.apple.rootless.storage.voiceshortcuts 267 | 268 | com.apple.private.security.storage-exempt.heritable 269 | 270 | com.apple.private.security.storage.AppleMediaServices 271 | 272 | com.apple.private.security.storage.ContactlessReader 273 | 274 | com.apple.private.security.storage.CoreRoutine 275 | 276 | com.apple.private.security.storage.DiagnosticReports 277 | 278 | com.apple.private.security.storage.DiagnosticReports.read-write 279 | 280 | com.apple.private.security.storage.DoNotDisturb 281 | 282 | com.apple.private.security.storage.Home 283 | 284 | com.apple.private.security.storage.IntelligencePlatform 285 | 286 | com.apple.private.security.storage.Location 287 | 288 | com.apple.private.security.storage.ManagedConfiguration 289 | 290 | com.apple.private.security.storage.MapsSync 291 | 292 | com.apple.private.security.storage.MobileBackup 293 | 294 | com.apple.private.security.storage.MobileStorageMounter 295 | 296 | com.apple.private.security.storage.PassKit 297 | 298 | com.apple.private.security.storage.SiriFeatureStore 299 | 300 | com.apple.private.security.storage.SiriSELF 301 | 302 | com.apple.private.security.storage.SoundProfileAsset 303 | 304 | com.apple.private.security.storage.TextUnderstanding 305 | 306 | com.apple.private.security.storage.Weather 307 | 308 | com.apple.private.security.storage.appleaccountd 309 | 310 | com.apple.private.security.storage.ciconia 311 | 312 | com.apple.private.security.storage.clipserviced 313 | 314 | com.apple.private.security.storage.coreduet_knowledge_store 315 | 316 | com.apple.private.security.storage.driverkitd 317 | 318 | com.apple.private.security.storage.geoanalyticsd 319 | 320 | com.apple.private.security.storage.geod 321 | 322 | com.apple.private.security.storage.launchd 323 | 324 | com.apple.private.security.storage.sessionkitd 325 | 326 | com.apple.private.security.storage.sysdiagnose.ScreenshotServicesService 327 | 328 | com.apple.private.security.storage.sysdiagnose.sysdiagnose 329 | 330 | com.apple.private.security.storage.tmp 331 | 332 | com.apple.rootless.critical 333 | 334 | com.apple.rootless.datavault.metadata 335 | 336 | com.apple.rootless.install 337 | 338 | com.apple.rootless.install.heritable 339 | 340 | com.apple.rootless.restricted-block-devices 341 | 342 | com.apple.rootless.storage.MobileAssetDownload 343 | 344 | com.apple.rootless.storage.amsengagementd 345 | 346 | com.apple.rootless.storage.com.apple.MobileAsset.HealthKit.FeatureAvailability 347 | 348 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriDialogAssets 349 | 350 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriExperienceCam 351 | 352 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriFindMyConfigurationFiles 353 | 354 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriInferredHelpfulness 355 | 356 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriTextToSpeech 357 | 358 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrAssistant 359 | 360 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrHammer 361 | 362 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrUaap 363 | 364 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAttentionAssets 365 | 366 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingMorphun 367 | 368 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingNL 369 | 370 | com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingNLOverrides 371 | 372 | com.apple.rootless.storage.coreparsec_feedbacks 373 | 374 | com.apple.rootless.storage.coreparsec_uploadables 375 | 376 | com.apple.rootless.storage.early_boot_mount 377 | 378 | com.apple.rootless.storage.screentime 379 | 380 | com.apple.rootless.volume.ISCRecovery 381 | 382 | com.apple.rootless.volume.Preboot 383 | 384 | com.apple.rootless.volume.Recovery 385 | 386 | com.apple.rootless.volume.Update 387 | 388 | com.apple.rootless.volume.VM 389 | 390 | com.apple.rootless.volume.iSCPreboot 391 | 392 | 393 | 394 | -------------------------------------------------------------------------------- /Bootstrap/basebin/preload: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/preload -------------------------------------------------------------------------------- /Bootstrap/basebin/preload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/preload.dylib -------------------------------------------------------------------------------- /Bootstrap/basebin/rebuildapp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/rebuildapp -------------------------------------------------------------------------------- /Bootstrap/basebin/rebuildapps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ls /Applications/ | while read app; do 4 | echo "--$app--"; 5 | 6 | uicache -p "/Applications/$app" 7 | 8 | done 9 | 10 | ls -d /var/containers/Bundle/Application/*/*.app/.jbroot | while read file; do 11 | bundle=$(dirname "$file") 12 | echo "--$bundle--" 13 | 14 | unlink "$bundle"/.jbroot 15 | ln -s / "$bundle"/.jbroot 16 | 17 | uicache -s -p "$bundle" 18 | done 19 | -------------------------------------------------------------------------------- /Bootstrap/basebin/test.sh: -------------------------------------------------------------------------------- 1 | set jbroot_path $(realpath ..) 2 | export DYLD_INSERT_LIBRARIES=$jbroot_path/basebin/bootstrap.dylib 3 | DYLD_INSERT_LIBRARIES=$jbroot_path/basebin/bootstrap.dylib $jbroot_path/usr/bin/zsh 4 | -------------------------------------------------------------------------------- /Bootstrap/basebin/uicache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/Bootstrap/basebin/uicache -------------------------------------------------------------------------------- /Bootstrap/bootstrap.h: -------------------------------------------------------------------------------- 1 | #ifndef bootstrap_h 2 | #define bootstrap_h 3 | 4 | #define BOOTSTRAP_VERSION (5) 5 | 6 | void rebuildSignature(NSString *directoryPath); 7 | 8 | int bootstrap(); 9 | 10 | int unbootstrap(); 11 | 12 | bool isBootstrapInstalled(); 13 | 14 | bool isSystemBootstrapped(); 15 | 16 | 17 | #endif /* bootstrap_h */ 18 | -------------------------------------------------------------------------------- /Bootstrap/bootstrap.m: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #include 4 | 5 | #include "common.h" 6 | #include "sources.h" 7 | #include "bootstrap.h" 8 | #include "NSUserDefaults+appDefaults.h" 9 | #include "AppList.h" 10 | 11 | extern int decompress_tar_zstd(const char* src_file_path, const char* dst_file_path); 12 | 13 | 14 | int getCFMajorVersion() 15 | { 16 | return ((int)kCFCoreFoundationVersionNumber / 100) * 100; 17 | } 18 | 19 | void rebuildSignature(NSString *directoryPath) 20 | { 21 | int machoCount=0, libCount=0; 22 | 23 | NSString *resolvedPath = [[directoryPath stringByResolvingSymlinksInPath] stringByStandardizingPath]; 24 | NSDirectoryEnumerator *directoryEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:resolvedPath isDirectory:YES] includingPropertiesForKeys:@[NSURLIsSymbolicLinkKey] options:0 errorHandler:nil]; 25 | 26 | NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"basebin/ldid"]; 27 | NSString* fastSignPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"basebin/fastPathSign"]; 28 | NSString* entitlementsPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"basebin/nickchan.entitlements"]; 29 | NSString* ldidEntitlements = [NSString stringWithFormat:@"-S%@", entitlementsPath]; 30 | 31 | for (NSURL *enumURL in directoryEnumerator) { 32 | @autoreleasepool { 33 | NSNumber *isSymlink; 34 | [enumURL getResourceValue:&isSymlink forKey:NSURLIsSymbolicLinkKey error:nil]; 35 | if (isSymlink && ![isSymlink boolValue]) { 36 | 37 | FILE *fp = fopen(enumURL.fileSystemRepresentation, "rb"); 38 | ASSERT(fp != NULL); 39 | 40 | bool ismacho=false, islib=false; 41 | machoGetInfo(fp, &ismacho, &islib); 42 | 43 | if(ismacho) { 44 | 45 | SYSLOG("rebuild %@", enumURL.path); 46 | 47 | machoCount++; 48 | 49 | if(!islib) { 50 | libCount++; 51 | ASSERT(spawnRoot(ldidPath, @[@"-M", ldidEntitlements, enumURL.path], nil, nil) == 0); 52 | } 53 | 54 | ASSERT(spawnRoot(fastSignPath, @[enumURL.path], nil, nil) == 0); 55 | } 56 | 57 | fclose(fp); 58 | 59 | } 60 | } 61 | } 62 | 63 | SYSLOG("rebuild finished! machoCount=%d, libCount=%d", machoCount, libCount); 64 | 65 | } 66 | 67 | int disableRootHideBlacklist() 68 | { 69 | NSString* roothideDir = jbroot(@"/var/mobile/Library/RootHide"); 70 | if(![NSFileManager.defaultManager fileExistsAtPath:roothideDir]) { 71 | NSDictionary* attr = @{NSFilePosixPermissions:@(0755), NSFileOwnerAccountID:@(501), NSFileGroupOwnerAccountID:@(501)}; 72 | ASSERT([NSFileManager.defaultManager createDirectoryAtPath:roothideDir withIntermediateDirectories:YES attributes:attr error:nil]); 73 | } 74 | 75 | ASSERT(chmod(roothideDir.fileSystemRepresentation, 0755)==0); 76 | ASSERT(chown(roothideDir.fileSystemRepresentation, 501, 501)==0); 77 | 78 | NSString *configFilePath = jbroot(@"/var/mobile/Library/RootHide/RootHideConfig.plist"); 79 | NSMutableDictionary* defaults = [NSMutableDictionary dictionaryWithContentsOfFile:configFilePath]; 80 | 81 | if(!defaults) defaults = [[NSMutableDictionary alloc] init]; 82 | [defaults setValue:@YES forKey:@"blacklistDisabled"]; 83 | 84 | ASSERT([defaults writeToFile:configFilePath atomically:YES]); 85 | 86 | return 0; 87 | } 88 | 89 | int buildPackageSources() 90 | { 91 | NSFileManager* fm = NSFileManager.defaultManager; 92 | 93 | ASSERT([[NSString stringWithFormat:@(DEFAULT_SOURCES), getCFMajorVersion()] writeToFile:jbroot(@"/etc/apt/sources.list.d/default.sources") atomically:YES encoding:NSUTF8StringEncoding error:nil]); 94 | 95 | //Users in some regions seem to be unable to access github.io 96 | SYSLOG("locale=%@", [NSUserDefaults.appDefaults valueForKey:@"locale"]); 97 | if([[NSUserDefaults.appDefaults valueForKey:@"locale"] isEqualToString:@"CN"]) { 98 | ASSERT([[NSString stringWithFormat:@(ALT_SOURCES), getCFMajorVersion()] writeToFile:jbroot(@"/etc/apt/sources.list.d/sileo.sources") atomically:YES encoding:NSUTF8StringEncoding error:nil]); 99 | } 100 | 101 | if(![fm fileExistsAtPath:jbroot(@"/var/mobile/Library/Application Support/xyz.willy.Zebra")]) 102 | { 103 | NSDictionary* attr = @{NSFilePosixPermissions:@(0755), NSFileOwnerAccountID:@(501), NSFileGroupOwnerAccountID:@(501)}; 104 | ASSERT([fm createDirectoryAtPath:jbroot(@"/var/mobile/Library/Application Support/xyz.willy.Zebra") withIntermediateDirectories:YES attributes:attr error:nil]); 105 | } 106 | 107 | ASSERT([[NSString stringWithFormat:@(ZEBRA_SOURCES), getCFMajorVersion()] writeToFile:jbroot(@"/var/mobile/Library/Application Support/xyz.willy.Zebra/sources.list") atomically:YES encoding:NSUTF8StringEncoding error:nil]); 108 | 109 | return 0; 110 | } 111 | 112 | int rebuildBasebin() 113 | { 114 | NSFileManager* fm = NSFileManager.defaultManager; 115 | 116 | if([fm fileExistsAtPath:jbroot(@"/basebin")]) { 117 | ASSERT([fm removeItemAtPath:jbroot(@"/basebin") error:nil]); 118 | } 119 | 120 | NSString* basebinPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"basebin"]; 121 | ASSERT([fm copyItemAtPath:basebinPath toPath:jbroot(@"/basebin") error:nil]); 122 | 123 | unlink(jbroot(@"/basebin/.jbroot").fileSystemRepresentation); 124 | ASSERT([fm createSymbolicLinkAtPath:jbroot(@"/basebin/.jbroot") withDestinationPath:jbroot(@"/") error:nil]); 125 | 126 | return 0; 127 | } 128 | 129 | int startBootstrapd() 130 | { 131 | NSString* log=nil; 132 | NSString* err=nil; 133 | int status = spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"daemon",@"-f"], &log, &err); 134 | if(status != 0) { 135 | STRAPLOG("bootstrap server load faild(%d):\n%@\nERR:%@", status, log, err); 136 | ABORT(); 137 | } 138 | 139 | STRAPLOG("bootstrap server load successful"); 140 | 141 | sleep(1); 142 | 143 | status = spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"check"], &log, &err); 144 | if(status != 0) { 145 | STRAPLOG("bootstrap server check faild(%d):\n%@\nERR:%@", status, log, err); 146 | ABORT(); 147 | } 148 | STRAPLOG("bootstrap server check successful"); 149 | 150 | return 0; 151 | } 152 | 153 | int InstallBootstrap(NSString* jbroot_path) 154 | { 155 | STRAPLOG("install bootstrap..."); 156 | 157 | NSFileManager* fm = NSFileManager.defaultManager; 158 | 159 | ASSERT(mkdir(jbroot_path.fileSystemRepresentation, 0755) == 0); 160 | ASSERT(chown(jbroot_path.fileSystemRepresentation, 0, 0) == 0); 161 | 162 | NSString* bootstrapZstFile = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent: 163 | [NSString stringWithFormat:@"strapfiles/bootstrap-%d.tar.zst", getCFMajorVersion()]]; 164 | if(![fm fileExistsAtPath:bootstrapZstFile]) { 165 | STRAPLOG("can not find bootstrap file, maybe this version of the app is not for iOS%d", NSProcessInfo.processInfo.operatingSystemVersion.majorVersion); 166 | return -1; 167 | } 168 | 169 | NSString* bootstrapTarFile = [NSTemporaryDirectory() stringByAppendingPathComponent:@"bootstrap.tar"]; 170 | if([fm fileExistsAtPath:bootstrapTarFile]) 171 | ASSERT([fm removeItemAtPath:bootstrapTarFile error:nil]); 172 | 173 | ASSERT(decompress_tar_zstd(bootstrapZstFile.fileSystemRepresentation, bootstrapTarFile.fileSystemRepresentation) == 0); 174 | 175 | NSString* tarPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"tar"]; 176 | ASSERT(spawnRoot(tarPath, @[@"-xpkf", bootstrapTarFile, @"-C", jbroot_path], nil, nil) == 0); 177 | 178 | STRAPLOG("rebuild boostrap binaries"); 179 | rebuildSignature(jbroot_path); 180 | 181 | NSString* jbroot_secondary = [NSString stringWithFormat:@"/var/mobile/Containers/Shared/AppGroup/.jbroot-%016llX", jbrand()]; 182 | ASSERT(mkdir(jbroot_secondary.fileSystemRepresentation, 0755) == 0); 183 | ASSERT(chown(jbroot_secondary.fileSystemRepresentation, 0, 0) == 0); 184 | 185 | ASSERT([fm moveItemAtPath:jbroot(@"/var") toPath:[jbroot_secondary stringByAppendingPathComponent:@"/var"] error:nil]); 186 | ASSERT([fm createSymbolicLinkAtPath:jbroot(@"/var") withDestinationPath:@"private/var" error:nil]); 187 | 188 | ASSERT([fm removeItemAtPath:jbroot(@"/private/var") error:nil]); 189 | ASSERT([fm createSymbolicLinkAtPath:jbroot(@"/private/var") withDestinationPath:[jbroot_secondary stringByAppendingPathComponent:@"/var"] error:nil]); 190 | 191 | ASSERT([fm removeItemAtPath:[jbroot_secondary stringByAppendingPathComponent:@"/var/tmp"] error:nil]); 192 | ASSERT([fm moveItemAtPath:jbroot(@"/tmp") toPath:[jbroot_secondary stringByAppendingPathComponent:@"/var/tmp"] error:nil]); 193 | ASSERT([fm createSymbolicLinkAtPath:jbroot(@"/tmp") withDestinationPath:@"var/tmp" error:nil]); 194 | 195 | for(NSString* item in [fm contentsOfDirectoryAtPath:jbroot_path error:nil]) 196 | { 197 | if([item isEqualToString:@"var"]) 198 | continue; 199 | 200 | ASSERT([fm createSymbolicLinkAtPath:[jbroot_secondary stringByAppendingPathComponent:item] withDestinationPath:[jbroot_path stringByAppendingPathComponent:item] error:nil]); 201 | } 202 | 203 | ASSERT([fm removeItemAtPath:[jbroot_secondary stringByAppendingPathComponent:@".jbroot"] error:nil]); 204 | ASSERT([fm createSymbolicLinkAtPath:[jbroot_secondary stringByAppendingPathComponent:@".jbroot"] 205 | withDestinationPath:jbroot_path error:nil]); 206 | 207 | 208 | STRAPLOG("Status: Building Base Binaries"); 209 | ASSERT(rebuildBasebin() == 0); 210 | 211 | STRAPLOG("Status: Starting Bootstrapd"); 212 | ASSERT(startBootstrapd() == 0); 213 | 214 | STRAPLOG("Status: Finalizing Bootstrap"); 215 | NSString* log=nil; 216 | NSString* err=nil; 217 | int status = spawnBootstrap((char*[]){"/bin/sh", "/prep_bootstrap.sh", NULL}, &log, &err); 218 | if(status != 0) { 219 | STRAPLOG("faild(%d):%@\nERR:%@", status, log, err); 220 | ABORT(); 221 | } 222 | 223 | if(![fm fileExistsAtPath:jbroot(@"/var/mobile/Library/Preferences")]) 224 | { 225 | NSDictionary* attr = @{NSFilePosixPermissions:@(0755), NSFileOwnerAccountID:@(501), NSFileGroupOwnerAccountID:@(501)}; 226 | ASSERT([fm createDirectoryAtPath:jbroot(@"/var/mobile/Library/Preferences") withIntermediateDirectories:YES attributes:attr error:nil]); 227 | } 228 | 229 | ASSERT(buildPackageSources() == 0); 230 | 231 | 232 | STRAPLOG("Status: Installing Packages"); 233 | NSString* libkrw0_dummy = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"libkrw0-dummy.deb"]; 234 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/dpkg", "-i", rootfsPrefix(libkrw0_dummy).fileSystemRepresentation, NULL}, nil, nil) == 0); 235 | 236 | NSString* sileoDeb = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"sileo.deb"]; 237 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/dpkg", "-i", rootfsPrefix(sileoDeb).fileSystemRepresentation, NULL}, nil, nil) == 0); 238 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache", "-p", "/Applications/Sileo.app", NULL}, nil, nil) == 0); 239 | 240 | NSString* zebraDeb = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"zebra.deb"]; 241 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/dpkg", "-i", rootfsPrefix(zebraDeb).fileSystemRepresentation, NULL}, nil, nil) == 0); 242 | ASSERT(spawnBootstrap((char*[]){"/usr/bin/uicache", "-p", "/Applications/Zebra.app", NULL}, nil, nil) == 0); 243 | 244 | ASSERT([[NSString stringWithFormat:@"%d",BOOTSTRAP_VERSION] writeToFile:jbroot(@"/.bootstrapped") atomically:YES encoding:NSUTF8StringEncoding error:nil]); 245 | ASSERT([fm copyItemAtPath:jbroot(@"/.bootstrapped") toPath:[jbroot_secondary stringByAppendingPathComponent:@".bootstrapped"] error:nil]); 246 | 247 | STRAPLOG("Status: Bootstrap Installed"); 248 | 249 | 250 | return 0; 251 | } 252 | 253 | int ReRandomizeBootstrap() 254 | { 255 | //jbroot() disabled 256 | 257 | NSFileManager* fm = NSFileManager.defaultManager; 258 | 259 | uint64_t prev_jbrand = jbrand(); 260 | uint64_t new_jbrand = jbrand_new(); 261 | 262 | ASSERT( [fm moveItemAtPath:[NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", prev_jbrand] 263 | toPath:[NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", new_jbrand] error:nil] ); 264 | 265 | ASSERT([fm moveItemAtPath:[NSString stringWithFormat:@"/var/mobile/Containers/Shared/AppGroup/.jbroot-%016llX", prev_jbrand] 266 | toPath:[NSString stringWithFormat:@"/var/mobile/Containers/Shared/AppGroup/.jbroot-%016llX", new_jbrand] error:nil]); 267 | 268 | 269 | NSString* jbroot_path = [NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", new_jbrand]; 270 | NSString* jbroot_secondary = [NSString stringWithFormat:@"/var/mobile/Containers/Shared/AppGroup/.jbroot-%016llX", new_jbrand]; 271 | 272 | for(NSString* item in [fm contentsOfDirectoryAtPath:jbroot_path error:nil]) 273 | { 274 | if([item isEqualToString:@"var"]) 275 | continue; 276 | 277 | NSString* checkpath = [jbroot_secondary stringByAppendingPathComponent:item]; 278 | 279 | struct stat st; 280 | if(lstat(checkpath.fileSystemRepresentation, &st)==0) { 281 | ASSERT([fm removeItemAtPath:checkpath error:nil]); 282 | } 283 | 284 | ASSERT([fm createSymbolicLinkAtPath:checkpath withDestinationPath:[jbroot_path stringByAppendingPathComponent:item] error:nil]); 285 | } 286 | 287 | ASSERT([fm removeItemAtPath:[jbroot_path stringByAppendingPathComponent:@"/private/var"] error:nil]); 288 | ASSERT([fm createSymbolicLinkAtPath:[jbroot_path stringByAppendingPathComponent:@"/private/var"] 289 | withDestinationPath:[jbroot_secondary stringByAppendingPathComponent:@"/var"] error:nil]); 290 | 291 | ASSERT([fm removeItemAtPath:[jbroot_secondary stringByAppendingPathComponent:@".jbroot"] error:nil]); 292 | ASSERT([fm createSymbolicLinkAtPath:[jbroot_secondary stringByAppendingPathComponent:@".jbroot"] 293 | withDestinationPath:jbroot_path error:nil]); 294 | 295 | //jbroot() enabled 296 | 297 | STRAPLOG("Status: Building Base Binaries"); 298 | ASSERT(rebuildBasebin() == 0); 299 | 300 | STRAPLOG("Status: Starting Bootstrapd"); 301 | ASSERT(startBootstrapd() == 0); 302 | 303 | STRAPLOG("Status: Updating Symlinks"); 304 | ASSERT(spawnBootstrap((char*[]){"/bin/sh", "/usr/libexec/updatelinks.sh", NULL}, nil, nil) == 0); 305 | 306 | return 0; 307 | } 308 | 309 | int bootstrap() 310 | { 311 | ASSERT(getuid()==0); 312 | 313 | STRAPLOG("bootstrap..."); 314 | 315 | NSFileManager* fm = NSFileManager.defaultManager; 316 | 317 | NSString* jbroot_path = find_jbroot(); 318 | 319 | if(!jbroot_path) { 320 | STRAPLOG("device is not strapped..."); 321 | 322 | jbroot_path = [NSString stringWithFormat:@"/var/containers/Bundle/Application/.jbroot-%016llX", jbrand_new()]; 323 | 324 | STRAPLOG("bootstrap @ %@", jbroot_path); 325 | 326 | ASSERT(InstallBootstrap(jbroot_path) == 0); 327 | 328 | } else if(![fm fileExistsAtPath:jbroot(@"/.bootstrapped")]) { 329 | STRAPLOG("remove unfinished bootstrap %@", jbroot_path); 330 | 331 | uint64_t prev_jbrand = jbrand(); 332 | 333 | ASSERT([fm removeItemAtPath:jbroot_path error:nil]); 334 | 335 | NSString* jbroot_secondary = [NSString stringWithFormat:@"/var/mobile/Containers/Shared/AppGroup/.jbroot-%016llX", prev_jbrand]; 336 | if([fm fileExistsAtPath:jbroot_secondary]) { 337 | STRAPLOG("remove unfinished bootstrap %@", jbroot_secondary); 338 | ASSERT([fm removeItemAtPath:jbroot_secondary error:nil]); 339 | } 340 | 341 | STRAPLOG("bootstrap @ %@", jbroot_path); 342 | 343 | ASSERT(InstallBootstrap(jbroot_path) == 0); 344 | 345 | } else { 346 | STRAPLOG("device is strapped: %@", jbroot_path); 347 | 348 | STRAPLOG("Status: Rerandomize jbroot"); 349 | 350 | ASSERT(ReRandomizeBootstrap() == 0); 351 | } 352 | 353 | ASSERT(disableRootHideBlacklist()==0); 354 | 355 | STRAPLOG("Status: Rebuilding Apps"); 356 | ASSERT(spawnBootstrap((char*[]){"/bin/sh", "/basebin/rebuildapps.sh", NULL}, nil, nil) == 0); 357 | 358 | NSDictionary* bootinfo = @{@"bootsession":getBootSession()}; 359 | ASSERT([bootinfo writeToFile:jbroot(@"/basebin/.bootinfo.plist") atomically:YES]); 360 | 361 | STRAPLOG("Status: Bootstrap Successful"); 362 | 363 | return 0; 364 | } 365 | 366 | int unbootstrap() 367 | { 368 | STRAPLOG("unbootstrap..."); 369 | 370 | //try 371 | spawnRoot(jbroot(@"/basebin/bootstrapd"), @[@"exit"], nil, nil); 372 | 373 | //jbroot unavailable now 374 | 375 | NSFileManager* fm = NSFileManager.defaultManager; 376 | 377 | NSString* dirpath = @"/var/containers/Bundle/Application/"; 378 | for(NSString* item in [fm directoryContentsAtPath:dirpath]) 379 | { 380 | if([fm fileExistsAtPath: 381 | [dirpath stringByAppendingPathComponent:@".installed_dopamine"]]) 382 | continue; 383 | 384 | if(is_jbroot_name(item.UTF8String)) { 385 | STRAPLOG("remove %@ @ %@", item, dirpath); 386 | ASSERT([fm removeItemAtPath:[dirpath stringByAppendingPathComponent:item] error:nil]); 387 | } 388 | } 389 | 390 | 391 | dirpath = @"/var/mobile/Containers/Shared/AppGroup/"; 392 | for(NSString* item in [fm directoryContentsAtPath:dirpath]) 393 | { 394 | if([fm fileExistsAtPath: 395 | [dirpath stringByAppendingPathComponent:@".installed_dopamine"]]) 396 | continue; 397 | 398 | if(is_jbroot_name(item.UTF8String)) { 399 | STRAPLOG("remove %@ @ %@", item, dirpath); 400 | ASSERT([fm removeItemAtPath:[dirpath stringByAppendingPathComponent:item] error:nil]); 401 | } 402 | } 403 | 404 | SYSLOG("bootstrap uninstalled!"); 405 | 406 | [LSApplicationWorkspace.defaultWorkspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES]; 407 | 408 | AppList* tsapp = [AppList appWithBundleIdentifier:@"com.opa334.TrollStore"]; 409 | if(tsapp) { 410 | NSString* log=nil; 411 | NSString* err=nil; 412 | if(spawnRoot([tsapp.bundleURL.path stringByAppendingPathComponent:@"trollstorehelper"], @[@"refresh"], &log, &err) != 0) { 413 | STRAPLOG("refresh tsapps failed:%@\nERR:%@", log, err); 414 | } 415 | } else { 416 | STRAPLOG("trollstore not found!"); 417 | } 418 | 419 | killAllForApp("/usr/libexec/backboardd"); 420 | 421 | return 0; 422 | } 423 | 424 | 425 | bool isBootstrapInstalled() 426 | { 427 | if(!find_jbroot()) 428 | return NO; 429 | 430 | if(![NSFileManager.defaultManager fileExistsAtPath:jbroot(@"/.bootstrapped")]) 431 | return NO; 432 | 433 | return YES; 434 | } 435 | 436 | bool isSystemBootstrapped() 437 | { 438 | if(!isBootstrapInstalled()) return false; 439 | 440 | NSDictionary* bootinfo = [NSDictionary dictionaryWithContentsOfFile:jbroot(@"/basebin/.bootinfo.plist")]; 441 | if(!bootinfo) return false; 442 | 443 | NSString* bootsession = bootinfo[@"bootsession"]; 444 | if(!bootsession) return false; 445 | 446 | return [bootsession isEqualToString:getBootSession()]; 447 | } 448 | -------------------------------------------------------------------------------- /Bootstrap/common.h: -------------------------------------------------------------------------------- 1 | #ifndef common_h 2 | #define common_h 3 | 4 | #include "syslog.h" 5 | #include "utils.h" 6 | #include "seh.h" 7 | 8 | #define Localized(x) x 9 | 10 | #endif /* common_h */ 11 | -------------------------------------------------------------------------------- /Bootstrap/credits.h: -------------------------------------------------------------------------------- 1 | #ifndef credits_h 2 | #define credits_h 3 | // dictionary will be sorted alphabetically 4 | NSDictionary* CREDITS = @{ 5 | @"opa334" : @"http://github.com/opa334", 6 | @"hayden" : @"https://procursus.social/@hayden", 7 | @"CKatri" : @"https://procursus.social/@cameron", 8 | @"Alfie" : @"https://alfiecg.uk", 9 | @"BomberFish" : @"https://twitter.com/bomberfish77", 10 | @"Évelyne" : @"http://github.com/evelyneee", 11 | @"sourcelocation" : @"http://github.com/sourcelocation", 12 | @"Linus Henze" : @"http://github.com/LinusHenze", 13 | @"Cryptic" : @"http://github.com/Cryptiiiic", 14 | @"Clarity" : @"http://github.com/TheRealClarity", 15 | @"Dhinakg" : @"http://github.com/dhinakg", 16 | @"dleovl" : @"https://github.com/dleovl", 17 | @"Capt Inc" : @"http://github.com/captinc", 18 | @"Sam Bingner" : @"http://github.com/sbingner", 19 | @"ProcursusTeam" : @"https://procursus.social/@team", 20 | @"TheosTeam" : @"https://theos.dev", 21 | @"kirb" : @"http://github.com/kirb", 22 | @"Amy While" : @"http://github.com/elihwyma", 23 | @"roothide" : @"http://github.com/RootHide", 24 | @"Shadow-" : @"http://iosjb.top/", 25 | @"SeanIsTethered" : @"https://github.com/jailbreakmerebooted", 26 | @"Huy Nguyen" : @"https://twitter.com/little_34306", 27 | @"haxi0" : @"https://haxi0.space", 28 | @"Nebula" : @"https://itsnebula.net", 29 | @"DuyKhanhTran" : @"https://twitter.com/TranKha50277352", 30 | @"Nathan" : @"https://github.com/verygenericname", 31 | @"Nick Chan" : @"https://nickchan.lol", 32 | @"Muirey03" : @"https://twitter.com/Muirey03", 33 | @"absidue" : @"https://github.com/absidue", 34 | @"MasterMike" : @"https://ios.cfw.guide", 35 | @"Nightwind" : @"https://twitter.com/NightwindDev", 36 | @"Leptos" : @"https://github.com/leptos-null", 37 | @"Lightmann" : @"https://github.com/L1ghtmann", 38 | @"iAdam1n" : @"https://twitter.com/iAdam1n", 39 | @"xina520" : @"https://twitter.com/xina520", 40 | @"Barron" : @"https://tweaksdev22.github.io", 41 | @"iarrays" : @"https://iarrays.com", 42 | @"niceios" : @"https://twitter.com/niceios", 43 | @"Snail" : @"https://twitter.com/somnusix", 44 | @"Misty" : @"https://twitter.com/miscmisty", 45 | @"limneos" : @"https://twitter.com/limneos", 46 | @"iDownloadBlog" : @"https://twitter.com/idownloadblog", 47 | @"GeoSnOw" : @"https://twitter.com/fce365", 48 | @"onejailbreak" : @"https://twitter.com/onejailbreak_", 49 | @"iExmo" : @"https://twitter.com/iexmojailbreak", 50 | @"omrkujman" : @"https://twitter.com/omrkujman", 51 | @"nzhaonan" : @"https://twitter.com/nzhaonan", 52 | @"YourRepo" : @"https://twitter.com/yourepo", 53 | @"Phuc Do" : @"https://twitter.com/dobabaophuc", 54 | @"dxcool223x" : @"https://twitter.com/dxcool223x", 55 | @"akusio" : @"https://twitter.com/akusio_rr", 56 | @"xsf1re" : @"https://twitter.com/xsf1re", 57 | @"PoomSmart" : @"https://twitter.com/poomsmart", 58 | @"Elias Sfeir" : @"https://twitter.com/eliassfeir1", 59 | @"SquidGesture" : @"https://twitter.com/lclrc", 60 | @"yandevelop" : @"https://twitter.com/yandevelop", 61 | @"EquationGroups" : @"https://twitter.com/equationgroups", 62 | @"tihmstar" : @"https://twitter.com/tihmstar", 63 | @"laileld" : @"https://twitter.com/h_h_x_t", 64 | @"bswbw" : @"https://twitter.com/bswbw", 65 | @"Jonathan" : @"https://twitter.com/jontelang", 66 | @"iRaMzi" : @"https://twitter.com/iramzi7", 67 | @"xybp888" : @"https://twitter.com/xybp888", 68 | @"Ellie" : @"https://twitter.com/elliessurviving", 69 | @"tigisoftware" : @"https://twitter.com/tigisoftware", 70 | @"Kevin" : @"https://github.com/iodes", 71 | }; 72 | 73 | #endif /* credits_h */ 74 | -------------------------------------------------------------------------------- /Bootstrap/envbuf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int envbuf_len(const char *envp[]) 5 | { 6 | if (envp == NULL) return 1; 7 | 8 | int k = 0; 9 | const char *env = envp[k++]; 10 | while (env != NULL) { 11 | env = envp[k++]; 12 | } 13 | return k; 14 | } 15 | 16 | char **envbuf_mutcopy(const char *envp[]) 17 | { 18 | if (envp == NULL) return NULL; //opa said don't comment this 19 | 20 | int len = envbuf_len(envp); 21 | char **envcopy = malloc(len * sizeof(char *)); 22 | 23 | for (int i = 0; i < len-1; i++) { 24 | envcopy[i] = strdup(envp[i]); 25 | } 26 | envcopy[len-1] = NULL; 27 | 28 | return envcopy; 29 | } 30 | 31 | void envbuf_free(char *envp[]) 32 | { 33 | if (envp == NULL) return; 34 | 35 | int len = envbuf_len((const char**)envp); 36 | for (int i = 0; i < len-1; i++) { 37 | free(envp[i]); 38 | } 39 | free(envp); 40 | } 41 | 42 | int envbuf_find(const char *envp[], const char *name) 43 | { 44 | if (envp) { 45 | unsigned long nameLen = strlen(name); 46 | int k = 0; 47 | const char *env = envp[k++]; 48 | while (env != NULL) { 49 | unsigned long envLen = strlen(env); 50 | if (envLen > nameLen) { 51 | if (!strncmp(env, name, nameLen)) { 52 | if (env[nameLen] == '=') { 53 | return k-1; 54 | } 55 | } 56 | } 57 | env = envp[k++]; 58 | } 59 | } 60 | return -1; 61 | } 62 | 63 | const char *envbuf_getenv(const char *envp[], const char *name) 64 | { 65 | if (envp) { 66 | unsigned long nameLen = strlen(name); 67 | int envIndex = envbuf_find(envp, name); 68 | if (envIndex >= 0) { 69 | return &envp[envIndex][nameLen+1]; 70 | } 71 | } 72 | return NULL; 73 | } 74 | 75 | void envbuf_setenv(char **envpp[], const char *name, const char *value, int override) 76 | { 77 | if (envpp) { 78 | char **envp = *envpp; 79 | if (!envp) { 80 | // treat NULL as [NULL] 81 | envp = malloc(sizeof(const char *)); 82 | envp[0] = NULL; 83 | } 84 | 85 | char *envToSet = malloc(strlen(name)+strlen(value)+2); 86 | strcpy(envToSet, name); 87 | strcat(envToSet, "="); 88 | strcat(envToSet, value); 89 | 90 | int existingEnvIndex = envbuf_find((const char **)envp, name); 91 | if (existingEnvIndex >= 0) { 92 | if(!override) { 93 | free(envToSet); 94 | return; 95 | } 96 | // if already exists: deallocate old variable, then replace pointer 97 | free(envp[existingEnvIndex]); 98 | envp[existingEnvIndex] = envToSet; 99 | } 100 | else { 101 | // if doesn't exist yet: increase env buffer size, place at end 102 | int prevLen = envbuf_len((const char **)envp); 103 | *envpp = realloc(envp, (prevLen+1)*sizeof(const char *)); 104 | envp = *envpp; 105 | envp[prevLen-1] = envToSet; 106 | envp[prevLen] = NULL; 107 | } 108 | } 109 | } 110 | 111 | void envbuf_unsetenv(char **envpp[], const char *name) 112 | { 113 | if (envpp) { 114 | char **envp = *envpp; 115 | if (!envp) return; 116 | 117 | int existingEnvIndex = envbuf_find((const char **)envp, name); 118 | if (existingEnvIndex >= 0) { 119 | free(envp[existingEnvIndex]); 120 | int prevLen = envbuf_len((const char **)envp); 121 | for (int i = existingEnvIndex; i < (prevLen-1); i++) { 122 | envp[i] = envp[i+1]; 123 | } 124 | *envpp = realloc(envp, (prevLen-1)*sizeof(const char *)); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Bootstrap/envbuf.h: -------------------------------------------------------------------------------- 1 | int envbuf_len(const char *envp[]); 2 | char **envbuf_mutcopy(const char *envp[]); 3 | void envbuf_free(char *envp[]); 4 | int envbuf_find(const char *envp[], const char *name); 5 | const char *envbuf_getenv(const char *envp[], const char *name); 6 | void envbuf_setenv(char **envpp[], const char *name, const char *value, int overwrite); 7 | void envbuf_unsetenv(char **envpp[], const char *name); -------------------------------------------------------------------------------- /Bootstrap/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "AppDelegate.h" 3 | #include "NSUserDefaults+appDefaults.h" 4 | #include "common.h" 5 | 6 | int main(int argc, char * argv[]) { 7 | 8 | if(argc >= 2) 9 | { 10 | @try { 11 | SYSLOG("Bootstrap cmd %s", argv[1]); 12 | ASSERT(getuid() == 0); 13 | 14 | if(strcmp(argv[1], "bootstrap")==0) { 15 | int bootstrap(); 16 | exit(bootstrap()); 17 | } else if(strcmp(argv[1], "unbootstrap")==0) { 18 | int unbootstrap(); 19 | exit(unbootstrap()); 20 | } else if(strcmp(argv[1], "enableapp")==0) { 21 | int enableForApp(NSString* bundlePath); 22 | exit(enableForApp(@(argv[2]))); 23 | } else if(strcmp(argv[1], "disableapp")==0) { 24 | int disableForApp(NSString* bundlePath); 25 | exit(disableForApp(@(argv[2]))); 26 | } else if(strcmp(argv[1], "rebuildiconcache")==0) { 27 | int rebuildIconCache(); 28 | exit(rebuildIconCache()); 29 | } else if(strcmp(argv[1], "testprefs")==0) { 30 | SYSLOG("locale=%@", [NSUserDefaults.appDefaults valueForKey:@"locale"]); 31 | [NSUserDefaults.appDefaults setValue:@"CA" forKey:@"locale"]; 32 | [NSUserDefaults.appDefaults synchronize]; 33 | SYSLOG("locale=%@", [NSUserDefaults.appDefaults valueForKey:@"locale"]); 34 | exit(0); 35 | } 36 | 37 | SYSLOG("unknown cmd: %s", argv[1]); 38 | ABORT(); 39 | } 40 | @catch (NSException *exception) 41 | { 42 | SYSLOG("***exception: %@", exception); 43 | exit(-1); 44 | } 45 | } 46 | 47 | NSString * appDelegateClassName; 48 | @autoreleasepool { 49 | // Setup code that might create autoreleased objects goes here. 50 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 51 | } 52 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 53 | } 54 | -------------------------------------------------------------------------------- /Bootstrap/seh.h: -------------------------------------------------------------------------------- 1 | #ifndef seh_h 2 | #define seh_h 3 | 4 | #undef abort 5 | #define abort #error# 6 | 7 | #define ABORT() do {\ 8 | @throw [NSException\ 9 | exceptionWithName:@"ABORT"\ 10 | reason:[NSString stringWithFormat:@"%s (%d)", __FILE_NAME__, __LINE__]\ 11 | userInfo:nil];\ 12 | } while(0) 13 | 14 | #undef assert 15 | #define assert #error# 16 | 17 | #define ASSERT(...) do{if(!(__VA_ARGS__)) {\ 18 | @throw [NSException\ 19 | exceptionWithName:@"ASSERT"\ 20 | reason:[NSString stringWithFormat:@"%s (%d): %s", __FILE_NAME__, __LINE__, #__VA_ARGS__]\ 21 | userInfo:nil];\ 22 | }} while(0) 23 | 24 | #endif /* seh_h */ 25 | -------------------------------------------------------------------------------- /Bootstrap/sources.h: -------------------------------------------------------------------------------- 1 | #ifndef sources_h 2 | #define sources_h 3 | 4 | #define DEFAULT_SOURCES "\ 5 | Types: deb\n\ 6 | URIs: https://repo.chariz.com/\n\ 7 | Suites: ./\n\ 8 | Components:\n\ 9 | \n\ 10 | Types: deb\n\ 11 | URIs: https://havoc.app/\n\ 12 | Suites: ./\n\ 13 | Components:\n\ 14 | \n\ 15 | Types: deb\n\ 16 | URIs: http://apt.thebigboss.org/repofiles/cydia/\n\ 17 | Suites: stable\n\ 18 | Components: main\n\ 19 | \n\ 20 | Types: deb\n\ 21 | URIs: https://roothide.github.io/\n\ 22 | Suites: ./\n\ 23 | Components:\n\ 24 | \n\ 25 | Types: deb\n\ 26 | URIs: https://roothide.github.io/procursus\n\ 27 | Suites: iphoneos-arm64e/%d\n\ 28 | Components: main\n\ 29 | " 30 | 31 | #define ALT_SOURCES "\ 32 | Types: deb\n\ 33 | URIs: https://iosjb.top/\n\ 34 | Suites: ./\n\ 35 | Components:\n\ 36 | \n\ 37 | Types: deb\n\ 38 | URIs: https://iosjb.top/procursus\n\ 39 | Suites: iphoneos-arm64e/%d\n\ 40 | Components: main\n\ 41 | " 42 | 43 | #define ZEBRA_SOURCES "\ 44 | # Zebra Sources List\n\ 45 | deb https://getzbra.com/repo/ ./\n\ 46 | deb https://repo.chariz.com/ ./\n\ 47 | deb https://havoc.app/ ./\n\ 48 | deb https://roothide.github.io/ ./\n\ 49 | deb https://roothide.github.io/procursus iphoneos-arm64e/%d main\n\ 50 | \n\ 51 | " 52 | 53 | #endif /* sources_h */ 54 | -------------------------------------------------------------------------------- /Bootstrap/syslog.h: -------------------------------------------------------------------------------- 1 | 2 | //oh shit why NSLog also output to stderr 3 | //luckly syslog also accept NSObject 4 | 5 | #include 6 | 7 | #define NSLog #error# 8 | 9 | #define SYSLOG(fmt, ...) do { fmt[0];\ 10 | openlog("bootstrap",LOG_PID,LOG_AUTH);\ 11 | syslog(LOG_DEBUG, fmt, ## __VA_ARGS__);\ 12 | closelog();\ 13 | } while(0) 14 | 15 | #define STRAPLOG(fmt, ...) do { fmt[0];\ 16 | SYSLOG(fmt, ## __VA_ARGS__);\ 17 | fprintf(stdout, [NSString stringWithFormat:@fmt, ## __VA_ARGS__].UTF8String);\ 18 | fprintf(stdout, "\n");\ 19 | fflush(stdout);\ 20 | } while(0) 21 | -------------------------------------------------------------------------------- /Bootstrap/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef utils_h 2 | #define utils_h 3 | 4 | #import 5 | 6 | extern const char** environ; 7 | 8 | uint64_t jbrand(); 9 | 10 | uint64_t jbrand_new(); 11 | 12 | NSString* find_jbroot(); 13 | 14 | NSString* jbroot(NSString *path); 15 | 16 | int is_jbroot_name(const char* name); 17 | 18 | NSString* rootfsPrefix(NSString* path); 19 | 20 | NSString* getBootSession(); 21 | 22 | int spawn(const char* path, const char** argv, const char** envp, void(^std_out)(char*), void(^std_err)(char*)); 23 | 24 | int spawnBootstrap(const char** argv, NSString** stdOut, NSString** stdErr); 25 | 26 | int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdErr); 27 | 28 | void machoGetInfo(FILE* candidateFile, bool *isMachoOut, bool *isLibraryOut); 29 | 30 | BOOL isDefaultInstallationPath(NSString* _path); 31 | 32 | void killAllForApp(const char* bundlePath); 33 | 34 | 35 | @interface LSApplicationWorkspace : NSObject 36 | + (id)defaultWorkspace; 37 | - (BOOL)openApplicationWithBundleID:(id)arg1; 38 | - (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 39 | internal:(BOOL)arg2 40 | user:(BOOL)arg3; 41 | @end 42 | 43 | #endif /* utils_h */ 44 | -------------------------------------------------------------------------------- /Bootstrap/utils.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "envbuf.h" 6 | #include "common.h" 7 | 8 | uint64_t jbrand_new() 9 | { 10 | uint64_t value = ((uint64_t)arc4random()) | ((uint64_t)arc4random())<<32; 11 | uint8_t check = value>>8 ^ value >> 16 ^ value>>24 ^ value>>32 ^ value>>40 ^ value>>48 ^ value>>56; 12 | return (value & ~0xFF) | check; 13 | } 14 | 15 | int is_jbrand_value(uint64_t value) 16 | { 17 | uint8_t check = value>>8 ^ value >> 16 ^ value>>24 ^ value>>32 ^ value>>40 ^ value>>48 ^ value>>56; 18 | return check == (uint8_t)value; 19 | } 20 | 21 | #define JB_ROOT_PREFIX ".jbroot-" 22 | #define JB_RAND_LENGTH (sizeof(uint64_t)*sizeof(char)*2) 23 | 24 | int is_jbroot_name(const char* name) 25 | { 26 | if(strlen(name) != (sizeof(JB_ROOT_PREFIX)-1+JB_RAND_LENGTH)) 27 | return 0; 28 | 29 | if(strncmp(name, JB_ROOT_PREFIX, sizeof(JB_ROOT_PREFIX)-1) != 0) 30 | return 0; 31 | 32 | char* endp=NULL; 33 | uint64_t value = strtoull(name+sizeof(JB_ROOT_PREFIX)-1, &endp, 16); 34 | if(!endp || *endp!='\0') 35 | return 0; 36 | 37 | if(!is_jbrand_value(value)) 38 | return 0; 39 | 40 | return 1; 41 | } 42 | 43 | uint64_t resolve_jbrand_value(const char* name) 44 | { 45 | if(strlen(name) != (sizeof(JB_ROOT_PREFIX)-1+JB_RAND_LENGTH)) 46 | return 0; 47 | 48 | if(strncmp(name, JB_ROOT_PREFIX, sizeof(JB_ROOT_PREFIX)-1) != 0) 49 | return 0; 50 | 51 | char* endp=NULL; 52 | uint64_t value = strtoull(name+sizeof(JB_ROOT_PREFIX)-1, &endp, 16); 53 | if(!endp || *endp!='\0') 54 | return 0; 55 | 56 | if(!is_jbrand_value(value)) 57 | return 0; 58 | 59 | return value; 60 | } 61 | 62 | 63 | NSString* find_jbroot() 64 | { 65 | //jbroot path may change when re-randomize it 66 | NSString * jbroot = nil; 67 | NSArray *subItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/var/containers/Bundle/Application/" error:nil]; 68 | for (NSString *subItem in subItems) { 69 | if (is_jbroot_name(subItem.UTF8String)) 70 | { 71 | NSString* path = [@"/var/containers/Bundle/Application/" stringByAppendingPathComponent:subItem]; 72 | 73 | // if([NSFileManager.defaultManager fileExistsAtPath: 74 | // [path stringByAppendingPathComponent:@".installed_dopamine"]]) 75 | // continue; 76 | 77 | jbroot = path; 78 | break; 79 | } 80 | } 81 | return jbroot; 82 | } 83 | 84 | NSString *jbroot(NSString *path) 85 | { 86 | NSString* jbroot = find_jbroot(); 87 | ASSERT(jbroot != NULL); //to avoid [nil stringByAppendingString: 88 | return [jbroot stringByAppendingPathComponent:path]; 89 | } 90 | 91 | uint64_t jbrand() 92 | { 93 | NSString* jbroot = find_jbroot(); 94 | ASSERT(jbroot != NULL); 95 | return resolve_jbrand_value([jbroot lastPathComponent].UTF8String); 96 | } 97 | 98 | NSString* rootfsPrefix(NSString* path) 99 | { 100 | return [@"/rootfs/" stringByAppendingPathComponent:path]; 101 | } 102 | 103 | #define POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE 1 104 | extern int posix_spawnattr_set_persona_np(const posix_spawnattr_t* __restrict, uid_t, uint32_t); 105 | extern int posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t* __restrict, uid_t); 106 | extern int posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t* __restrict, uid_t); 107 | 108 | int spawn(const char* path, const char** argv, const char** envp, void(^std_out)(char*), void(^std_err)(char*)) 109 | { 110 | SYSLOG("spawn %s", path); 111 | 112 | __block pid_t pid=0; 113 | posix_spawnattr_t attr; 114 | posix_spawnattr_init(&attr); 115 | 116 | posix_spawnattr_set_persona_np(&attr, 99, POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE); 117 | posix_spawnattr_set_persona_uid_np(&attr, 0); 118 | posix_spawnattr_set_persona_gid_np(&attr, 0); 119 | 120 | posix_spawn_file_actions_t action; 121 | posix_spawn_file_actions_init(&action); 122 | 123 | int outPipe[2]; 124 | pipe(outPipe); 125 | posix_spawn_file_actions_addclose(&action, outPipe[0]); 126 | posix_spawn_file_actions_adddup2(&action, outPipe[1], STDOUT_FILENO); 127 | posix_spawn_file_actions_addclose(&action, outPipe[1]); 128 | 129 | int errPipe[2]; 130 | pipe(errPipe); 131 | posix_spawn_file_actions_addclose(&action, errPipe[0]); 132 | posix_spawn_file_actions_adddup2(&action, errPipe[1], STDERR_FILENO); 133 | posix_spawn_file_actions_addclose(&action, errPipe[1]); 134 | 135 | 136 | dispatch_semaphore_t lock = dispatch_semaphore_create(0); 137 | 138 | dispatch_queue_t queue = dispatch_queue_create("spawnPipeQueue", DISPATCH_QUEUE_CONCURRENT); 139 | 140 | dispatch_source_t stdOutSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, outPipe[0], 0, queue); 141 | dispatch_source_t stdErrSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, errPipe[0], 0, queue); 142 | 143 | int outFD = outPipe[0]; 144 | int errFD = errPipe[0]; 145 | 146 | dispatch_source_set_cancel_handler(stdOutSource, ^{ 147 | close(outFD); 148 | dispatch_semaphore_signal(lock); 149 | SYSLOG("stdout canceled [%d]", pid); 150 | }); 151 | dispatch_source_set_cancel_handler(stdErrSource, ^{ 152 | close(errFD); 153 | dispatch_semaphore_signal(lock); 154 | SYSLOG("stderr canceled [%d]", pid); 155 | }); 156 | 157 | dispatch_source_set_event_handler(stdOutSource, ^{ 158 | char buffer[BUFSIZ]={0}; 159 | ssize_t bytes = read(outFD, buffer, sizeof(buffer)-1); 160 | if (bytes <= 0) { 161 | dispatch_source_cancel(stdOutSource); 162 | return; 163 | } 164 | SYSLOG("spawn[%d] stdout: %s", pid, buffer); 165 | if(std_out) std_out(buffer); 166 | }); 167 | dispatch_source_set_event_handler(stdErrSource, ^{ 168 | char buffer[BUFSIZ]={0}; 169 | ssize_t bytes = read(errFD, buffer, sizeof(buffer)-1); 170 | if (bytes <= 0) { 171 | dispatch_source_cancel(stdErrSource); 172 | return; 173 | } 174 | SYSLOG("spawn[%d] stderr: %s", pid, buffer); 175 | if(std_err) std_err(buffer); 176 | }); 177 | 178 | dispatch_resume(stdOutSource); 179 | dispatch_resume(stdErrSource); 180 | 181 | int spawnError = posix_spawn(&pid, path, &action, &attr, argv, envp); 182 | SYSLOG("spawn ret=%d, pid=%d", spawnError, pid); 183 | 184 | posix_spawnattr_destroy(&attr); 185 | posix_spawn_file_actions_destroy(&action); 186 | 187 | close(outPipe[1]); 188 | close(errPipe[1]); 189 | 190 | if(spawnError != 0) 191 | { 192 | SYSLOG("posix_spawn error %d:%s\n", spawnError, strerror(spawnError)); 193 | dispatch_source_cancel(stdOutSource); 194 | dispatch_source_cancel(stdErrSource); 195 | return spawnError; 196 | } 197 | 198 | //wait stdout 199 | dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); 200 | //wait stderr 201 | dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER); 202 | 203 | int status=0; 204 | while(waitpid(pid, &status, 0) != -1) 205 | { 206 | if (WIFSIGNALED(status)) { 207 | return 128 + WTERMSIG(status); 208 | } else if (WIFEXITED(status)) { 209 | return WEXITSTATUS(status); 210 | } 211 | //keep waiting?return status; 212 | }; 213 | return -1; 214 | } 215 | 216 | int spawnBootstrap(const char** argv, NSString** stdOut, NSString** stdErr) 217 | { 218 | NSMutableArray* argArr = [[NSMutableArray alloc] init]; 219 | for(int i=1; argv[i]; i++) [argArr addObject:[NSString stringWithUTF8String:argv[i]]]; 220 | SYSLOG("spawnBootstrap %s with %@", argv[0], argArr); 221 | 222 | char **envc = envbuf_mutcopy(environ); 223 | 224 | envbuf_setenv(&envc, "DYLD_INSERT_LIBRARIES", jbroot(@"/basebin/bootstrap.dylib").fileSystemRepresentation, 1); 225 | 226 | 227 | __block NSMutableString* outString=nil; 228 | __block NSMutableString* errString=nil; 229 | 230 | if(stdOut) outString = [NSMutableString new]; 231 | if(stdErr) errString = [NSMutableString new]; 232 | 233 | 234 | int retval = spawn(jbroot(@(argv[0])).fileSystemRepresentation, argv, envc, ^(char* outstr){ 235 | if(stdOut) [outString appendString:@(outstr)]; 236 | }, ^(char* errstr){ 237 | if(stdErr) [errString appendString:@(errstr)]; 238 | }); 239 | 240 | envbuf_free(envc); 241 | 242 | return retval; 243 | } 244 | 245 | int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString** stdErr) 246 | { 247 | SYSLOG("spawnRoot %@ with %@", path, args); 248 | 249 | NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new]; 250 | [argsM insertObject:path atIndex:0]; 251 | 252 | NSUInteger argCount = [argsM count]; 253 | char **argsC = (char **)malloc((argCount + 1) * sizeof(char*)); 254 | 255 | for (NSUInteger i = 0; i < argCount; i++) 256 | { 257 | argsC[i] = strdup([[argsM objectAtIndex:i] UTF8String]); 258 | } 259 | argsC[argCount] = NULL; 260 | 261 | 262 | __block NSMutableString* outString=nil; 263 | __block NSMutableString* errString=nil; 264 | 265 | if(stdOut) outString = [NSMutableString new]; 266 | if(stdErr) errString = [NSMutableString new]; 267 | 268 | int retval = spawn(path.fileSystemRepresentation, argsC, environ, ^(char* outstr){ 269 | if(stdOut) [outString appendString:@(outstr)]; 270 | }, ^(char* errstr){ 271 | if(stdErr) [errString appendString:@(errstr)]; 272 | }); 273 | 274 | if(stdOut) *stdOut = outString.copy; 275 | if(stdErr) *stdErr = errString.copy; 276 | 277 | for (NSUInteger i = 0; i < argCount; i++) 278 | { 279 | free(argsC[i]); 280 | } 281 | free(argsC); 282 | 283 | return retval; 284 | } 285 | 286 | void machoEnumerateArchs(FILE* machoFile, bool (^archEnumBlock)(struct mach_header_64* header, uint32_t offset)) 287 | { 288 | struct mach_header_64 mh={0}; 289 | if(fseek(machoFile,0,SEEK_SET)!=0)return; 290 | if(fread(&mh,sizeof(mh),1,machoFile)!=1)return; 291 | 292 | if(mh.magic==FAT_MAGIC || mh.magic==FAT_CIGAM)//and || mh.magic==FAT_MAGIC_64 || mh.magic==FAT_CIGAM_64? with fat_arch_64 293 | { 294 | struct fat_header fh={0}; 295 | if(fseek(machoFile,0,SEEK_SET)!=0)return; 296 | if(fread(&fh,sizeof(fh),1,machoFile)!=1)return; 297 | 298 | for(int i = 0; i < OSSwapBigToHostInt32(fh.nfat_arch); i++) 299 | { 300 | uint32_t archMetadataOffset = sizeof(fh) + sizeof(struct fat_arch) * i; 301 | 302 | struct fat_arch fatArch={0}; 303 | if(fseek(machoFile, archMetadataOffset, SEEK_SET)!=0)break; 304 | if(fread(&fatArch, sizeof(fatArch), 1, machoFile)!=1)break; 305 | 306 | if(fseek(machoFile, OSSwapBigToHostInt32(fatArch.offset), SEEK_SET)!=0)break; 307 | if(fread(&mh, sizeof(mh), 1, machoFile)!=1)break; 308 | 309 | if(mh.magic != MH_MAGIC_64 && mh.magic != MH_CIGAM_64) continue; //require Macho64 310 | 311 | if(!archEnumBlock(&mh, OSSwapBigToHostInt32(fatArch.offset))) 312 | break; 313 | } 314 | } 315 | else if(mh.magic == MH_MAGIC_64 || mh.magic == MH_CIGAM_64) //require Macho64 316 | { 317 | archEnumBlock(&mh, 0); 318 | } 319 | } 320 | 321 | void machoGetInfo(FILE* candidateFile, bool *isMachoOut, bool *isLibraryOut) 322 | { 323 | if (!candidateFile) return; 324 | 325 | __block bool isMacho=false; 326 | __block bool isLibrary = false; 327 | 328 | machoEnumerateArchs(candidateFile, ^bool(struct mach_header_64* header, uint32_t offset) { 329 | switch(OSSwapLittleToHostInt32(header->filetype)) { 330 | case MH_DYLIB: 331 | case MH_BUNDLE: 332 | isLibrary = true; 333 | case MH_EXECUTE: 334 | isMacho = true; 335 | return false; 336 | 337 | default: 338 | return true; 339 | } 340 | }); 341 | 342 | if (isMachoOut) *isMachoOut = isMacho; 343 | if (isLibraryOut) *isLibraryOut = isLibrary; 344 | } 345 | 346 | #define APP_PATH_PREFIX "/private/var/containers/Bundle/Application/" 347 | 348 | BOOL isDefaultInstallationPath(NSString* _path) 349 | { 350 | if(!_path) return NO; 351 | 352 | const char* path = _path.UTF8String; 353 | 354 | char rp[PATH_MAX]; 355 | if(!realpath(path, rp)) return NO; 356 | 357 | if(strncmp(rp, APP_PATH_PREFIX, sizeof(APP_PATH_PREFIX)-1) != 0) 358 | return NO; 359 | 360 | char* p1 = rp + sizeof(APP_PATH_PREFIX)-1; 361 | char* p2 = strchr(p1, '/'); 362 | if(!p2) return NO; 363 | 364 | //is normal app or jailbroken app/daemon? 365 | if((p2 - p1) != (sizeof("xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx")-1)) 366 | return NO; 367 | 368 | return YES; 369 | } 370 | 371 | void killAllForApp(const char* bundlePath) 372 | { 373 | SYSLOG("killBundleForPath: %s", bundlePath); 374 | 375 | char realBundlePath[PATH_MAX]; 376 | if(!realpath(bundlePath, realBundlePath)) 377 | return; 378 | 379 | static int maxArgumentSize = 0; 380 | if (maxArgumentSize == 0) { 381 | size_t size = sizeof(maxArgumentSize); 382 | if (sysctl((int[]){ CTL_KERN, KERN_ARGMAX }, 2, &maxArgumentSize, &size, NULL, 0) == -1) { 383 | perror("sysctl argument size"); 384 | maxArgumentSize = 4096; // Default 385 | } 386 | } 387 | int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL}; 388 | struct kinfo_proc *info; 389 | size_t length; 390 | size_t count; 391 | 392 | if (sysctl(mib, 3, NULL, &length, NULL, 0) < 0) 393 | return; 394 | if (!(info = malloc(length))) 395 | return; 396 | if (sysctl(mib, 3, info, &length, NULL, 0) < 0) { 397 | free(info); 398 | return; 399 | } 400 | count = length / sizeof(struct kinfo_proc); 401 | for (int i = 0; i < count; i++) { 402 | pid_t pid = info[i].kp_proc.p_pid; 403 | if (pid == 0) { 404 | continue; 405 | } 406 | size_t size = maxArgumentSize; 407 | char* buffer = (char *)malloc(length); 408 | if (sysctl((int[]){ CTL_KERN, KERN_PROCARGS2, pid }, 3, buffer, &size, NULL, 0) == 0) { 409 | char *executablePath = buffer + sizeof(int); 410 | //SYSLOG("executablePath [%d] %s", pid, executablePath); 411 | char realExecutablePath[PATH_MAX]; 412 | if (realpath(executablePath, realExecutablePath) 413 | && strncmp(realExecutablePath, realBundlePath, strlen(realBundlePath)) == 0) { 414 | kill(pid, SIGKILL); 415 | } 416 | } 417 | free(buffer); 418 | } 419 | free(info); 420 | } 421 | 422 | 423 | NSString* getBootSession() 424 | { 425 | const size_t maxUUIDLength = 37; 426 | char uuid[maxUUIDLength]={0}; 427 | size_t uuidLength = maxUUIDLength; 428 | sysctlbyname("kern.bootsessionuuid", uuid, &uuidLength, NULL, 0); 429 | 430 | return @(uuid); 431 | } 432 | -------------------------------------------------------------------------------- /Bootstrap/zstd_wrapper.m: -------------------------------------------------------------------------------- 1 | // 2 | // zstd_wrapper.m 3 | // 4 | // 5 | // Created by Lars Fröder on 23.04.23. 6 | // 7 | 8 | #import 9 | #import 10 | #include "common.h" 11 | 12 | #define BUFFER_SIZE 8192 13 | 14 | int decompress_tar_zstd(const char* src_file_path, const char* dst_file_path) { 15 | // Open the input file for reading 16 | FILE *input_file = fopen(src_file_path, "rb"); 17 | if (input_file == NULL) { 18 | SYSLOG("Failed to open input file %s: %s", src_file_path, strerror(errno)); 19 | return 40; 20 | } 21 | 22 | // Open the output file for writing 23 | FILE *output_file = fopen(dst_file_path, "wb"); 24 | if (output_file == NULL) { 25 | SYSLOG("Failed to open output file %s: %s", dst_file_path, strerror(errno)); 26 | fclose(input_file); 27 | return 41; 28 | } 29 | 30 | // Create a ZSTD decompression context 31 | ZSTD_DCtx *dctx = ZSTD_createDCtx(); 32 | if (dctx == NULL) { 33 | SYSLOG("Failed to create ZSTD decompression context"); 34 | fclose(input_file); 35 | fclose(output_file); 36 | return 42; 37 | } 38 | 39 | // Create a buffer for reading input data 40 | uint8_t *input_buffer = (uint8_t *) malloc(BUFFER_SIZE); 41 | if (input_buffer == NULL) { 42 | SYSLOG("Failed to allocate input buffer"); 43 | ZSTD_freeDCtx(dctx); 44 | fclose(input_file); 45 | fclose(output_file); 46 | return 43; 47 | } 48 | 49 | // Create a buffer for writing output data 50 | uint8_t *output_buffer = (uint8_t *) malloc(BUFFER_SIZE); 51 | if (output_buffer == NULL) { 52 | SYSLOG("Failed to allocate output buffer"); 53 | free(input_buffer); 54 | ZSTD_freeDCtx(dctx); 55 | fclose(input_file); 56 | fclose(output_file); 57 | return 44; 58 | } 59 | 60 | // Create a ZSTD decompression stream 61 | ZSTD_inBuffer in = {0}; 62 | ZSTD_outBuffer out = {0}; 63 | ZSTD_DStream *dstream = ZSTD_createDStream(); 64 | if (dstream == NULL) { 65 | SYSLOG("Failed to create ZSTD decompression stream"); 66 | free(output_buffer); 67 | free(input_buffer); 68 | ZSTD_freeDCtx(dctx); 69 | fclose(input_file); 70 | fclose(output_file); 71 | return 45; 72 | } 73 | 74 | // Initialize the ZSTD decompression stream 75 | size_t ret = ZSTD_initDStream(dstream); 76 | if (ZSTD_isError(ret)) { 77 | SYSLOG("Failed to initialize ZSTD decompression stream: %s", ZSTD_getErrorName(ret)); 78 | ZSTD_freeDStream(dstream); 79 | free(output_buffer); 80 | free(input_buffer); 81 | ZSTD_freeDCtx(dctx); 82 | fclose(input_file); 83 | fclose(output_file); 84 | return 46; 85 | } 86 | 87 | // Read and decompress the input file 88 | size_t total_bytes_read = 0; 89 | size_t total_bytes_written = 0; 90 | size_t bytes_read; 91 | size_t bytes_written; 92 | while (1) { 93 | // Read input data into the input buffer 94 | bytes_read = fread(input_buffer, 1, BUFFER_SIZE, input_file); 95 | if (bytes_read == 0) { 96 | if (feof(input_file)) { 97 | // End of input file reached, break out of loop 98 | break; 99 | } else { 100 | SYSLOG("Failed to read input file: %s", strerror(errno)); 101 | ZSTD_freeDStream(dstream); 102 | free(output_buffer); 103 | free(input_buffer); 104 | ZSTD_freeDCtx(dctx); 105 | fclose(input_file); 106 | fclose(output_file); 107 | return 47; 108 | } 109 | } 110 | 111 | in.src = input_buffer; 112 | in.size = bytes_read; 113 | in.pos = 0; 114 | 115 | while (in.pos < in.size) { 116 | // Initialize the output buffer 117 | out.dst = output_buffer; 118 | out.size = BUFFER_SIZE; 119 | out.pos = 0; 120 | 121 | // Decompress the input data 122 | ret = ZSTD_decompressStream(dstream, &out, &in); 123 | if (ZSTD_isError(ret)) { 124 | SYSLOG("Failed to decompress input data: %s", ZSTD_getErrorName(ret)); 125 | ZSTD_freeDStream(dstream); 126 | free(output_buffer); 127 | free(input_buffer); 128 | ZSTD_freeDCtx(dctx); 129 | fclose(input_file); 130 | fclose(output_file); 131 | return 48; 132 | } 133 | 134 | // Write the decompressed data to the output file 135 | bytes_written = fwrite(output_buffer, 1, out.pos, output_file); 136 | if (bytes_written != out.pos) { 137 | SYSLOG("Failed to write output file: %s", strerror(errno)); 138 | ZSTD_freeDStream(dstream); 139 | free(output_buffer); 140 | free(input_buffer); 141 | ZSTD_freeDCtx(dctx); 142 | fclose(input_file); 143 | fclose(output_file); 144 | return 49; 145 | } 146 | 147 | total_bytes_written += bytes_written; 148 | } 149 | 150 | total_bytes_read += bytes_read; 151 | } 152 | 153 | SYSLOG("Decompressed %lu bytes from %s to %lu bytes in %s", total_bytes_read, src_file_path, total_bytes_written, dst_file_path); 154 | 155 | // Clean up resources 156 | ZSTD_freeDStream(dstream); 157 | free(output_buffer); 158 | free(input_buffer); 159 | ZSTD_freeDCtx(dctx); 160 | fclose(input_file); 161 | fclose(output_file); 162 | 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 RootHide 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ARCHS = arm64 2 | TARGET = iphone:latest:15.0 3 | DEB_ARCH = iphoneos-arm64e 4 | IPHONEOS_DEPLOYMENT_TARGET = 15.0 5 | 6 | INSTALL_TARGET_PROCESSES = Bootstrap 7 | 8 | THEOS_PACKAGE_SCHEME = roothide 9 | 10 | THEOS_DEVICE_IP = iphone13.local 11 | 12 | #disable theos auto sign for all mach-o 13 | TARGET_CODESIGN = echo "don't sign" 14 | 15 | include $(THEOS)/makefiles/common.mk 16 | 17 | XCODE_SCHEME = Bootstrap 18 | 19 | XCODEPROJ_NAME = Bootstrap 20 | 21 | Bootstrap_XCODEFLAGS = MARKETING_VERSION=$(THEOS_PACKAGE_BASE_VERSION) \ 22 | IPHONEOS_DEPLOYMENT_TARGET="$(IPHONEOS_DEPLOYMENT_TARGET)" \ 23 | CODE_SIGN_IDENTITY="" \ 24 | AD_HOC_CODE_SIGNING_ALLOWED=YES 25 | Bootstrap_XCODE_SCHEME = $(XCODE_SCHEME) 26 | #Bootstrap_CODESIGN_FLAGS = -Sentitlements.plist 27 | Bootstrap_INSTALL_PATH = /Applications 28 | 29 | include $(THEOS_MAKE_PATH)/xcodeproj.mk 30 | 31 | clean:: 32 | rm -rf ./packages/* 33 | 34 | before-package:: 35 | rm -rf ./packages 36 | cp -a ./strapfiles ./.theos/_/Applications/Bootstrap.app/ 37 | ldid -Sentitlements.plist ./.theos/_/Applications/Bootstrap.app/Bootstrap 38 | mkdir -p ./packages/Payload 39 | cp -R ./.theos/_/Applications/Bootstrap.app ./packages/Payload 40 | cd ./packages && zip -mry ./Bootstrap.tipa ./Payload 41 | rm -rf ./.theos/_/Applications 42 | mkdir ./.theos/_/tmp 43 | cp ./packages/Bootstrap.tipa ./.theos/_/tmp/ 44 | 45 | after-install:: 46 | install.exec 'uiopen -b com.roothide.Bootstrap' 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bootstrap 2 | [![GitHub stars](https://img.shields.io/github/stars/RootHide/Bootstrap?style=social)](https://github.com/RootHide/Bootstrap/stargazers) 3 | 4 | 5 | A full featured bootstrap for ios14.0-17.0, A8-A17,M1+M2. (currently tested on ios15.0~ios17.0) 6 | 7 | ## Building 8 | 9 | You'll need MacOS to build, as you require Xcode Command Line Tools. If you don't have Xcode installed, you can install the Command Line Tools by itself by running `xcode-select --install`. 10 | 11 | 1. Update your theos to the this 12 | 13 | ```bash -c "$(curl -fsSL https://raw.githubusercontent.com/roothide/theos/master/bin/install-theos)"``` 14 | 15 | This build of Theos is consistently updated. 16 | 17 | 2. Build `Bootstrap.tipa` 18 | 19 | ```make package``` 20 | 21 | 3. Transfer `Bootstrap.tipa` from `./packages/` to your device and install it with TrollStore! 22 | 23 | ## Usage 24 | 25 | Once you open the Bootstrap app, press Bootstrap. This will install the necessary apps and files. 26 | 27 | You can add various sources to Sileo or Zebra, and install tweaks. You may need to convert tweaks to be Bootstrap compatible. 28 | 29 | By default, tweaks are not injected into any apps. To enable tweak injection, click AppEnabler in the Bootstrap app, and toggle on an app you want to enable your tweaks in. You *cannot* inject into SpringBoard (com.apple.springboard) or Photos (com.apple.mobileslideshow) at the moment. 30 | 31 | ## Develop tweaks 32 | 33 | [Document](https://github.com/RootHide/Developer) 34 | 35 | ## How to install tweaks? 36 | 37 | Bootstrap can enable tweaks for almost all apps, but it does not yet support springboard tweaks, such as the homescreen, lockscreen, control center, statusbar tweaks. 38 | 39 | When installing a tweak, you might see a message saying 'Not Updated'. This tweak will need to be updated to support Bootstrap. 40 | 41 | Install the Patcher in the sileo. When attempting to install a tweak, press 'Convert'. In the share sheet, press the Patcher app. When you convert a tweak to be Bootstrap compatible, you're given the option to directly convert simple tweaks or use rootless compat layer. If a tweak doesn't work with directly converting, try the rootless compat layer! You will need to install rootless-compat as a dependancy. 42 | 43 | ## I have a question that isn't listed here. Where do I go for help? 44 | 45 | You can join the our Discord [here](https://discord.com/invite/scqCkumAYp). 46 | 47 | ## Credits 48 | 49 | Huge thanks to these people, we couldn't have completed this project without their help! 50 | 51 | - absidue: [https://github.com/absidue](https://github.com/absidue) 52 | - akusio: [https://twitter.com/akusio_rr](https://twitter.com/akusio_rr) 53 | - Alfie: [https://alfiecg.uk](https://alfiecg.uk) 54 | - Amy While: [http://github.com/elihwyma](http://github.com/elihwyma) 55 | - Barron: [https://tweaksdev22.github.io](https://tweaksdev22.github.io) 56 | - BomberFish: [https://twitter.com/bomberfish77](https://twitter.com/bomberfish77) 57 | - bswbw: [https://twitter.com/bswbw](https://twitter.com/bswbw) 58 | - Capt Inc: [http://github.com/captinc](http://github.com/captinc) 59 | - CKatri: [https://procursus.social/@cameron](https://procursus.social/@cameron) 60 | - Clarity: [http://github.com/TheRealClarity](http://github.com/TheRealClarity) 61 | - Cryptic: [http://github.com/Cryptiiiic](http://github.com/Cryptiiiic) 62 | - dxcool223x: [https://twitter.com/dxcool223x](https://twitter.com/dxcool223x) 63 | - Dhinakg: [http://github.com/dhinakg](http://github.com/dhinakg) 64 | - DuyKhanhTran: [https://twitter.com/TranKha50277352](https://twitter.com/TranKha50277352) 65 | - dleovl: [https://github.com/dleovl](https://github.com/dleovl) 66 | - Elias Sfeir: [https://twitter.com/eliassfeir1](https://twitter.com/eliassfeir1) 67 | - Ellie: [https://twitter.com/elliessurviving](https://twitter.com/elliessurviving) 68 | - EquationGroups: [https://twitter.com/equationgroups](https://twitter.com/equationgroups) 69 | - Évelyne: [http://github.com/evelyneee](http://github.com/evelyneee) 70 | - GeoSnOw: [https://twitter.com/fce365](https://twitter.com/fce365) 71 | - G3n3sis: [https://twitter.com/G3nNuk_e](https://twitter.com/G3nNuk_e) 72 | - hayden: [https://procursus.social/@hayden](https://procursus.social/@hayden) 73 | - Huy Nguyen: [https://twitter.com/little_34306](https://twitter.com/little_34306) 74 | - iAdam1n: [https://twitter.com/iAdam1n](https://twitter.com/iAdam1n) 75 | - iarrays: [https://iarrays.com](https://iarrays.com) 76 | - iDownloadBlog: [https://twitter.com/idownloadblog](https://twitter.com/idownloadblog) 77 | - iExmo: [https://twitter.com/iexmojailbreak](https://twitter.com/iexmojailbreak) 78 | - iRaMzi: [https://twitter.com/iramzi7](https://twitter.com/iramzi7) 79 | - Jonathan: [https://twitter.com/jontelang](https://twitter.com/jontelang) 80 | - Kevin: [https://github.com/iodes](https://github.com/iodes) 81 | - kirb: [http://github.com/kirb](http://github.com/kirb) 82 | - laileld: [https://twitter.com/h_h_x_t](https://twitter.com/h_h_x_t) 83 | - Leptos: [https://github.com/leptos-null](https://github.com/leptos-null) 84 | - limneos: [https://twitter.com/limneos](https://twitter.com/limneos) 85 | - Lightmann: [https://github.com/L1ghtmann](https://github.com/L1ghtmann) 86 | - Linus Henze: [http://github.com/LinusHenze](http://github.com/LinusHenze) 87 | - MasterMike: [https://ios.cfw.guide](https://ios.cfw.guide) 88 | - Misty: [https://twitter.com/miscmisty](https://twitter.com/miscmisty) 89 | - Muirey03: [https://twitter.com/Muirey03](https://twitter.com/Muirey03) 90 | - Nathan: [https://github.com/verygenericname](https://github.com/verygenericname) 91 | - Nebula: [https://itsnebula.net](https://itsnebula.net) 92 | - niceios: [https://twitter.com/niceios](https://twitter.com/niceios) 93 | - Nightwind: [https://twitter.com/NightwindDev](https://twitter.com/NightwindDev) 94 | - Nick Chan: [https://nickchan.lol](https://nickchan.lol) 95 | - nzhaonan: [https://twitter.com/nzhaonan](https://twitter.com/nzhaonan) 96 | - omrkujman: [https://twitter.com/omrkujman](https://twitter.com/omrkujman) 97 | - opa334: [http://github.com/opa334](http://github.com/opa334) 98 | - onejailbreak: [https://twitter.com/onejailbreak_](https://twitter.com/onejailbreak_) 99 | - Phuc Do: [https://twitter.com/dobabaophuc](https://twitter.com/dobabaophuc) 100 | - PoomSmart: [https://twitter.com/poomsmart](https://twitter.com/poomsmart) 101 | - ProcursusTeam: [https://procursus.social/@team](https://procursus.social/@team) 102 | - roothide: [http://github.com/RootHide](http://github.com/RootHide) 103 | - Sam Bingner: [http://github.com/sbingner](http://github.com/sbingner) 104 | - Shadow-: [http://iosjb.top/](http://iosjb.top/) 105 | - Snail: [https://twitter.com/somnusix](https://twitter.com/somnusix) 106 | - SquidGesture: [https://twitter.com/lclrc](https://twitter.com/lclrc) 107 | - sourcelocation: [http://github.com/sourcelocation](http://github.com/sourcelocation) 108 | - SeanIsTethered: [http://github.com/jailbreakmerebooted](https://github.com/jailbreakmerebooted) 109 | - TheosTeam: [https://theos.dev](https://theos.dev) 110 | - tigisoftware: [https://twitter.com/tigisoftware](https://twitter.com/tigisoftware) 111 | - tihmstar: [https://twitter.com/tihmstar](https://twitter.com/tihmstar) 112 | - xina520: [https://twitter.com/xina520](https://twitter.com/xina520) 113 | - xybp888: [https://twitter.com/xybp888](https://twitter.com/xybp888) 114 | - xsf1re: [https://twitter.com/xsf1re](https://twitter.com/xsf1re) 115 | - yandevelop: [https://twitter.com/yandevelop](https://twitter.com/yandevelop) 116 | - YourRepo: [https://twitter.com/yourepo](https://twitter.com/yourepo) 117 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.roothide.bootstrap 2 | Name: RootHide Bootstrap 3 | Version: 0.1 4 | Architecture: iphoneos-arm64e 5 | Depends: firmware (>= 15.0) 6 | Description: RootHide Bootstrap for TrollStore 7 | Maintainer: RootHide 8 | Author: RootHide 9 | Section: System 10 | 11 | -------------------------------------------------------------------------------- /entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | platform-application 6 | 7 | com.apple.private.security.no-sandbox 8 | 9 | 10 | 19 | 20 | proc_info-allow 21 | 22 | 23 | com.apple.private.security.storage.AppBundles 24 | 25 | com.apple.private.security.storage.AppDataContainers 26 | 27 | 28 | com.apple.security.iokit-user-client-class 29 | 30 | AGXDeviceUserClient 31 | IOHDIXControllerUserClient 32 | IOSurfaceRootUserClient 33 | 34 | 35 | com.apple.private.persona-mgmt 36 | 37 | 38 | com.apple.security.exception.shared-preference.read-write 39 | 40 | com.roothide.Bootstrap 41 | com.roothide.Bootstrap.shared 42 | 43 | 44 | com.apple.private.MobileContainerManager.allowed 45 | 46 | 47 | com.apple.springboard.launchapplications 48 | 49 | com.apple.backboardd.launchapplications 50 | 51 | 52 | com.apple.lsapplicationworkspace.rebuildappdatabases 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /libkrw0-dummy.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/libkrw0-dummy.deb -------------------------------------------------------------------------------- /sileo.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/sileo.deb -------------------------------------------------------------------------------- /strapfiles/bootstrap-1800.tar.zst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/strapfiles/bootstrap-1800.tar.zst -------------------------------------------------------------------------------- /strapfiles/bootstrap-1900.tar.zst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/strapfiles/bootstrap-1900.tar.zst -------------------------------------------------------------------------------- /strapfiles/bootstrap-2000.tar.zst: -------------------------------------------------------------------------------- 1 | bootstrap-1900.tar.zst -------------------------------------------------------------------------------- /suid.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf2639 2 | \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} 3 | {\colortbl;\red255\green255\blue255;\red0\green0\blue0;} 4 | {\*\expandedcolortbl;;\csgray\c0;} 5 | \paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 6 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 7 | 8 | \f0\fs22 \cf2 \CocoaLigature0 /usr/bin/chpass\ 9 | /usr/bin/su\ 10 | /usr/bin/quota\ 11 | /usr/bin/sudo\ 12 | /usr/bin/login\ 13 | /usr/bin/passwd\ 14 | /usr/libexec/filza/Filza\ 15 | /usr/sbin/shshd\ 16 | \ 17 | } -------------------------------------------------------------------------------- /tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/tar -------------------------------------------------------------------------------- /zebra.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haxi0/BootstrapSwiftUI/4df315269ccab1febb5a858d160249f4351385d7/zebra.deb --------------------------------------------------------------------------------