Skip to content

Commit

Permalink
Fix CydiaSubstrate crash for real now; Add basic settings screen
Browse files Browse the repository at this point in the history
Apparently, MSGetImageByName didn't take symlink resolution into account, causing it to return null, leading MSFindSymbol to call _dyld_get_all_image_infos which was hidden
  • Loading branch information
khanhduytran0 committed Apr 29, 2024
1 parent 6d30758 commit 93ad7cd
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 124 deletions.
33 changes: 0 additions & 33 deletions FixCydiaSubstrate.c

This file was deleted.

2 changes: 1 addition & 1 deletion LCAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
@interface LCAppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) UINavigationController *rootViewController;
@property (nonatomic, strong) UIViewController *rootViewController;

@end
6 changes: 3 additions & 3 deletions LCAppDelegate.m
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#import "LCAppDelegate.h"
#import "LCJITLessSetupViewController.h"
#import "LCRootViewController.h"
#import "LCTabBarController.h"

@implementation LCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *viewController;
if ([NSBundle.mainBundle.executablePath.lastPathComponent isEqualToString:@"JITLessSetup"]) {
viewController = [[LCJITLessSetupViewController alloc] init];
_rootViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
} else {
viewController = [[LCRootViewController alloc] init];
_rootViewController = [[LCTabBarController alloc] init];
}
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_rootViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
_window.rootViewController = _rootViewController;
[_window makeKeyAndVisible];
return YES;
Expand Down
69 changes: 1 addition & 68 deletions LCRootViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import "LCUtils.h"
#import "MBRoundProgressView.h"
#import "UIKitPrivate.h"
#import "UIViewController+LCAlert.h"
#import "unarchive.h"
#import "AppInfo.h"

Expand Down Expand Up @@ -135,85 +136,17 @@ - (void)loadView {
[NSFileManager.defaultManager createDirectoryAtPath:self.tweakPath withIntermediateDirectories:NO attributes:nil error:nil];

// Setup action bar
self.title = @"LiveContainer";
self.navigationItem.rightBarButtonItems = @[
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(launchButtonTapped)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonTapped)]
];

if (!LCUtils.certificateData) {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Setup JIT-less" style:UIBarButtonItemStylePlain target:self action:@selector(setupJITLessTapped)];
} /* else {
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Test JIT-less" style:UIBarButtonItemStylePlain target:self action:@selector(testJITLessTapped)];
} */
}

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}

- (void)showDialogTitle:(NSString *)title message:(NSString *)message {
[self showDialogTitle:title message:message handler:nil];
}
- (void)showDialogTitle:(NSString *)title message:(NSString *)message handler:(void(^)(UIAlertAction *))handler {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:handler];
[alert addAction:okAction];
UIAlertAction* copyAction = [UIAlertAction actionWithTitle:@"Copy" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
UIPasteboard.generalPasteboard.string = message;
if (handler) handler(action);
}];
[alert addAction:copyAction];
[self presentViewController:alert animated:YES completion:nil];
}

- (void)showInputDialogTitle:(NSString *)title message:(NSString *)message placeholder:(NSString *)placeholder callback:(NSString *(^)(NSString *inputText))callback {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = placeholder;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.borderStyle = UITextBorderStyleRoundedRect;
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
UITextField *textField = alert.textFields[0];
NSString *error = callback(textField.text.length == 0 ? placeholder : textField.text);
if (error) {
alert.message = error;
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
okAction.shouldDismissHandler = ^{
return NO;
};
[alert addAction:okAction];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}

- (void)setupJITLessTapped {
if (!LCUtils.isAppGroupSideStore) {
[self showDialogTitle:@"Error" message:@"Unsupported installation method. Please use SideStore to setup this feature."];
return;
}

NSError *error;
NSURL *url = [LCUtils archiveIPAWithSetupMode:YES error:&error];
if (!url) {
[self showDialogTitle:@"Error" message:error.localizedDescription];
return;
}

[self showDialogTitle:@"Instruction" message:@"Setting up JIT-less allows you to use LiveContainer without having to enable JIT. LiveContainer needs to safely obtain the certificate from SideStore. Press OK to continue."
handler:^(UIAlertAction * action) {
[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:@"sidestore://install?url=%@", url]] options:@{} completionHandler:nil];
}];
}

- (void)addButtonTapped {
UIDocumentPickerViewController* documentPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:@[[UTType typeWithFilenameExtension:@"ipa" conformingToType:UTTypeData]]];
documentPickerVC.allowsMultipleSelection = YES;
Expand Down
6 changes: 6 additions & 0 deletions LCSettingsListController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#import <UIKit/UIKit.h>
#import <Preferences/PSListController.h>
#import <Preferences/PSSpecifier.h>

