diff --git a/RootHelper/Makefile b/RootHelper/Makefile index 5ec3849..548ab5d 100644 --- a/RootHelper/Makefile +++ b/RootHelper/Makefile @@ -10,6 +10,6 @@ trollstorehelper_CFLAGS = -fobjc-arc -I../Shared trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 trollstorehelper_INSTALL_PATH = /usr/local/bin trollstorehelper_LIBRARIES = archive -trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices +trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager include $(THEOS_MAKE_PATH)/tool.mk diff --git a/RootHelper/main.m b/RootHelper/main.m index c83536d..501694b 100644 --- a/RootHelper/main.m +++ b/RootHelper/main.m @@ -590,19 +590,8 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, NSLog(@"[installApp force = %d]", force); NSString* appPayloadPath = [appPackagePath stringByAppendingPathComponent:@"Payload"]; - - NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appPayloadPath error:nil]; - if(!items) return 167; - - NSString* appBundleToInstallPath; - for(NSString* item in items) - { - if([item.pathExtension isEqualToString:@"app"]) - { - appBundleToInstallPath = [appPayloadPath stringByAppendingPathComponent:item]; - break; - } - } + + NSString* appBundleToInstallPath = findAppPathInBundlePath(appPayloadPath); if(!appBundleToInstallPath) return 167; NSString* appId = appIdForAppPath(appBundleToInstallPath); @@ -626,7 +615,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, if(signRet != 0) return signRet; } - MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil]; + MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil]; if(appContainer) { // App update @@ -638,7 +627,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, // Make sure the installed app is a TrollStore app or the container is empty (or the force flag is set) NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:@"_TrollStore"]; - if(!appBundleURL && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil] && !force) + if(appBundleURL && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil] && !force) { NSLog(@"[installApp] already installed and not a TrollStore app... bailing out"); return 171; @@ -680,10 +669,21 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, // Do initial placeholder installation using LSApplicationWorkspace NSLog(@"[installApp] doing placeholder installation using LSApplicationWorkspace"); + // The installApplication API (re)moves the app bundle, so in order to be able to later + // fall back to the custom method, we need to make a temporary copy just for using it on this API once + // Yeah this sucks, but there is no better solution unfortunately + NSError* tmpCopyError; + NSString* lsAppPackageTmpCopy = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; + if(![[NSFileManager defaultManager] copyItemAtPath:appPackagePath toPath:lsAppPackageTmpCopy error:&tmpCopyError]) + { + NSLog(@"failed to make temporary copy of app packge: %@", tmpCopyError); + return 170; + } + NSError* installError; @try { - systemMethodSuccessful = [[LSApplicationWorkspace defaultWorkspace] installApplication:[NSURL fileURLWithPath:appPackagePath] withOptions:@{ + systemMethodSuccessful = [[LSApplicationWorkspace defaultWorkspace] installApplication:[NSURL fileURLWithPath:lsAppPackageTmpCopy] withOptions:@{ LSInstallTypeKey : @1, @"PackageType" : @"Placeholder" } error:&installError]; @@ -698,7 +698,11 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, { NSLog(@"[installApp] encountered error %@ while trying to do placeholder install", installError); } + + [[NSFileManager defaultManager] removeItemAtPath:lsAppPackageTmpCopy error:nil]; } + + NSLog(@"[installApp] app bundle still exists? %d", [[NSFileManager defaultManager] fileExistsAtPath:appBundleToInstallPath]); if(!systemMethodSuccessful) { @@ -707,7 +711,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, NSLog(@"[installApp] doing custom installation using MCMAppContainer"); NSError* mcmError; - appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:nil error:&mcmError]; + appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:YES existed:nil error:&mcmError]; if(!appContainer || mcmError) { @@ -726,14 +730,13 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appBundleToInstallPath toPath:newAppBundlePath error:©Error]; if(!suc) { - NSLog(@"[installApp] Failed to copy app bundle for app %@, error: %@", appId, copyError); return 178; } } } - appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil]; + appContainer = [MCMAppContainer containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil]; // Mark app as TrollStore app NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"]; diff --git a/RootHelper/uicache.m b/RootHelper/uicache.m index d05af82..beb689f 100644 --- a/RootHelper/uicache.m +++ b/RootHelper/uicache.m @@ -16,16 +16,16 @@ NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlement if(!entitlements) return nil; NSString* entitlementForGroups; - NSString* mcmClass; + Class mcmClass; if(systemGroups) { entitlementForGroups = @"com.apple.security.system-groups"; - mcmClass = @"MCMSystemDataContainer"; + mcmClass = [MCMSystemDataContainer class]; } else { entitlementForGroups = @"com.apple.security.application-groups"; - mcmClass = @"MCMSharedDataContainer"; + mcmClass = [MCMSharedDataContainer class]; } NSArray* groupIDs = entitlements[entitlementForGroups]; @@ -35,7 +35,7 @@ NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlement for(NSString* groupID in groupIDs) { - MCMContainer* container = [NSClassFromString(mcmClass) containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil]; + MCMContainer* container = [mcmClass containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil]; if(container.url) { groupContainers[groupID] = container.url.path; @@ -94,7 +94,6 @@ NSDictionary* constructEnvironmentVariablesForContainerPath(NSString* containerP void registerPath(NSString* path, BOOL unregister, BOOL system) { if(!path) return; - loadMCMFramework(); LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace]; if(unregister && ![[NSFileManager defaultManager] fileExistsAtPath:path]) diff --git a/Shared/CoreServices.h b/Shared/CoreServices.h index b24dd1f..79da2ad 100644 --- a/Shared/CoreServices.h +++ b/Shared/CoreServices.h @@ -69,4 +69,10 @@ extern NSString *LSInstallTypeKey; @end @interface MCMPluginKitPluginDataContainer : MCMDataContainer +@end + +@interface MCMSystemDataContainer : MCMContainer +@end + +@interface MCMSharedDataContainer : MCMContainer @end \ No newline at end of file diff --git a/Shared/TSUtil.h b/Shared/TSUtil.h index 5871fef..2d1d1e0 100644 --- a/Shared/TSUtil.h +++ b/Shared/TSUtil.h @@ -4,7 +4,6 @@ #define TrollStoreErrorDomain @"TrollStoreErrorDomain" extern void chineseWifiFixup(void); -extern void loadMCMFramework(void); extern NSString* safe_getExecutablePath(); extern NSString* rootHelperPath(void); extern NSString* getNSStringFromFile(int fd); diff --git a/Shared/TSUtil.m b/Shared/TSUtil.m index 5b116ca..eebacc1 100644 --- a/Shared/TSUtil.m +++ b/Shared/TSUtil.m @@ -26,15 +26,6 @@ void chineseWifiFixup(void) } } -void loadMCMFramework(void) -{ - static dispatch_once_t onceToken; - dispatch_once (&onceToken, ^{ - NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"]; - [mcmBundle load]; - }); -} - extern char*** _NSGetArgv(); NSString* safe_getExecutablePath() { @@ -379,9 +370,8 @@ NSArray* trollStoreInstalledAppBundlePaths() NSString* trollStorePath() { - loadMCMFramework(); NSError* mcmError; - MCMAppContainer* appContainer = [NSClassFromString(@"MCMAppContainer") containerWithIdentifier:@"com.opa334.TrollStore" createIfNecessary:NO existed:NULL error:&mcmError]; + MCMAppContainer* appContainer = [MCMAppContainer containerWithIdentifier:@"com.opa334.TrollStore" createIfNecessary:NO existed:NULL error:&mcmError]; if(!appContainer) return nil; return appContainer.url.path; } diff --git a/TrollHelper/Makefile b/TrollHelper/Makefile index e93739f..c4ff699 100644 --- a/TrollHelper/Makefile +++ b/TrollHelper/Makefile @@ -9,7 +9,7 @@ APPLICATION_NAME = TrollStorePersistenceHelper TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices -TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences +TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 diff --git a/TrollStore/Makefile b/TrollStore/Makefile index 343bf07..a58bb5d 100644 --- a/TrollStore/Makefile +++ b/TrollStore/Makefile @@ -7,7 +7,7 @@ APPLICATION_NAME = TrollStore TrollStore_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices -TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons +TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager TrollStore_LIBRARIES = archive TrollStore_CFLAGS = -fobjc-arc -I../Shared TrollStore_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12