Skip to content

Commit

Permalink
New jit less mode (#213)
Browse files Browse the repository at this point in the history
* zsign POC

* new jitless mode & remove unused files

* better project structure

* recover info.plist

* readme update

* Update app hiding in readme
  • Loading branch information
hugeBlack authored Nov 18, 2024
1 parent 8b6e503 commit 5d54a31
Show file tree
Hide file tree
Showing 48 changed files with 323 additions and 1,943 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ packages/
.DS_Store
LiveContainer.xcodeproj
project.xcworkspace
xcuserdata
xcuserdata
Resources/Frameworks/OpenSSL.framework
2 changes: 1 addition & 1 deletion AltStoreTweak/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ include $(THEOS)/makefiles/common.mk
LIBRARY_NAME = AltStoreTweak

AltStoreTweak_FILES = Tweak.m
AltStoreTweak_CFLAGS = -fobjc-arc
AltStoreTweak_CFLAGS = -fobjc-arc -DCONFIG_COMMIT=\"$(CONFIG_COMMIT)\"
AltStoreTweak_INSTALL_PATH = /Applications/LiveContainer.app/Frameworks

include $(THEOS_MAKE_PATH)/library.mk
82 changes: 42 additions & 40 deletions AltStoreTweak/Tweak.m
Original file line number Diff line number Diff line change
@@ -1,64 +1,66 @@
@import Foundation;
@import Security;

void LCCopyKeychainItems(NSString *oldService, NSString *newService) {
// Query to find all keychain items with the old service
NSData* getKeyChainItemFromService(NSString* key, NSString* service) {
NSDictionary *query = @{
(__bridge id)kSecAttrService: oldService,
(__bridge id)kSecAttrService: service,
(__bridge id)kSecAttrAccount: key,
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnData: @YES,
(__bridge id)kSecAttrSynchronizable: (__bridge id)kSecAttrSynchronizableAny,
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitAll,
(__bridge id)kSecReturnAttributes: @YES
(__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne,
};

CFTypeRef result = NULL;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, &result);

if (status == errSecSuccess) {
NSArray *items = (__bridge NSArray *)result;
NSData *data = (__bridge NSData *)result;
return data;

for (NSDictionary *item in items) {
// Retrieve attributes and data of the keychain item
NSString *account = item[(id)kSecAttrAccount];
NSData *passwordData = item[(id)kSecValueData];

NSDictionary *deleteQuery = @{
(__bridge id)kSecAttrService: newService,
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrSynchronizable: (__bridge id)kSecAttrSynchronizableAny,
(__bridge id)kSecAttrAccount: account
};

OSStatus deleteStatus = SecItemDelete((CFDictionaryRef)deleteQuery);
if (deleteStatus != errSecSuccess && deleteStatus != errSecItemNotFound) {
NSLog(@"[LC] Delete failed %d", (int)deleteStatus);
continue;
}

// Create a new keychain entry with the new service name
NSDictionary *newItem = @{
(__bridge id)kSecAttrService: newService,
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrSynchronizable: (__bridge id)kSecAttrSynchronizableAny,
(__bridge id)kSecAttrAccount: account,
(__bridge id)kSecValueData: passwordData
};
OSStatus addStatus = SecItemAdd((CFDictionaryRef)newItem, NULL);
if (addStatus != errSecSuccess) {
NSLog(@"[LC] Add item failed %d", (int)deleteStatus);
}
}
} else {
NSLog(@"[LC] Error retrieving keychain items: %d", (int)status);
return nil;
}
}

BOOL synced = NO;
__attribute__((constructor))
static void LCAltstoreHookInit(void) {
if (!synced) {
LCCopyKeychainItems(@"com.rileytestut.AltStore", [NSBundle.mainBundle bundleIdentifier]);
synced = YES;
if (synced) {
return;
}
NSLog(@"[LC] LiveContainer AltStore Tweak build %s", CONFIG_COMMIT);
NSString* bundleId = [NSBundle.mainBundle bundleIdentifier];
NSString* serviceName;
NSArray<NSString*>* appGroups = [NSBundle.mainBundle.infoDictionary objectForKey:@"ALTAppGroups"];
if(appGroups == nil || [appGroups count] == 0) {
NSLog(@"[LC] Invalid install method! Failed to find App Group ID.");
return;
}

NSString* appGroupId = appGroups.firstObject;
if([bundleId containsString:@"SideStore"]) {
serviceName = @"com.SideStore.SideStore";
} else if ([bundleId containsString:@"AltStore"]) {
serviceName = @"com.rileytestut.AltStore";
} else {
NSLog(@"[LC] Failed to figure out which store this is!");
return;
}
NSData *certData = getKeyChainItemFromService(@"signingCertificate", serviceName);
if(certData == nil) {
NSLog(@"[LC] Failed to retrive certificate data!");
return;
}
NSData *certPassword = getKeyChainItemFromService(@"signingCertificatePassword", serviceName);
if(certPassword == nil) {
NSLog(@"[LC] Failed to retrive certificate password!");
return;
}
NSUserDefaults* appGroupUserDefaults = [[NSUserDefaults alloc] initWithSuiteName:appGroupId];
[appGroupUserDefaults setObject:certData forKey:@"LCCertificateData"];
[appGroupUserDefaults setObject:[NSString stringWithUTF8String:certPassword.bytes] forKey:@"LCCertificatePassword"];
NSLog(@"[LC] Successfully updated JIT-Less certificate!");
synced = YES;
}
9 changes: 8 additions & 1 deletion LiveContainerSwiftUI/LCAppBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,12 @@ struct LCAppBanner : View {
Text("lc.appBanner.waitForJitMsg".loc)
}

.alert("lc.common.error".loc, isPresented: $errorShow) {
.alert("lc.common.error".loc, isPresented: $errorShow){
Button("lc.common.ok".loc, action: {
})
Button("lc.common.copy".loc, action: {
copyError()
})
} message: {
Text(errorInfo)
}
Expand Down Expand Up @@ -386,6 +389,10 @@ struct LCAppBanner : View {

return ans
}

func copyError() {
UIPasteboard.general.string = errorInfo
}

}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#import "LCAppDelegateSwiftUI.h"
#import <UIKit/UIKit.h>
#import "LCUtils.h"
#import "LCSharedUtils.h"
#import "../LCSharedUtils.h"

@implementation LCAppDelegateSwiftUI

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "LCUtils.h"

@interface LCAppInfo : NSObject {
NSMutableDictionary* _info;
Expand Down Expand Up @@ -30,5 +31,5 @@
- (instancetype)initWithBundlePath:(NSString*)bundlePath;
- (NSDictionary *)generateWebClipConfig;
- (void)save;
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* errorInfo))progressHandler forceSign:(BOOL)forceSign;
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* progress))progressHandler forceSign:(BOOL)forceSign;
@end
19 changes: 14 additions & 5 deletions LiveContainerUI/LCAppInfo.m → LiveContainerSwiftUI/LCAppInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ - (UIImage*)icon {
icon = [UIImage imageNamed:[_info valueForKeyPath:@"CFBundleIconFiles"][0] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
}

if(!icon) {
icon = [UIImage imageNamed:[_info valueForKeyPath:@"CFBundleIcons~ipad"][@"CFBundlePrimaryIcon"][@"CFBundleIconName"] inBundle:[[NSBundle alloc] initWithPath: _bundlePath] compatibleWithTraitCollection:nil];
}

if(!icon) {
icon = [UIImage imageNamed:@"DefaultIcon"];
}
Expand Down Expand Up @@ -176,12 +180,14 @@ - (void)preprocessBundleBeforeSiging:(NSURL *)bundleURL completion:(dispatch_blo
[NSFileManager.defaultManager removeItemAtURL:[bundleURL URLByAppendingPathComponent:@"PlugIns"] error:nil];
// Remove code signature from all library files
[LCUtils removeCodeSignatureFromBundleURL:bundleURL];


dispatch_async(dispatch_get_main_queue(), completion);
});
}