@interface LCSettingsListController : PSListController
@end
51 changes: 51 additions & 0 deletions LCSettingsListController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#import "LCSettingsListController.h"
#import "LCUtils.h"
#import "UIViewController+LCAlert.h"

@implementation LCSettingsListController

- (NSMutableArray*)specifiers {
if(!_specifiers) {
_specifiers = [NSMutableArray new];
PSSpecifier* jitlessGroup = [PSSpecifier emptyGroupSpecifier];
jitlessGroup.name = @"JIT-less";
[jitlessGroup setProperty:@"JIT-less allows you to use LiveContainer without having to enable JIT. Requires SideStore." forKey:@"footerText"];
[_specifiers addObject:jitlessGroup];

NSString *setupJITLessButtonName = LCUtils.certificateData ? @"JIT-less is set up" : @"Setup JIT-less";
PSSpecifier* setupJITLessButton = [PSSpecifier preferenceSpecifierNamed:setupJITLessButtonName target:self set:nil get:nil detail:nil cell:PSButtonCell edit:nil];
setupJITLessButton.identifier = @"setup-jitless";
[setupJITLessButton setProperty:@(!LCUtils.certificateData) forKey:@"enabled"];
setupJITLessButton.buttonAction = @selector(setupJITLessPressed);
[_specifiers addObject:setupJITLessButton];

PSSpecifier* signTweaksButton = [PSSpecifier preferenceSpecifierNamed:@"Sign tweaks" target:self set:nil get:nil detail:nil cell:PSButtonCell edit:nil];
signTweaksButton.identifier = @"sign-tweaks";
[signTweaksButton setProperty:@(!!LCUtils.certificateData) forKey:@"enabled"];
signTweaksButton.buttonAction = @selector(signTweaksPressed);
[_specifiers addObject:signTweaksButton];
}
return _specifiers;
}

- (void)setupJITLessPressed {
if (!LCUtils.isAppGroupSideStore) {
[self showDialogTitle:@"Error" message:@"Unsupported installation method. Please use SideStore to setup this feature."];
return;
}

NSError *error;
NSURL *url = [LCUtils archiveIPAWithSetupMode:YES error:&error];
if (!url) {
[self showDialogTitle:@"Error" message:error.localizedDescription];
return;
}

[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:@"sidestore://install?url=%@", url]] options:@{} completionHandler:nil];
}

- (void)signTweaksPressed {

}

@end
4 changes: 4 additions & 0 deletions LCTabBarController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#import <UIKit/UIKit.h>

@interface LCTabBarController : UITabBarController
@end
25 changes: 25 additions & 0 deletions LCTabBarController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#import "LCRootViewController.h"
#import "LCSettingsListController.h"
#import "LCTabBarController.h"

@implementation LCTabBarController

- (void)loadView {
[super loadView];

LCRootViewController* appTableVC = [LCRootViewController new];
appTableVC.title = @"Apps";

LCSettingsListController* settingsListVC = [LCSettingsListController new];
settingsListVC.title = @"Settings";

UINavigationController* appNavigationController = [[UINavigationController alloc] initWithRootViewController:appTableVC];
UINavigationController* settingsNavigationController = [[UINavigationController alloc] initWithRootViewController:settingsListVC];

appNavigationController.tabBarItem.image = [UIImage systemImageNamed:@"square.stack.3d.up.fill"];
settingsNavigationController.tabBarItem.image = [UIImage systemImageNamed:@"gear"];

self.viewControllers = @[appNavigationController, settingsNavigationController];
}

