├── .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 | [](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
--------------------------------------------------------------------------------