// return "SignNeeded" if sign is needed, other wise return an error
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* errorInfo))progressHandler forceSign:(BOOL)forceSign {
- (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo))completetionHandler progressHandler:(void(^)(NSProgress* progress))progressHandler forceSign:(BOOL)forceSign {
NSString *appPath = self.bundlePath;
NSString *infoPath = [NSString stringWithFormat:@"%@/Info.plist", appPath];
NSMutableDictionary *info = _info;
Expand Down Expand Up @@ -243,9 +249,8 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo
info[@"CFBundleIdentifier"] = info[@"LCBundleIdentifier"];
[info removeObjectForKey:@"LCBundleExecutable"];
[info removeObjectForKey:@"LCBundleIdentifier"];

__block NSProgress *progress = [LCUtils signAppBundle:appPathURL
completionHandler:^(BOOL success, NSError *_Nullable error) {

void (^signCompletionHandler)(BOOL success, NSError *error) = ^(BOOL success, NSError *_Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!error) {
info[@"LCJITLessSignID"] = @(signID);
Expand All @@ -267,7 +272,11 @@ - (void)patchExecAndSignIfNeedWithCompletionHandler:(void(^)(NSString* errorInfo
}

});
}];
};

__block NSProgress *progress;

progress = [LCUtils signAppBundle:appPathURL completionHandler:signCompletionHandler];
if (progress) {
progressHandler(progress);
}
Expand Down
16 changes: 14 additions & 2 deletions LiveContainerSwiftUI/LCAppListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,14 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {

}
.navigationViewStyle(StackNavigationViewStyle())
.alert(isPresented: $errorShow){
Alert(title: Text("lc.common.error".loc), message: Text(errorInfo))
.alert("lc.common.error".loc, isPresented: $errorShow){
Button("lc.common.ok".loc, action: {
})
Button("lc.common.copy".loc, action: {
copyError()
})
} message: {
Text(errorInfo)
}
.fileImporter(isPresented: $choosingIPA, allowedContentTypes: [.ipa]) { result in
Task { await startInstallApp(result) }
Expand Down Expand Up @@ -400,11 +406,13 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
if sameBundleIdApp.count > 0 && !sharedModel.isHiddenAppUnlocked {
do {
if !(try await LCUtils.authenticateUser()) {
self.installprogressVisible = false
return
}
} catch {
errorInfo = error.localizedDescription
errorShow = true
self.installprogressVisible = false
return
}
}
Expand Down Expand Up @@ -602,4 +610,8 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
isNavigationActive = false
navigateTo = nil
}

func copyError() {
UIPasteboard.general.string = errorInfo
}
}
1 change: 0 additions & 1 deletion LiveContainerSwiftUI/LCAppSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ struct LCAppSettingsView : View{
.transition(.opacity.combined(with: .slide))
}
}


Section {
Toggle(isOn: $model.uiDoSymlinkInbox) {
Expand Down
File renamed without changes.
Loading

0 comments on commit 5d54a31

Please sign in to comment.