├── .github └── workflows │ └── build.yml ├── .gitignore ├── AppDelegate.h ├── AppDelegate.m ├── DecoratedAppSceneView.h ├── DecoratedAppSceneView.m ├── DecoratedFloatingView.h ├── DecoratedFloatingView.m ├── LICENSE ├── LauncherViewController.h ├── LauncherViewController.m ├── Makefile ├── README.md ├── Resources └── Info.plist ├── SceneDelegate.h ├── SceneDelegate.m ├── UIKitPrivate.h ├── ViewController.h ├── ViewController.m ├── ViewController.m_sb ├── ViewController.m_sb2 ├── control ├── entitlements.xml └── main.m /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | name: Build 10 | runs-on: macos-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@main 15 | 16 | - name: Checkout theos/theos 17 | uses: actions/checkout@main 18 | with: 19 | repository: theos/theos 20 | ref: master 21 | submodules: recursive 22 | path: theos 23 | 24 | - name: Checkout theos/sdks 25 | uses: actions/checkout@main 26 | with: 27 | repository: theos/sdks 28 | ref: master 29 | sparse-checkout: iPhoneOS16.5.sdk 30 | path: theos/sdks 31 | 32 | - name: Ensure main utils are installed 33 | uses: dhinakg/procursus-action@main 34 | with: 35 | packages: coreutils make xz ldid 36 | 37 | - name: Build 38 | run: | 39 | export THEOS=theos 40 | 41 | git submodule init 42 | git submodule update 43 | gmake package FINALPACKAGE=1 STRIP=0 44 | cd packages && mv *.ipa "`basename *.ipa .ipa`.tipa" 45 | 46 | - name: Upload artifact 47 | uses: actions/upload-artifact@main 48 | with: 49 | name: artifact 50 | path: packages/*.tipa 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/ 2 | packages/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // 4 | 5 | #import 6 | #import "UIKitPrivate.h" 7 | 8 | @interface AppDelegate : UIResponder 9 | 10 | @property(nonatomic) UIRootWindowScenePresentationBinder *binder; 11 | @property(strong, nonatomic) UIWindow *window; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "ViewController.h" 3 | 4 | @interface UIRootSceneWindow : UIWindow 5 | @end 6 | 7 | @implementation UIRootSceneWindow(hook) 8 | - (void)layoutSubviews { 9 | [super layoutSubviews]; 10 | self.layer.backgroundColor = UIColor.clearColor.CGColor; 11 | } 12 | 13 | - (CGFloat)windowLevel { 14 | return 10000; 15 | } 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | - (instancetype)init { 21 | self = [super init]; 22 | FBSMutableSceneDefinition *definition = [FBSMutableSceneDefinition definition]; 23 | definition.identity = [FBSSceneIdentity identityForIdentifier:NSBundle.mainBundle.bundleIdentifier]; 24 | definition.clientIdentity = [FBSSceneClientIdentity localIdentity]; 25 | definition.specification = [UIApplicationSceneSpecification specification]; 26 | FBSMutableSceneParameters *parameters = [FBSMutableSceneParameters parametersForSpecification:definition.specification]; 27 | 28 | UIMutableApplicationSceneSettings *settings = [UIMutableApplicationSceneSettings new]; 29 | settings.displayConfiguration = UIScreen.mainScreen.displayConfiguration; 30 | settings.frame = [UIScreen.mainScreen _referenceBounds]; 31 | settings.level = 1; 32 | settings.foreground = YES; 33 | settings.interfaceOrientation = UIInterfaceOrientationPortrait; 34 | settings.deviceOrientationEventsEnabled = YES; 35 | [settings.ignoreOcclusionReasons addObject:@"SystemApp"]; 36 | parameters.settings = settings; 37 | 38 | UIMutableApplicationSceneClientSettings *clientSettings = [UIMutableApplicationSceneClientSettings new]; 39 | clientSettings.interfaceOrientation = UIInterfaceOrientationPortrait; 40 | clientSettings.statusBarStyle = 0; 41 | parameters.clientSettings = clientSettings; 42 | 43 | FBScene *scene = [[FBSceneManager sharedInstance] createSceneWithDefinition:definition initialParameters:parameters]; 44 | self.binder = [[UIRootWindowScenePresentationBinder alloc] initWithPriority:0 displayConfiguration:settings.displayConfiguration]; 45 | [self.binder addScene:scene]; 46 | return self; 47 | } 48 | 49 | #pragma mark - UISceneSession lifecycle 50 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 51 | // Called when a new scene session is being created. 52 | // Use this method to select a configuration to create the new scene with. 53 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 54 | } 55 | 56 | 57 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 58 | // Called when the user discards a scene session. 59 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 60 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 61 | } 62 | 63 | - (void)applicationDidBecomeActive:(UIApplication *)application { 64 | } 65 | 66 | - (void)applicationDidEnterBackground:(UIApplication *)application { 67 | } 68 | 69 | - (void)applicationWillEnterForeground:(UIApplication *)application { 70 | } 71 | 72 | - (void)applicationWillResignActive:(UIApplication *)application { 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /DecoratedAppSceneView.h: -------------------------------------------------------------------------------- 1 | #import "UIKitPrivate.h" 2 | #import "DecoratedFloatingView.h" 3 | 4 | @interface DecoratedAppSceneView : DecoratedFloatingView 5 | @property(nonatomic) _UIScenePresenter *presenter; 6 | @property(nonatomic) UIMutableApplicationSceneSettings *settings; 7 | @property(nonatomic) UIApplicationSceneTransitionContext *transitionContext; 8 | @property(nonatomic) NSString *sceneID; 9 | 10 | - (instancetype)initWithBundleID:(LSApplicationProxy *)app; 11 | @end 12 | -------------------------------------------------------------------------------- /DecoratedAppSceneView.m: -------------------------------------------------------------------------------- 1 | #import "DecoratedAppSceneView.h" 2 | 3 | @implementation DecoratedAppSceneView 4 | - (instancetype)initWithBundleID:(LSApplicationProxy *)app{ 5 | self = [super initWithFrame:CGRectMake(0, 100, 400, 400)]; 6 | 7 | self.navigationBar.overrideUserInterfaceStyle = UIUserInterfaceStyleDark; 8 | [self.navigationBar.standardAppearance configureWithTransparentBackground]; 9 | self.navigationBar.standardAppearance.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; 10 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemClose target:self action:@selector(closeWindow)]; 11 | 12 | NSString *bundleID = app.bundleIdentifier; 13 | self.transitionContext = [UIApplicationSceneTransitionContext new]; 14 | RBSProcessIdentity* identity = [RBSProcessIdentity identityForEmbeddedApplicationIdentifier:bundleID]; 15 | RBSProcessPredicate* predicate = [RBSProcessPredicate predicateMatchingIdentity:identity]; 16 | 17 | FBProcessManager *manager = FBProcessManager.sharedInstance; 18 | FBApplicationProcessLaunchTransaction *transaction = [[FBApplicationProcessLaunchTransaction alloc] initWithProcessIdentity:identity executionContextProvider:^id(void){ 19 | FBMutableProcessExecutionContext *context = [FBMutableProcessExecutionContext new]; 20 | context.identity = identity; 21 | context.environment = @{}; // environment variables 22 | //context.waitForDebugger = NO; 23 | //context.disableASLR = NO; 24 | context.launchIntent = 4; 25 | //context.watchdogProvider = SBSceneWatchdogProvider 26 | return [manager launchProcessWithContext:context]; 27 | }]; 28 | 29 | [transaction setCompletionBlock:^{ 30 | // At this point, the process is spawned and we're ready to create a scene to render in our app 31 | RBSProcessHandle* processHandle = [RBSProcessHandle handleForPredicate:predicate error:nil]; 32 | [manager registerProcessForAuditToken:processHandle.auditToken]; 33 | // NSString *identifier = [NSString stringWithFormat:@"sceneID:%@-%@", bundleID, @"default"]; 34 | self.sceneID = [NSString stringWithFormat:@"sceneID:%@-%@", bundleID, @"default"]; 35 | 36 | 37 | FBSMutableSceneDefinition *definition = [FBSMutableSceneDefinition definition]; 38 | definition.identity = [FBSSceneIdentity identityForIdentifier:self.sceneID]; 39 | definition.clientIdentity = [FBSSceneClientIdentity identityForProcessIdentity:identity]; 40 | definition.specification = [UIApplicationSceneSpecification specification]; 41 | FBSMutableSceneParameters *parameters = [FBSMutableSceneParameters parametersForSpecification:definition.specification]; 42 | 43 | UIMutableApplicationSceneSettings *settings = [UIMutableApplicationSceneSettings new]; 44 | settings.canShowAlerts = YES; 45 | settings.cornerRadiusConfiguration = [[BSCornerRadiusConfiguration alloc] initWithTopLeft:self.layer.cornerRadius bottomLeft:self.layer.cornerRadius bottomRight:self.layer.cornerRadius topRight:self.layer.cornerRadius]; 46 | settings.displayConfiguration = UIScreen.mainScreen.displayConfiguration; 47 | settings.foreground = YES; 48 | settings.frame = self.bounds; 49 | settings.interfaceOrientation = UIInterfaceOrientationPortrait; 50 | //settings.interruptionPolicy = 2; // reconnect 51 | settings.level = 1; 52 | settings.peripheryInsets = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0); 53 | settings.persistenceIdentifier = NSUUID.UUID.UUIDString; 54 | settings.safeAreaInsetsPortrait = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0); 55 | //settings.statusBarDisabled = 1; 56 | //settings.previewMaximumSize = 57 | //settings.deviceOrientationEventsEnabled = YES; 58 | self.settings = settings; 59 | parameters.settings = settings; 60 | 61 | UIMutableApplicationSceneClientSettings *clientSettings = [UIMutableApplicationSceneClientSettings new]; 62 | clientSettings.interfaceOrientation = UIInterfaceOrientationPortrait; 63 | clientSettings.statusBarStyle = 0; 64 | parameters.clientSettings = clientSettings; 65 | 66 | FBScene *scene = [[FBSceneManager sharedInstance] createSceneWithDefinition:definition initialParameters:parameters]; 67 | 68 | self.navigationItem.title = app.localizedName; 69 | 70 | self.presenter = [scene.uiPresentationManager createPresenterWithIdentifier:self.sceneID]; 71 | [self.presenter activate]; 72 | [self insertSubview:self.presenter.presentationView atIndex:0]; 73 | }]; 74 | [transaction begin]; 75 | return self; 76 | } 77 | 78 | - (void)closeWindow { 79 | self.layer.masksToBounds = NO; 80 | [UIView transitionWithView:self duration:0.4 options:UIViewAnimationOptionTransitionCurlUp animations:^{ 81 | self.hidden = YES; 82 | } completion:^(BOOL b){ 83 | [[FBSceneManager sharedInstance] destroyScene:self.sceneID withTransitionContext:nil]; 84 | if(self.presenter){ 85 | [self.presenter deactivate]; 86 | [self.presenter invalidate]; 87 | self.presenter = nil; 88 | } 89 | [self removeFromSuperview]; 90 | }]; 91 | } 92 | 93 | - (void)resizeWindow:(UIPanGestureRecognizer*)sender { 94 | [super resizeWindow:sender]; 95 | 96 | self.settings.frame = self.bounds; 97 | [self.presenter.scene updateSettings:self.settings withTransitionContext:self.transitionContext completion:nil]; 98 | } 99 | @end 100 | -------------------------------------------------------------------------------- /DecoratedFloatingView.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface DecoratedFloatingView : UIView 4 | 5 | @property(nonatomic) UINavigationBar *navigationBar; 6 | @property(nonatomic) UINavigationItem *navigationItem; 7 | @property(nonatomic) UIView *resizeHandle; 8 | 9 | - (instancetype)initWithFrame:(CGRect)frame navigationBar:(UINavigationBar *)navigationBar; 10 | 11 | - (void)moveWindow:(UIPanGestureRecognizer*)sender; 12 | - (void)resizeWindow:(UIPanGestureRecognizer*)sender; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /DecoratedFloatingView.m: -------------------------------------------------------------------------------- 1 | #import "DecoratedFloatingView.h" 2 | 3 | @implementation DecoratedFloatingView 4 | 5 | - (instancetype)initWithFrame:(CGRect)frame { 6 | // Navigation bar 7 | UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 44)]; 8 | navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; 9 | UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Unnamed window"]; 10 | navigationBar.items = @[navigationItem]; 11 | return [self initWithFrame:frame navigationBar:navigationBar]; 12 | } 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame navigationBar:(UINavigationBar *)navigationBar { 15 | self = [super initWithFrame:frame]; 16 | self.layer.cornerRadius = 10; 17 | self.layer.masksToBounds = YES; 18 | 19 | self.navigationBar = navigationBar; 20 | self.navigationItem = navigationBar.items.firstObject; 21 | if (!self.navigationBar.superview) { 22 | [self addSubview:self.navigationBar]; 23 | } 24 | 25 | UIPanGestureRecognizer *moveGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveWindow:)]; 26 | moveGesture.minimumNumberOfTouches = 1; 27 | moveGesture.maximumNumberOfTouches = 1; 28 | [self.navigationBar addGestureRecognizer:moveGesture]; 29 | 30 | // Resize handle (idea stolen from Notes debugging window) 31 | self.resizeHandle = [[UIView alloc] initWithFrame:CGRectMake(self.frame.size.width - 30, self.frame.size.height - 30, 60, 60)]; 32 | self.resizeHandle.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2]; 33 | self.resizeHandle.transform = CGAffineTransformMakeRotation(M_PI_4); 34 | [self addSubview:self.resizeHandle]; 35 | UIPanGestureRecognizer *resizeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(resizeWindow:)]; 36 | resizeGesture.minimumNumberOfTouches = 1; 37 | resizeGesture.maximumNumberOfTouches = 1; 38 | [self.resizeHandle addGestureRecognizer:resizeGesture]; 39 | return self; 40 | } 41 | 42 | - (void)moveWindow:(UIPanGestureRecognizer*)sender { 43 | if (sender.state == UIGestureRecognizerStateBegan) { 44 | [self.superview 45 | 46 | bringSubviewToFront:self]; 47 | } 48 | 49 | CGPoint point = [sender translationInView:self]; 50 | [sender setTranslation:CGPointZero inView:self]; 51 | 52 | self.center = CGPointMake(self.center.x + point.x, self.center.y + point.y); 53 | } 54 | 55 | - (void)resizeWindow:(UIPanGestureRecognizer*)sender { 56 | CGPoint point = [sender translationInView:self]; 57 | [sender setTranslation:CGPointZero inView:self]; 58 | 59 | CGRect frame = self.frame; 60 | frame.size.width = MAX(50, frame.size.width + point.x); 61 | frame.size.height = MAX(50, frame.size.height + point.y); 62 | self.frame = frame; 63 | self.resizeHandle.center = CGPointMake(self.resizeHandle.center.x + point.x, self.resizeHandle.center.y + point.y); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LauncherViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "UIKitPrivate.h" 3 | 4 | @interface LauncherViewController : UITableViewController 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /LauncherViewController.m: -------------------------------------------------------------------------------- 1 | #import "DecoratedAppSceneView.h" 2 | #import "LauncherViewController.h" 3 | #import "ViewController.h" 4 | 5 | @interface LauncherViewController () 6 | @property(nonatomic) NSMutableArray *apps; 7 | @end 8 | 9 | @implementation LauncherViewController 10 | -(void)loadView { 11 | [super loadView]; 12 | self.view.backgroundColor = UIColor.systemBackgroundColor; 13 | self.title = @"FrontBoardAppLauncher"; 14 | 15 | self.apps = [[NSMutableArray alloc] init]; 16 | NSArray *app_list = [LSApplicationWorkspace.defaultWorkspace allInstalledApplications]; 17 | for (LSApplicationProxy *app in app_list) { 18 | if ([app.applicationType isEqual:@"User"] || ([app.applicationType isEqual:@"System"] && ![app.appTags containsObject:@"hidden"] && !app.launchProhibited && !app.placeholder && !app.removedSystemApp)) { 19 | [self.apps addObject:app]; 20 | } 21 | } 22 | [self.apps sortUsingDescriptors:@[ 23 | [NSSortDescriptor sortDescriptorWithKey:@"localizedName" ascending:YES], 24 | ]]; 25 | } 26 | 27 | -(UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 28 | NSString *cellID = @"Cell"; 29 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 30 | if (cell == nil) { 31 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; 32 | } 33 | 34 | cell.textLabel.text = self.apps[indexPath.row].localizedName; 35 | cell.detailTextLabel.text = self.apps[indexPath.row].bundleIdentifier; 36 | cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:cell.detailTextLabel.text format:0 scale:UIScreen.mainScreen.scale]; 37 | return cell; 38 | } 39 | 40 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 41 | [tableView deselectRowAtIndexPath:indexPath animated:NO]; 42 | DecoratedAppSceneView *view = [[DecoratedAppSceneView alloc] initWithBundleID:self.apps[indexPath.row]]; 43 | CGRect origFrame = view.frame; 44 | CGRect cellFrame = view.frame; 45 | 46 | UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 47 | cellFrame.origin = [cell.superview convertPoint:cell.frame.origin toView:self.navigationController.parentViewController.view]; 48 | cellFrame.size = cell.frame.size; 49 | 50 | view.alpha = 0; 51 | view.frame = cellFrame; 52 | view.backgroundColor = [UIColor blackColor]; 53 | [self.navigationController.parentViewController.view addSubview:view]; 54 | [UIView animateWithDuration:0.4 55 | animations:^{ 56 | view.alpha = 1; 57 | view.frame = origFrame; 58 | } completion:nil]; 59 | } 60 | 61 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 62 | return 1; 63 | } 64 | 65 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 66 | return self.apps.count; 67 | } 68 | @end 69 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ARCHS := arm64 2 | PACKAGE_FORMAT := ipa 3 | TARGET := iphone:clang:16.5:15.0 4 | 5 | include $(THEOS)/makefiles/common.mk 6 | 7 | APPLICATION_NAME = FrontBoardAppLauncher 8 | 9 | FrontBoardAppLauncher_FILES = \ 10 | AppDelegate.m \ 11 | DecoratedAppSceneView.m \ 12 | DecoratedFloatingView.m \ 13 | LauncherViewController.m \ 14 | SceneDelegate.m \ 15 | ViewController.m \ 16 | main.m 17 | FrontBoardAppLauncher_FRAMEWORKS = UIKit 18 | FrontBoardAppLauncher_PRIVATE_FRAMEWORKS = CoreServices FrontBoard RunningBoardServices 19 | FrontBoardAppLauncher_CFLAGS = -fcommon -fobjc-arc -Iinclude -I. -Wno-error 20 | # FrontBoardAppLauncher_LDFLAGS = 21 | FrontBoardAppLauncher_CODESIGN_FLAGS = -Sentitlements.xml 22 | 23 | include $(THEOS_MAKE_PATH)/application.mk 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FrontBoardAppLauncher 2 | Reference usage of FrontBoard & UIKit private API to display external app scene. 3 | 4 | This app implements multitasking. 5 | 6 | ## Supported iOS versions 7 | Requires TrollStore. 8 | 9 | iOS 15.0+ are supported. 10 | 11 | iOS 14.x is not yet supported. There is an issue in FrontBoard. 12 | 13 | ## Known issues 14 | - Apps stay running even after closing 15 | - In-app keyboard offset may be off 16 | - Keyboard doesn't work when windowed on top of SpringBoard yet 17 | - Re-opening an app after closing may crash 18 | - Single-scene apps may not work yet. You may see empty window in such cases. 19 | -------------------------------------------------------------------------------- /Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BSServiceDomains 6 | 7 | com.apple.frontboard 8 | 9 | DerivedServiceRestrictions 10 | 11 | com.apple.uis.applicationStateService 12 | com.apple.uis.applicationSupportService 13 | com.apple.frontboard.layout-monitor 14 | 15 | Services 16 | 17 | com.apple.frontboard.system-service 18 | 19 | com.apple.frontboard.workspace-service 20 | 21 | 22 | 23 | 24 | CFBundleDevelopmentRegion 25 | en 26 | CFBundleDisplayName 27 | FrontBoardAppLauncher 28 | CFBundleExecutable 29 | FrontBoardAppLauncher 30 | CFBundleIcons 31 | 32 | CFBundlePrimaryIcon 33 | 34 | CFBundleIconFiles 35 | 36 | AppIcon60x60 37 | 38 | CFBundleIconName 39 | AppIcon 40 | 41 | 42 | CFBundleIcons~ipad 43 | 44 | CFBundlePrimaryIcon 45 | 46 | CFBundleIconFiles 47 | 48 | AppIcon60x60 49 | AppIcon76x76 50 | 51 | CFBundleIconName 52 | AppIcon 53 | 54 | 55 | CFBundleIdentifier 56 | com.kdt.frontboardapplauncher 57 | CFBundleInfoDictionaryVersion 58 | 6.0 59 | CFBundleName 60 | FrontBoardAppLauncher 61 | CFBundlePackageType 62 | APPL 63 | CFBundleShortVersionString 64 | 1.3 65 | CFBundleSignature 66 | ???? 67 | CFBundleVersion 68 | 2 69 | LSRequiresIPhoneOS 70 | 71 | LSSupportsOpeningDocumentsInPlace 72 | 73 | MinimumOSVersion 74 | 12.0 75 | UIApplicationSceneManifest 76 | 77 | UIApplicationSupportsMultipleScenes 78 | 79 | UISceneConfigurations 80 | 81 | UIWindowSceneSessionRoleApplication 82 | 83 | 84 | UISceneConfigurationName 85 | Default Configuration 86 | UISceneDelegateClassName 87 | SceneDelegate 88 | 89 | 90 | 91 | 92 | UIApplicationSupportsIndirectInputEvents 93 | 94 | UIFileSharingEnabled 95 | 96 | UILaunchStoryboardName 97 | LaunchScreen 98 | UIRequiredDeviceCapabilities 99 | 100 | arm64 101 | 102 | UISupportedInterfaceOrientations 103 | 104 | UIInterfaceOrientationLandscapeLeft 105 | UIInterfaceOrientationLandscapeRight 106 | UIInterfaceOrientationPortraitLeft 107 | UIInterfaceOrientationPortraitRight 108 | 109 | UISupportedInterfaceOrientations~ipad 110 | 111 | UIInterfaceOrientationLandscapeLeft 112 | UIInterfaceOrientationLandscapeRight 113 | UIInterfaceOrientationPortraitLeft 114 | UIInterfaceOrientationPortraitRight 115 | 116 | UIViewControllerBasedStatusBarAppearance 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /SceneDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface SceneDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow * window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /SceneDelegate.m: -------------------------------------------------------------------------------- 1 | #import "SceneDelegate.h" 2 | #import "ViewController.h" 3 | 4 | @implementation UINavigationBar(forceFullHeightInLandscape) 5 | 6 | - (BOOL)forceFullHeightInLandscape { 7 | return YES; 8 | } 9 | 10 | @end 11 | 12 | @interface SceneDelegate () 13 | 14 | @end 15 | 16 | @implementation SceneDelegate 17 | 18 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 19 | UIWindowScene *windowScene = (UIWindowScene *)scene; 20 | self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; 21 | self.window.frame = windowScene.coordinateSpace.bounds; 22 | self.window.rootViewController = [ViewController new]; 23 | [self.window makeKeyAndVisible]; 24 | } 25 | 26 | 27 | - (void)sceneDidDisconnect:(UIScene *)scene { 28 | // Called as the scene is being released by the system. 29 | // This occurs shortly after the scene enters the background, or when its session is discarded. 30 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 31 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 32 | } 33 | 34 | 35 | - (void)sceneDidBecomeActive:(UIScene *)scene { 36 | // Called when the scene has moved from an inactive state to an active state. 37 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 38 | } 39 | 40 | 41 | - (void)sceneWillResignActive:(UIScene *)scene { 42 | // Called when the scene will move from an active state to an inactive state. 43 | // This may occur due to temporary interruptions (ex. an incoming phone call). 44 | } 45 | 46 | 47 | - (void)sceneWillEnterForeground:(UIScene *)scene { 48 | // Called as the scene transitions from the background to the foreground. 49 | // Use this method to undo the changes made on entering the background. 50 | } 51 | 52 | 53 | - (void)sceneDidEnterBackground:(UIScene *)scene { 54 | // Called as the scene transitions from the foreground to the background. 55 | // Use this method to save data, release shared resources, and store enough scene-specific state information 56 | // to restore the scene back to its current state. 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /UIKitPrivate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef struct { 4 | unsigned val[8]; 5 | } SCD_Struct_RB3; 6 | 7 | @interface LSResourceProxy : NSObject 8 | @property (setter=_setLocalizedName:,nonatomic,copy) NSString *localizedName; 9 | @end 10 | 11 | @interface LSBundleProxy : LSResourceProxy 12 | @end 13 | 14 | @interface LSApplicationProxy : LSBundleProxy 15 | @property(nonatomic, assign, readonly) NSString *bundleIdentifier; 16 | @property(nonatomic, assign, readonly) NSString *localizedShortName; 17 | @property(nonatomic, assign, readonly) NSString *primaryIconName; 18 | 19 | @property (nonatomic,readonly) NSString * applicationIdentifier; 20 | @property (nonatomic,readonly) NSString * applicationType; 21 | @property (nonatomic,readonly) NSArray * appTags; 22 | @property (getter=isLaunchProhibited,nonatomic,readonly) BOOL launchProhibited; 23 | @property (getter=isPlaceholder,nonatomic,readonly) BOOL placeholder; 24 | @property (getter=isRemovedSystemApp,nonatomic,readonly) BOOL removedSystemApp; 25 | @end 26 | 27 | @interface LSApplicationWorkspace : NSObject 28 | + (instancetype)defaultWorkspace; 29 | - (NSArray *)allInstalledApplications; 30 | @end 31 | 32 | @interface BSCornerRadiusConfiguration : NSObject 33 | - (id)initWithTopLeft:(CGFloat)tl bottomLeft:(CGFloat)bl bottomRight:(CGFloat)br topRight:(CGFloat)tr; 34 | @end 35 | 36 | // BoardServices 37 | @interface BSSettings : NSObject 38 | @end 39 | 40 | @interface BSTransaction : NSObject 41 | - (void)addChildTransaction:(id)transaction; 42 | - (void)begin; 43 | - (void)setCompletionBlock:(dispatch_block_t)block; 44 | @end 45 | 46 | // FrontBoard 47 | 48 | @class RBSProcessIdentity, FBProcessExecutableSlice, UIMutableApplicationSceneSettings, UIMutableApplicationSceneClientSettings, UIScenePresentationManager, _UIScenePresenter; 49 | 50 | @interface FBApplicationProcessLaunchTransaction : BSTransaction 51 | - (instancetype) initWithProcessIdentity:(RBSProcessIdentity *)identity executionContextProvider:(id)providerBlock; 52 | - (void)_begin; 53 | @end 54 | 55 | @interface FBProcessExecutionContext : NSObject 56 | @end 57 | 58 | @interface FBMutableProcessExecutionContext : FBProcessExecutionContext 59 | 60 | @property (nonatomic,copy) RBSProcessIdentity * identity; 61 | @property (nonatomic,copy) NSArray * arguments; 62 | @property (nonatomic,copy) NSDictionary * environment; 63 | @property (nonatomic,retain) NSURL * standardOutputURL; 64 | @property (nonatomic,retain) NSURL * standardErrorURL; 65 | @property (assign,nonatomic) BOOL waitForDebugger; 66 | @property (assign,nonatomic) BOOL disableASLR; 67 | @property (assign,nonatomic) BOOL checkForLeaks; 68 | @property (assign,nonatomic) long long launchIntent; 69 | //@property (nonatomic,retain) id watchdogProvider; 70 | @property (nonatomic,copy) NSString * overrideExecutablePath; 71 | //@property (nonatomic,retain) FBProcessExecutableSlice * overrideExecutableSlice; 72 | @property (nonatomic,copy) id completion; 73 | -(id)copyWithZone:(NSZone*)arg1 ; 74 | @end 75 | 76 | @interface FBProcess : NSObject 77 | - (id)name; 78 | @end 79 | 80 | @interface FBScene : NSObject 81 | - (FBProcess *)clientProcess; 82 | - (UIScenePresentationManager *)uiPresentationManager; 83 | - (void)updateSettings:(UIMutableApplicationSceneSettings *)settings withTransitionContext:(id)context completion:(id)completion; 84 | @end 85 | 86 | @interface FBDisplayManager : NSObject 87 | + (instancetype)sharedInstance; 88 | - (id)mainConfiguration; 89 | @end 90 | 91 | @interface FBSSceneClientIdentity : NSObject 92 | + (instancetype)identityForBundleID:(NSString *)bundleID; 93 | + (instancetype)identityForProcessIdentity:(RBSProcessIdentity *)identity; 94 | + (instancetype)localIdentity; 95 | @end 96 | 97 | @interface FBProcessManager : NSObject 98 | + (instancetype)sharedInstance; 99 | - (FBProcessExecutionContext *)launchProcessWithContext:(FBMutableProcessExecutionContext *)context; 100 | - (void)registerProcessForAuditToken:(SCD_Struct_RB3)token; 101 | @end 102 | 103 | @interface FBSSceneSpecification : NSObject 104 | + (instancetype)specification; 105 | @end 106 | 107 | // RunningBoardServices 108 | @interface RBSProcessIdentity : NSObject 109 | + (instancetype)identityForEmbeddedApplicationIdentifier:(NSString *)identifier; 110 | @end 111 | 112 | @interface RBSProcessPredicate 113 | + (instancetype)predicateMatchingIdentity:(RBSProcessIdentity *)identity; 114 | @end 115 | 116 | @interface RBSProcessHandle 117 | + (instancetype)handleForPredicate:(RBSProcessPredicate *)predicate error:(NSError **)error; 118 | - (SCD_Struct_RB3)auditToken; 119 | @end 120 | 121 | @interface UIApplicationSceneSpecification : FBSSceneSpecification 122 | @end 123 | 124 | @interface FBSSceneIdentity : NSObject 125 | + (instancetype)identityForIdentifier:(NSString *)id; 126 | @end 127 | 128 | // FBSSceneSettings 129 | @interface UIMutableApplicationSceneSettings : NSObject 130 | @property(nonatomic, assign, readwrite) BOOL canShowAlerts; 131 | @property(nonatomic, assign) BOOL deviceOrientationEventsEnabled; 132 | @property(nonatomic, assign, readwrite) NSInteger interruptionPolicy; 133 | @property(nonatomic, strong, readwrite) NSString *persistenceIdentifier; 134 | @property (nonatomic, assign, readwrite) UIEdgeInsets peripheryInsets; 135 | @property (nonatomic, assign, readwrite) UIEdgeInsets safeAreaInsetsPortrait, safeAreaInsetsPortraitUpsideDown, safeAreaInsetsLandscapeLeft, safeAreaInsetsLandscapeRight; 136 | @property (nonatomic, strong, readwrite) BSCornerRadiusConfiguration *cornerRadiusConfiguration; 137 | - (id)displayConfiguration; 138 | - (CGRect)frame; 139 | - (NSMutableSet *)ignoreOcclusionReasons; 140 | - (void)setDisplayConfiguration:(id)c; 141 | - (void)setForeground:(BOOL)f; 142 | - (void)setFrame:(CGRect)frame; 143 | - (void)setLevel:(NSInteger)level; 144 | - (void)setStatusBarDisabled:(BOOL)disabled; 145 | - (void)setInterfaceOrientation:(NSInteger)o; 146 | - (BSSettings *)otherSettings; 147 | @end 148 | 149 | @interface FBSSceneParameters : NSObject 150 | @property(nonatomic, copy) UIMutableApplicationSceneSettings *settings; 151 | @property(nonatomic, copy) UIMutableApplicationSceneClientSettings *clientSettings; 152 | + (instancetype)parametersForSpecification:(FBSSceneSpecification *)spec; 153 | //- (void)updateSettingsWithBlock:(id)block; 154 | @end 155 | 156 | @interface FBSMutableSceneParameters : FBSSceneParameters 157 | //- (void)updateClientSettingsWithBlock:(id)block; 158 | @end 159 | 160 | @interface FBSMutableSceneDefinition : NSObject 161 | @property(nonatomic, copy) FBSSceneClientIdentity *clientIdentity; 162 | @property(nonatomic, copy) FBSSceneIdentity *identity; 163 | @property(nonatomic, copy) FBSSceneSpecification *specification; 164 | + (instancetype)definition; 165 | @end 166 | 167 | @interface FBSceneManager : NSObject 168 | + (instancetype)sharedInstance; 169 | - (FBScene *)createSceneWithDefinition:(id)def initialParameters:(id)params; 170 | -(void)destroyScene:(id)arg1 withTransitionContext:(id)arg2 ; 171 | @end 172 | 173 | @interface UIImage(internal) 174 | + (instancetype)_applicationIconImageForBundleIdentifier:(NSString *)bundleID format:(NSInteger)format scale:(CGFloat)scale; 175 | @end 176 | 177 | // UIKit 178 | @interface UIApplicationSceneTransitionContext : NSObject 179 | @end 180 | 181 | @interface UIMutableApplicationSceneClientSettings : NSObject 182 | @property(nonatomic, assign) NSInteger interfaceOrientation; 183 | @property(nonatomic, assign) NSInteger statusBarStyle; 184 | @end 185 | 186 | @interface UIWindow (Private) 187 | - (instancetype)_initWithFrame:(CGRect)frame attached:(BOOL)attached; 188 | - (void)orderFront:(id)arg1; 189 | @end 190 | 191 | @interface UIScreen (Private) 192 | - (CGRect)_referenceBounds; 193 | - (id)displayConfiguration; 194 | @end 195 | 196 | @interface UIScenePresentationBinder : NSObject 197 | - (void)addScene:(id)scene; 198 | @end 199 | 200 | @interface UIScenePresentationManager : NSObject 201 | - (instancetype)_initWithScene:(FBScene *)scene; 202 | - (_UIScenePresenter *)createPresenterWithIdentifier:(NSString *)identifier; 203 | @end 204 | 205 | @interface _UIScenePresenterOwner : NSObject 206 | - (instancetype)initWithScenePresentationManager:(UIScenePresentationManager *)manager context:(FBScene *)scene; 207 | @end 208 | 209 | @interface _UIScenePresentationView : UIView 210 | //- (instancetype)initWithPresenter:(_UIScenePresenter *)presenter; 211 | @end 212 | 213 | @interface _UIScenePresenter : NSObject 214 | @property (nonatomic, assign, readonly) _UIScenePresentationView *presentationView; 215 | @property(nonatomic, assign, readonly) FBScene *scene; 216 | - (instancetype)initWithOwner:(_UIScenePresenterOwner *)manager identifier:(NSString *)scene sortContext:(NSNumber *)context; 217 | - (void)activate; 218 | - (void)deactivate; 219 | - (void)invalidate; 220 | @end 221 | 222 | @interface UIRootWindowScenePresentationBinder : UIScenePresentationBinder 223 | - (instancetype)initWithPriority:(int)pro displayConfiguration:(id)c; 224 | @end 225 | 226 | @interface UIScenePresentationContext : NSObject 227 | - (UIScenePresentationContext *)_initWithDefaultValues; 228 | @end 229 | 230 | @interface _UISceneLayerHostContainerView : UIView 231 | - (instancetype)initWithScene:(FBScene *)scene debugDescription:(NSString *)desc; 232 | - (void)_setPresentationContext:(UIScenePresentationContext *)context; 233 | @end 234 | 235 | @interface UIApplication() 236 | - (void)launchApplicationWithIdentifier:(NSString *)identifier suspended:(BOOL)suspended; 237 | @end 238 | 239 | // PreviewsServicesUI 240 | @interface UVInjectedScene: NSObject 241 | @property(nonatomic, assign, readonly) FBScene *scene; 242 | @property(nonatomic, assign, readonly) NSString *sceneIdentifier; 243 | + (instancetype)injectInProcess:(NSInteger)pid error:(NSError **)error; 244 | + (instancetype)_injectInProcessHandle:(RBSProcessHandle *)process error:(NSError **)error; 245 | @end 246 | 247 | @interface UVSceneHost : UIView 248 | + (instancetype)createWithInjectedScene:(UVInjectedScene *)scene error:(NSError **)error; 249 | @end 250 | -------------------------------------------------------------------------------- /ViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "UIKitPrivate.h" 3 | 4 | @interface ViewController : UIViewController 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ViewController.m: -------------------------------------------------------------------------------- 1 | #import "DecoratedAppSceneView.h" 2 | #import "LauncherViewController.h" 3 | #import "ViewController.h" 4 | 5 | @interface ViewController () 6 | @property(nonatomic) FBApplicationProcessLaunchTransaction *transaction; 7 | @property(nonatomic) UIScenePresentationManager *presentationManager; 8 | @end 9 | 10 | @implementation ViewController 11 | 12 | - (void)loadView { 13 | [super loadView]; 14 | //self.view.backgroundColor = UIColor.systemBackgroundColor; 15 | self.title = @"FrontBoardAppLauncher"; 16 | 17 | LauncherViewController *launcherVC = [LauncherViewController new]; 18 | 19 | UINavigationController* navigationVC = [[UINavigationController alloc] initWithRootViewController:launcherVC]; 20 | navigationVC.modalPresentationStyle = UIModalPresentationCurrentContext; 21 | [self addChildViewController:navigationVC]; 22 | 23 | DecoratedFloatingView *launcherView = [[DecoratedFloatingView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) navigationBar:navigationVC.navigationBar]; 24 | launcherView.center = self.view.center; 25 | launcherView.navigationItem.title = @"FrontBoardAppLauncher"; 26 | [launcherView insertSubview:navigationVC.view atIndex:0]; 27 | [self.view addSubview:launcherView]; 28 | navigationVC.view.frame = launcherView.bounds; 29 | [navigationVC didMoveToParentViewController:self]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /ViewController.m_sb: -------------------------------------------------------------------------------- 1 | // Ignore this file unless you're going to mess around SpringBoard 2 | 3 | #import "ViewController.h" 4 | #import "UIKitPrivate.h" 5 | #include 6 | #include 7 | #include 8 | 9 | void showDialog(UIViewController *viewController, NSString* title, NSString* message) { 10 | UIAlertController* alert = [UIAlertController alertControllerWithTitle:title 11 | message:message 12 | preferredStyle:UIAlertControllerStyleAlert]; 13 | //text.dataDetectorTypes = UIDataDetectorTypeLink; 14 | UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; 15 | [alert addAction:okAction]; 16 | 17 | [viewController presentViewController:alert animated:YES completion:nil]; 18 | } 19 | 20 | @interface UIScenePresentationContext : NSObject 21 | - (UIScenePresentationContext *)_initWithDefaultValues; 22 | @end 23 | 24 | @interface _UISceneLayerHostContainerView : UIView 25 | - (instancetype)initWithScene:(FBScene *)scene debugDescription:(NSString *)desc; 26 | - (void)_setPresentationContext:(UIScenePresentationContext *)context; 27 | @end 28 | 29 | @interface UIApplication() 30 | - (void)launchApplicationWithIdentifier:(NSString *)identifier suspended:(BOOL)suspended; 31 | @end 32 | 33 | @interface ViewController () 34 | @property(nonatomic) UIScenePresentationManager *presentationManager; 35 | @property(nonatomic) _UIScenePresenter *presenter; 36 | @property(nonatomic) _UIScenePresenterOwner *owner; 37 | //UVInjectedScene *uvScene; 38 | @end 39 | 40 | @implementation ViewController 41 | 42 | - (void)viewDidLoad { 43 | [super viewDidLoad]; 44 | self.view.backgroundColor = UIColor.systemBackgroundColor; 45 | self.title = @"FrontBoardAppLauncher"; 46 | 47 | // PreviewsServicesUI 48 | // [UVInjectedScene injectInProcess:PID error:&error]; 49 | // [UVInjectedScene _injectInProcessHandle:handle error:&error]; 50 | 51 | NSString *bundleID = @"com.apple.SpringBoard"; 52 | [self launch:bundleID]; 53 | 54 | RBSProcessIdentity* identity = [RBSProcessIdentity identityForDaemonJobLabel:bundleID]; 55 | //identityForApplicationJobLabel:nil bundleID:bundleID platform:2]; 56 | RBSProcessPredicate* predicate = [RBSProcessPredicate predicateMatchingIdentity:identity]; 57 | RBSProcessHandle* processHandle = [RBSProcessHandle handleForPredicate:predicate error:nil]; 58 | /* 59 | NSError *error; 60 | self.uvScene = [UVInjectedScene injectInProcess:processHandle.rbs_pid error:&error]; 61 | if (error) { 62 | showDialog(self, @"Error", [NSString stringWithFormat:@"RBS %@ pid %d\n%@", processHandle, processHandle.rbs_pid, error.localizedDescription]); 63 | return; 64 | } 65 | 66 | UVSceneHost *host = [UVSceneHost createWithInjectedScene:self.uvScene error:&error]; 67 | [self.view addSubview:host]; 68 | */ 69 | 70 | /* 71 | FBScene *scene = self.uvScene.scene; 72 | _UISceneLayerHostContainerView *layerHostView = [[NSClassFromString(@"_UISceneLayerHostContainerView") alloc] initWithScene:scene debugDescription:@"Debug"]; 73 | [layerHostView _setPresentationContext:[[UIScenePresentationContext alloc] _initWithDefaultValues]]; 74 | [self.view addSubview:layerHostView]; 75 | */ 76 | 77 | FBProcessManager *manager = FBProcessManager.sharedInstance; 78 | [manager registerProcessForAuditToken:processHandle.auditToken]; 79 | NSString *identifier = [NSString stringWithFormat:@"sceneID:%@-%@", bundleID, @"default"]; 80 | 81 | // FBSDisplayConfiguration 82 | id displayConfig = UIScreen.mainScreen.displayConfiguration; 83 | //[[FBDisplayManager sharedInstance] mainConfiguration]; 84 | //[FBDisplayManager mainConfiguration]; 85 | 86 | // In [PBAAppDelegate _createInitialAppScene]: 87 | FBSMutableSceneDefinition *definition = [FBSMutableSceneDefinition definition]; 88 | definition.identity = [FBSSceneIdentity identityForIdentifier:identifier]; 89 | definition.clientIdentity = [FBSSceneClientIdentity identityForBundleID:bundleID]; // identityForBundleID 90 | definition.specification = [UIApplicationSceneSpecification specification]; 91 | FBSMutableSceneParameters *parameters = [FBSMutableSceneParameters parametersForSpecification:definition.specification]; 92 | 93 | UIMutableApplicationSceneSettings *settings = [UIMutableApplicationSceneSettings new]; 94 | // persistenceIdentifier 95 | settings.displayConfiguration = displayConfig; 96 | settings.level = 1; 97 | settings.foreground = YES; 98 | settings.interfaceOrientation = UIInterfaceOrientationPortrait; 99 | settings.statusBarDisabled = 1; 100 | settings.frame = [UIScreen.mainScreen _referenceBounds]; 101 | //assert(settings.otherSettings); 102 | // settings.previewMaximumSize = 103 | //settings.deviceOrientationEventsEnabled = YES; 104 | //[settings.ignoreOcclusionReasons addObject:@"SystemApp"]; 105 | parameters.settings = settings; 106 | //[parameters updateSettingsWithBlock:block]; 107 | 108 | UIMutableApplicationSceneClientSettings *clientSettings = [UIMutableApplicationSceneClientSettings new]; 109 | clientSettings.interfaceOrientation = UIInterfaceOrientationPortrait; 110 | clientSettings.statusBarStyle = 0; 111 | parameters.clientSettings = clientSettings; 112 | //[parameters updateClientSettingsWithBlock:block]; 113 | 114 | /* 115 | FBScene *scene = [[FBSceneManager sharedInstance] createSceneWithDefinition:definition initialParameters:parameters]; 116 | 117 | self.presentationManager = [[UIScenePresentationManager alloc] _initWithScene:scene]; 118 | self.owner = [[NSClassFromString(@"_UIScenePresenterOwner") alloc] initWithScenePresentationManager:self.presentationManager context:scene]; 119 | self.presenter = [[NSClassFromString(@"_UIScenePresenter") alloc] initWithOwner:self.owner identifier:identifier sortContext:@(0)]; 120 | [self.view addSubview:self.presenter.presentationView]; 121 | [self.presenter activate]; 122 | */ 123 | } 124 | 125 | - (void)launch:(NSString *)bundleID { 126 | [UIApplication.sharedApplication launchApplicationWithIdentifier:bundleID suspended:YES]; // When launching the app suspended, it doesn't appear for the user. 127 | } 128 | 129 | /* 130 | NSMutableDictionary *infoPlistDic = [[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/Info.plist", [executablePath stringByDeletingLastPathComponent]]]; 131 | 132 | NSString* jobLabel; 133 | NSString const* bundleId = [infoPlistDic objectForKey:@"CFBundleIdentifier"]; 134 | 135 | NSUUID *uuid = [NSUUID UUID]; 136 | NSString *envFile = [standardDefaults stringForKey:@"envfile"]; 137 | NSDictionary *env = nil; 138 | 139 | if ([envFile length] > 0) { 140 | 141 | env = [[NSDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@", envFile]]; 142 | 143 | if ([env count] < 1) { 144 | fprintf(stderr, "Environment file specified, but no variables found! Ensure the file has a correct format (plist) and contains at least one variable/value combo!\n"); 145 | print_usage(); 146 | exit(1); 147 | } 148 | 149 | NSLog(@"Using additional environment variables:\n%@", env); 150 | } 151 | 152 | jobLabel = [NSString stringWithFormat:@"%@-%@",bundleId,uuid]; // Add the UUID to have unique job names if spawning multiple instances of the same app 153 | 154 | NSLog(@"Submitting job: %@", jobLabel); 155 | 156 | RBSProcessIdentity* identity = [cRbsProcessIdentity identityForApplicationJobLabel:jobLabel bundleID:bundleId platform:platformIdentifier]; 157 | RBSLaunchContext* context = [cRbsLaunchContext contextWithIdentity:identity]; 158 | 159 | NSString *outPath = NSTemporaryDirectory(); 160 | NSString *stdoutPath = [outPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_stdout.txt",jobLabel]]; 161 | NSString *stderrPath = [outPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_stderr.txt",jobLabel]]; 162 | 163 | // Look at -[RBLaunchdJobManager _generateDataWithIdentity:context:] to learn about the meaning of the context properties 164 | //[context setArguments:arguments]; 165 | [context setExecutablePath:executablePath]; 166 | [context setLsSpawnFlags:lsSpawnFlags]; 167 | //[context setMachServices:machServices]; 168 | [context setStandardOutputPath:stdoutPath]; 169 | [context setStandardErrorPath:stderrPath]; 170 | [context setEnvironment:env]; 171 | [context setExecutionOptions:0x8]; // Looking inside runningboard code it looks like this disabled pointer auth? Might come in handy 172 | NSLog(@"Initial role before: %d", context.initialRole); 173 | [context setLsInitialRole:0x7]; // This value is mapped to PRIO_DARWIN_ROLE_UI_FOCAL by RBSDarwinRoleFromRBSRole() 174 | NSLog(@"Initial role after: %d", context.initialRole); 175 | 176 | RBSLaunchRequest* request = [[cRbsLaunchRequest alloc] initWithContext:context]; 177 | 178 | NSError* errResult; 179 | BOOL success = [request execute:&context error:&errResult]; 180 | 181 | if (!success) { 182 | NSLog(@"Error: %@", errResult); 183 | exit(1); 184 | } 185 | 186 | RBSProcessPredicate* predicate = [cRbsProcessPredicate predicateMatchingIdentity:identity]; 187 | RBSProcessHandle* process = [cRbsProcessHandle handleForPredicate:predicate error:nil]; 188 | */ 189 | 190 | @end 191 | -------------------------------------------------------------------------------- /ViewController.m_sb2: -------------------------------------------------------------------------------- 1 | // ignore this file unless you're going to mess around SpringBoard 2 | 3 | #import "ViewController.h" 4 | #import "UIKitPrivate.h" 5 | #include 6 | #include 7 | #include 8 | 9 | void showDialog(UIViewController *viewController, NSString* title, NSString* message) { 10 | UIAlertController* alert = [UIAlertController alertControllerWithTitle:title 11 | message:message 12 | preferredStyle:UIAlertControllerStyleAlert]; 13 | //text.dataDetectorTypes = UIDataDetectorTypeLink; 14 | UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; 15 | [alert addAction:okAction]; 16 | 17 | [viewController presentViewController:alert animated:YES completion:nil]; 18 | } 19 | 20 | @interface SBExternalDisplayApplicationSceneSpecification : UIApplicationSceneSpecification 21 | - (NSString *)uiSceneSessionRole; 22 | @end 23 | 24 | @implementation SBExternalDisplayApplicationSceneSpecification 25 | - (NSString *)uiSceneSessionRole { 26 | return @"SBWindowSceneSessionRoleExternalDisplay"; 27 | } 28 | @end 29 | 30 | @interface UIScenePresentationContext : NSObject 31 | - (UIScenePresentationContext *)_initWithDefaultValues; 32 | @end 33 | 34 | @interface _UISceneLayerHostContainerView : UIView 35 | - (instancetype)initWithScene:(FBScene *)scene debugDescription:(NSString *)desc; 36 | - (void)_setPresentationContext:(UIScenePresentationContext *)context; 37 | @end 38 | 39 | @interface UIApplication() 40 | - (void)launchApplicationWithIdentifier:(NSString *)identifier suspended:(BOOL)suspended; 41 | @end 42 | 43 | @interface ViewController () 44 | @property(nonatomic) UIScenePresentationManager *presentationManager; 45 | @property(nonatomic) _UIScenePresenter *presenter; 46 | @property(nonatomic) _UIScenePresenterOwner *owner; 47 | //UVInjectedScene *uvScene; 48 | @end 49 | 50 | @implementation ViewController 51 | 52 | - (void)viewDidLoad { 53 | [super viewDidLoad]; 54 | self.view.backgroundColor = UIColor.systemBackgroundColor; 55 | self.title = @"FrontBoardAppLauncher"; 56 | 57 | // PreviewsServicesUI 58 | // [UVInjectedScene injectInProcess:PID error:&error]; 59 | // [UVInjectedScene _injectInProcessHandle:handle error:&error]; 60 | 61 | NSString *bundleID = @"com.apple.SpringBoard"; 62 | //[self launch:bundleID]; 63 | 64 | RBSProcessIdentity* identity = [RBSProcessIdentity identityForDaemonJobLabel:bundleID]; 65 | //identityForApplicationJobLabel:nil bundleID:bundleID platform:2]; 66 | RBSProcessPredicate* predicate = [RBSProcessPredicate predicateMatchingIdentity:identity]; 67 | RBSProcessHandle* processHandle = [RBSProcessHandle handleForPredicate:predicate error:nil]; 68 | 69 | /* 70 | NSError *error; 71 | self.uvScene = [UVInjectedScene injectInProcess:processHandle.rbs_pid error:&error]; 72 | if (error) { 73 | showDialog(self, @"Error", [NSString stringWithFormat:@"RBS %@ pid %d\n%@", processHandle, processHandle.rbs_pid, error.localizedDescription]); 74 | return; 75 | } 76 | 77 | UVSceneHost *host = [UVSceneHost createWithInjectedScene:self.uvScene error:&error]; 78 | [self.view addSubview:host]; 79 | */ 80 | 81 | /* 82 | FBScene *scene = self.uvScene.scene; 83 | _UISceneLayerHostContainerView *layerHostView = [[NSClassFromString(@"_UISceneLayerHostContainerView") alloc] initWithScene:scene debugDescription:@"Debug"]; 84 | [layerHostView _setPresentationContext:[[UIScenePresentationContext alloc] _initWithDefaultValues]]; 85 | [self.view addSubview:layerHostView]; 86 | */ 87 | 88 | FBProcessManager *manager = FBProcessManager.sharedInstance; 89 | [manager registerProcessForAuditToken:processHandle.auditToken]; 90 | NSString *identifier = @"SpringBoardInjectedScene"; 91 | 92 | // FBSDisplayConfiguration 93 | id displayConfig = UIScreen.mainScreen.displayConfiguration; 94 | //[[FBDisplayManager sharedInstance] mainConfiguration]; 95 | //[FBDisplayManager mainConfiguration]; 96 | 97 | // In [PBAAppDelegate _createInitialAppScene]: 98 | FBSMutableSceneDefinition *definition = [FBSMutableSceneDefinition definition]; 99 | definition.identity = [FBSSceneIdentity identityForIdentifier:identifier]; 100 | definition.clientIdentity = [FBSSceneClientIdentity identityForProcessIdentity:identity]; // identityForBundleID 101 | definition.specification = [NSClassFromString(@"SBExternalDisplayApplicationSceneSpecification") new]; 102 | FBSMutableSceneParameters *parameters = [FBSMutableSceneParameters parametersForSpecification:definition.specification]; 103 | 104 | UIMutableApplicationSceneSettings *settings = [UIMutableApplicationSceneSettings new]; 105 | // persistenceIdentifier 106 | settings.canShowAlerts = YES; 107 | settings.displayConfiguration = displayConfig; 108 | settings.foreground = YES; 109 | settings.frame = CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - 100); 110 | settings.interfaceOrientation = UIInterfaceOrientationPortrait; 111 | //settings.interruptionPolicy = 2; // reconnect 112 | settings.level = 1; 113 | settings.persistenceIdentifier = NSUUID.UUID.UUIDString; 114 | //settings.statusBarDisabled = 1; 115 | // settings.previewMaximumSize = 116 | //settings.deviceOrientationEventsEnabled = YES; 117 | //[settings.ignoreOcclusionReasons addObject:@"SystemApp"]; 118 | parameters.settings = settings; 119 | //[parameters updateSettingsWithBlock:block]; 120 | 121 | UIMutableApplicationSceneClientSettings *clientSettings = [UIMutableApplicationSceneClientSettings new]; 122 | clientSettings.interfaceOrientation = UIInterfaceOrientationPortrait; 123 | clientSettings.statusBarStyle = 0; 124 | parameters.clientSettings = clientSettings; 125 | //[parameters updateClientSettingsWithBlock:block]; 126 | 127 | FBScene *scene = [[FBSceneManager sharedInstance] createSceneWithDefinition:definition initialParameters:parameters]; 128 | 129 | self.presentationManager = [[UIScenePresentationManager alloc] _initWithScene:scene]; 130 | self.owner = [[NSClassFromString(@"_UIScenePresenterOwner") alloc] initWithScenePresentationManager:self.presentationManager context:scene]; 131 | self.presenter = [[NSClassFromString(@"_UIScenePresenter") alloc] initWithOwner:self.owner identifier:identifier sortContext:@(0)]; 132 | [self.view addSubview:self.presenter.presentationView]; 133 | [self.presenter activate]; 134 | } 135 | 136 | - (void)launch:(NSString *)bundleID { 137 | [UIApplication.sharedApplication launchApplicationWithIdentifier:bundleID suspended:YES]; // When launching the app suspended, it doesn't appear for the user. 138 | } 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.kdt.frontboardapplauncher 2 | Name: FrontBoardAppLauncher 3 | Version: 0.0.1 4 | Architecture: iphoneos-arm 5 | Description: An awesome application! 6 | Maintainer: khanhduytran0 7 | Author: khanhduytran0 8 | Section: Utilities 9 | -------------------------------------------------------------------------------- /entitlements.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.QuartzCore.displayable-context 6 | 7 | com.apple.QuartzCore.secure-mode 8 | 9 | com.apple.backboard.client 10 | 11 | com.apple.frontboard.launchapplications 12 | 13 | com.apple.private.security.no-sandbox 14 | 15 | com.apple.private.security.storage.AppBundles 16 | 17 | com.apple.private.security.storage.AppDataContainers 18 | 19 | com.apple.runningboard.assertions.frontboard 20 | 21 | com.apple.runningboard.hereditarygrantoriginator 22 | 23 | com.apple.runningboard.launchprocess 24 | 25 | com.apple.runningboard.primitiveattribute 26 | 27 | com.apple.runningboard.process-state 28 | 29 | com.apple.runningboard.targetidentities 30 | 31 | com.apple.runningboard.terminateprocess 32 | 33 | com.apple.security.exception.mach-lookup.global-name 34 | 35 | com.apple.frontboard.systemappservices 36 | com.apple.UIKit.statusbarserver 37 | com.apple.sirittsd 38 | com.apple.proactive.UserEducationSuggestion.server-listener.xpc 39 | com.apple.Photos.MultiLibrary 40 | com.apple.abm.helper.mobile 41 | com.apple.siri.activation.service 42 | com.apple.springboard.SBRendererService 43 | com.apple.appstored.xpc 44 | com.apple.appstored.xpc.request 45 | com.apple.PointerUI.pointeruid.service-launching 46 | com.apple.proactive.appDirectory 47 | com.apple.CarPlayApp.service 48 | com.apple.sleepd.sleepserver 49 | com.apple.donotdisturb.service 50 | com.apple.coordination.alarms 51 | com.apple.coordination.timers 52 | com.apple.tipsd 53 | com.apple.ModeEntityScorer 54 | com.apple.proactive.NotificationDigest.xpc 55 | com.apple.assistant.announcement_state.service 56 | com.apple.icloud.searchpartyd.beaconmanager 57 | com.apple.server.bluetooth.general.xpc 58 | com.apple.powerd.smartpowernap 59 | com.apple.biomesyncd.realTimeSession 60 | com.apple.sessionservices 61 | aps-connection-initiate 62 | com.apple.mobileassetd.v2 63 | com.apple.HearingApp 64 | 65 | com.apple.security.iokit-user-client-class 66 | 67 | AGXCommandQueue 68 | AGXDevice 69 | AGXDeviceUserClient 70 | AGXSharedUserClient 71 | AppleCredentialManagerUserClient 72 | AppleJPEGDriverUserClient 73 | ApplePPMUserClient 74 | AppleSPUHIDDeviceUserClient 75 | AppleSPUHIDDriverUserClient 76 | IOAccelContext 77 | IOAccelContext2 78 | IOAccelDevice 79 | IOAccelDevice2 80 | IOAccelSharedUserClient 81 | IOAccelSharedUserClient2 82 | IOAccelSubmitter2 83 | IOHIDEventServiceFastPathUserClient 84 | IOHIDLibUserClient 85 | IOMobileFramebufferUserClient 86 | IOReportUserClient 87 | IOSurfaceAcceleratorClient 88 | IOSurfaceRootUserClient 89 | RootDomainUserClient 90 | IOGPUDeviceUserClient 91 | 92 | com.apple.springboard-ui.client 93 | 94 | com.apple.springboard.statusbarstyleoverrides 95 | 96 | com.apple.springboard.statusbarstyleoverrides.coordinator 97 | 98 | UIStatusBarStyleOverrideDeveloperTools 99 | UIStatusBarStyleOverridePlaygrounds 100 | 101 | get-task-allow 102 | 103 | platform-application 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "AppDelegate.h" 3 | #include 4 | 5 | @interface UIStatusBarServer : NSObject 6 | @end 7 | @implementation UIStatusBarServer(hook) 8 | + (void)runServer { 9 | // FIXME: PreBoard doesn't call this 10 | } 11 | @end 12 | 13 | @implementation UIApplication(hook) 14 | - (BOOL)_supportedOnLockScreen { 15 | return YES; 16 | } 17 | @end 18 | 19 | @implementation UIViewController(hook) 20 | - (BOOL)_canShowWhileLocked { 21 | return YES; 22 | } 23 | @end 24 | 25 | @implementation UIWindow(hook) 26 | - (BOOL)_shouldCreateContextAsSecure { 27 | return YES; 28 | } 29 | @end 30 | 31 | void FBSystemShellInitialize(id block); 32 | 33 | int main(int argc, char **argv) { 34 | @autoreleasepool { 35 | FBSystemShellInitialize(nil); 36 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 37 | } 38 | } 39 | --------------------------------------------------------------------------------