@end
13 changes: 11 additions & 2 deletions LCUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,13 @@ + (NSProgress *)signAppBundle:(NSURL *)path completionHandler:(void (^)(BOOL suc
// Load libraries from Documents, yeah
NSArray *signerFrameworks = @[@"OpenSSL.framework", @"Roxas.framework", @"AltStoreCore.framework"];
for (NSString *framework in signerFrameworks) {
[[NSBundle bundleWithURL:[storeFrameworksPath URLByAppendingPathComponent:framework]] loadAndReturnError:&error];
NSBundle *frameworkBundle = [NSBundle bundleWithURL:[storeFrameworksPath URLByAppendingPathComponent:framework]];
if (!frameworkBundle) {
//completionHandler(NO, error);
abort();
return nil;
}
[frameworkBundle loadAndReturnError:&error];
if (error) {
completionHandler(NO, error);
return nil;
Expand All @@ -159,7 +165,10 @@ + (NSString *)appGroupID {
}

+ (BOOL)isAppGroupSideStore {
return [self.appGroupID containsString:@"com.SideStore.SideStore"];
if (![self.appGroupID containsString:@"com.SideStore.SideStore"]) return NO;
NSURL *appGroupPath = [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:self.appGroupID];
NSURL *storeBundlePath = [appGroupPath URLByAppendingPathComponent:@"Apps/com.SideStore.SideStore/App.app"];
return [NSFileManager.defaultManager fileExistsAtPath:storeBundlePath.path];
}

+ (void)changeMainExecutableTo:(NSString *)exec error:(NSError **)error {
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CONFIG_BRANCH = $(shell git branch --show-current)
CONFIG_COMMIT = $(shell git log --oneline | sed '2,10000000d' | cut -b 1-7)

# Build the UI library
LiveContainerUI_FILES = LCAppDelegate.m LCJITLessSetupViewController.m LCRootViewController.m LCUtils.m MBRoundProgressView.m unarchive.m AppInfo.m
LiveContainerUI_FILES = LCAppDelegate.m LCJITLessSetupViewController.m LCRootViewController.m LCSettingsListController.m LCTabBarController.m LCUtils.m MBRoundProgressView.m unarchive.m AppInfo.m
LiveContainerUI_CFLAGS = \
-fobjc-arc \
-DCONFIG_TYPE=\"$(CONFIG_TYPE)\" \
Expand All @@ -32,7 +32,7 @@ include $(THEOS_MAKE_PATH)/library.mk
# Build the app
APPLICATION_NAME = LiveContainer

$(APPLICATION_NAME)_FILES = dyld_bypass_validation.m main.m utils.m FixCydiaSubstrate.c fishhook/fishhook.c
$(APPLICATION_NAME)_FILES = dyld_bypass_validation.m main.m utils.m fishhook/fishhook.c NSBundle+FixCydiaSubstrate.m
$(APPLICATION_NAME)_CODESIGN_FLAGS = -Sentitlements.xml
$(APPLICATION_NAME)_CFLAGS = -fobjc-arc
$(APPLICATION_NAME)_LDFLAGS = -e_LiveContainerMain -rpath @loader_path/Frameworks
Expand Down
13 changes: 13 additions & 0 deletions NSBundle+FixCydiaSubstrate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import <Foundation/Foundation.h>

@implementation NSBundle(FixCydiaSubstrate)

- (NSString *)bundlePath {
NSString *path = self.bundleURL.path;
if ([path hasPrefix:@"/private"]) {
return path;
}
return [@"/private" stringByAppendingPathComponent:path];
}

@end
2 changes: 2 additions & 0 deletions TweakLoader.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include <dlfcn.h>
#include <objc/runtime.h>

__attribute__((constructor))
static void TweakLoaderConstructor() {
Expand Down
9 changes: 9 additions & 0 deletions UIViewController+LCAlert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#import <UIKit/UIKit.h>

@interface UIViewController(LCAlert)

- (void)showDialogTitle:(NSString *)title message:(NSString *)message;
- (void)showDialogTitle:(NSString *)title message:(NSString *)message handler:(void(^)(UIAlertAction *))handler;
- (void)showInputDialogTitle:(NSString *)title message:(NSString *)message placeholder:(NSString *)placeholder callback:(NSString *(^)(NSString *inputText))callback;

@end
48 changes: 48 additions & 0 deletions UIViewController+LCAlert.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#import "UIViewController+LCAlert.h"

@implementation UIViewController(LCAlert)

- (void)showDialogTitle:(NSString *)title message:(NSString *)message {
[self showDialogTitle:title message:message handler:nil];
}

- (void)showDialogTitle:(NSString *)title message:(NSString *)message handler:(void(^)(UIAlertAction *))handler {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:handler];
[alert addAction:okAction];
UIAlertAction* copyAction = [UIAlertAction actionWithTitle:@"Copy" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
UIPasteboard.generalPasteboard.string = message;
if (handler) handler(action);
}];
[alert addAction:copyAction];
[self presentViewController:alert animated:YES completion:nil];
}

- (void)showInputDialogTitle:(NSString *)title message:(NSString *)message placeholder:(NSString *)placeholder callback:(NSString *(^)(NSString *inputText))callback {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = placeholder;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.borderStyle = UITextBorderStyleRoundedRect;
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
UITextField *textField = alert.textFields[0];
NSString *error = callback(textField.text.length == 0 ? placeholder : textField.text);
if (error) {
alert.message = error;
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
okAction.shouldDismissHandler = ^{
return NO;
};
[alert addAction:okAction];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}

@end
Loading

0 comments on commit 93ad7cd

Please sign in to comment.