Skip to content

Commit

Permalink
Support AltStore (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
khanhduytran0 committed Aug 9, 2024
1 parent 6450c26 commit ec849e7
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 15 deletions.
2 changes: 1 addition & 1 deletion LiveContainerUI/LCAppListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ - (void)patchExecAndSignIfNeed:(NSIndexPath *)indexPath shouldSort:(BOOL)sortNam
CC_SHA1(LCUtils.certificateData.bytes, (CC_LONG)LCUtils.certificateData.length, digest);
signID = *(uint64_t *)digest + signRevision;
} else {
[self showDialogTitle:@"Error" message:@"Failed to find ALTCertificate.p12. Please refresh SideStore and try again." handler:nil];
[self showDialogTitle:@"Error" message:@"Failed to find ALTCertificate.p12. Please refresh your store and try again." handler:nil];
return;
}

Expand Down
4 changes: 2 additions & 2 deletions LiveContainerUI/LCJITLessSetupViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ - (void)validateSigningTest:(BOOL)loaded {
// Erase signingCertificate
[LCUtils deleteKeychainItem:@"signingCertificate" ofStore:@"com.rileytestut.AltStore"];
[LCUtils deleteKeychainItem:@"signingCertificate" ofStore:@"com.SideStore.SideStore"];
[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:@"sidestore://install?url=%@", url]] options:@{} completionHandler:nil];
[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:LCUtils.storeInstallURLScheme, url]] options:@{} completionHandler:nil];
}];
return;
}

[self showDialogTitle:@"Instruction" message:@"Done. Press OK to finish setting up."
handler:^(UIAlertAction * action) {
[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:@"sidestore://install?url=%@", url]] options:@{} completionHandler:nil];
[UIApplication.sharedApplication openURL:[NSURL URLWithString:[NSString stringWithFormat:LCUtils.storeInstallURLScheme, url]] options:@{} completionHandler:nil];
}];
}

Expand Down
6 changes: 3 additions & 3 deletions LiveContainerUI/LCSettingsListController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ - (void)loadView {
}

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

Expand All @@ -32,7 +32,7 @@ - (void)setupJITLessPressed {
return;
}

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

- (void)openSourceCode {
Expand Down
3 changes: 2 additions & 1 deletion LiveContainerUI/LCUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void LCPatchExecSlice(const char *path, struct mach_header_64 *header);
+ (void)removeCodeSignatureFromBundleURL:(NSURL *)appURL;
+ (NSProgress *)signAppBundle:(NSURL *)path completionHandler:(void (^)(BOOL success, NSError *error))completionHandler;

+ (BOOL)isAppGroupSideStore;
+ (BOOL)isAppGroupAltStoreLike;
+ (NSString *)storeInstallURLScheme;

@end
23 changes: 19 additions & 4 deletions LiveContainerUI/LCUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ + (NSData *)certificateDataFile {
return nil;
}
NSURL *appGroupPath = [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:self.appGroupID];
NSURL *url = [appGroupPath URLByAppendingPathComponent:@"Apps/com.SideStore.SideStore/App.app/ALTCertificate.p12"];
NSURL *url = [appGroupPath URLByAppendingPathComponent:[NSString stringWithFormat:@"Apps/%@/App.app/ALTCertificate.p12", self.storeBundleID]];
return [NSData dataWithContentsOfURL:url];
}

Expand Down Expand Up @@ -107,9 +107,24 @@ + (void)loadStoreFrameworksWithError:(NSError **)error {
}
}

+ (NSString *)storeBundleID {
// Assuming this format never changes...
// group.BUNDLEID.YOURTEAMID
return [self.appGroupID substringWithRange:NSMakeRange(6, self.appGroupID.length - 17)];
}

+ (NSURL *)storeBundlePath {
NSURL *appGroupPath = [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:self.appGroupID];
return [appGroupPath URLByAppendingPathComponent:@"Apps/com.SideStore.SideStore/App.app"];
appGroupPath = [appGroupPath URLByAppendingPathComponent:[NSString stringWithFormat:@"Apps/%@/App.app", self.storeBundleID]];
return appGroupPath;
}

+ (NSString *)storeInstallURLScheme {
if ([self.storeBundleID containsString:@"SideStore"]) {
return @"sidestore://install?url=%@";
} else {
return @"altstore://install?url=%@";
}
}

+ (void)removeCodeSignatureFromBundleURL:(NSURL *)appURL {
Expand Down Expand Up @@ -185,8 +200,8 @@ + (NSString *)appGroupID {
return [NSBundle.mainBundle.infoDictionary[@"ALTAppGroups"] firstObject];
}

+ (BOOL)isAppGroupSideStore {
if (![self.appGroupID containsString:@"com.SideStore.SideStore"]) return NO;
+ (BOOL)isAppGroupAltStoreLike {
if (self.appGroupID.length == 0) return NO;
return [NSFileManager.defaultManager fileExistsAtPath:self.storeBundlePath.path];
}

Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,23 @@ make package
### Main executable
- Core of LiveContainer
- Contains the logic of setting up guest environment and loading guest app.
- If no app is selected, it loads LiveContainerUI.

### LiveContainerUI
- LiveContainer's default implementation of app manager, tweak manager and settings.
- If you're making a mod loader
- LiveContainer's default implementation of app manager, tweak manager and settings UI.
- If you're making a mod loader, you can provide your own.

### TweakLoader
- A simple tweak injector, which loads CydiaSubstrate and load tweaks.
- Injected to every app you install in LiveContainer.

## Usage
Requires SideStore for both JIT and JIT-less mode.
Requires AltStore or SideStore
- Build from source or get prebuilt ipa in [the Actions tab](https://github.com/khanhduytran0/LiveContainer/actions)
- Open LiveContainer, tap the plus icon in the upper right hand corner and select IPA files to install.
- Choose the app you want to open in the next launch.

### With JIT
### With JIT (requires SideStore)
- Tap the play icon, it will jump to SideStore and exit.
- In SideStore, hold down LiveContainer and tap `Enable JIT`. If you have SideStore build supporting JIT URL scheme, it jumps back to LiveContainer with JIT enabled and the guest app is ready to use.

Expand Down Expand Up @@ -94,3 +99,4 @@ To install tweaks, you can use the built-in tweak manager in LiveContainer, whic
- [fishhook](https://github.com/facebook/fishhook): [BSD 3-Clause license](https://github.com/facebook/fishhook/blob/main/LICENSE)
- [MBRoundProgressView](https://gist.github.com/saturngod/1224648)
- @haxi0 for icon
- @Vishram1123 for the initial shortcut implementation.

0 comments on commit ec849e7

Please sign in to comment.