diff --git a/RootHelper/main.m b/RootHelper/main.m index 88b7284..280319b 100644 --- a/RootHelper/main.m +++ b/RootHelper/main.m @@ -48,25 +48,27 @@ NSArray* applicationsWithGroupId(NSString* groupId) return enumerator.allObjects; } -NSSet* appleURLSchemes(void) +NSSet* systemURLSchemes(void) { LSEnumerator* enumerator = [LSEnumerator enumeratorForApplicationProxiesWithOptions:0]; - enumerator.predicate = [NSPredicate predicateWithFormat:@"bundleIdentifier BEGINSWITH 'com.apple'"]; - NSMutableSet* systemURLSchemes = [NSMutableSet new]; + NSMutableSet* systemURLSchemesSet = [NSMutableSet new]; LSApplicationProxy* proxy; while(proxy = [enumerator nextObject]) { - for(NSString* claimedURLScheme in proxy.claimedURLSchemes) + if(isRemovableSystemApp(proxy.bundleIdentifier) || ![proxy.bundleURL.path hasPrefix:@"/private/var/containers"]) { - if([claimedURLScheme isKindOfClass:NSString.class]) + for(NSString* claimedURLScheme in proxy.claimedURLSchemes) { - [systemURLSchemes addObject:claimedURLScheme.lowercaseString]; + if([claimedURLScheme isKindOfClass:NSString.class]) + { + [systemURLSchemesSet addObject:claimedURLScheme.lowercaseString]; + } } } } - return systemURLSchemes.copy; + return systemURLSchemesSet.copy; } NSSet* immutableAppBundleIdentifiers(void) @@ -535,7 +537,7 @@ void applyPatchesToInfoDictionary(NSString* appPath) infoDictM[@"SBAppUsesLocalNotifications"] = @1; // Remove system claimed URL schemes if existant - NSSet* appleSchemes = appleURLSchemes(); + NSSet* appleSchemes = systemURLSchemes(); NSArray* CFBundleURLTypes = infoDictM[@"CFBundleURLTypes"]; if([CFBundleURLTypes isKindOfClass:[NSArray class]]) { @@ -705,7 +707,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate) if(suc) { NSLog(@"[installApp] App %@ installed, adding to icon cache now...", appId); - registerPath((char*)newAppBundlePath.fileSystemRepresentation, 0, YES); + registerPath(newAppBundlePath, NO, YES); return 0; } else @@ -724,7 +726,7 @@ int uninstallApp(NSString* appPath, NSString* appId) // Most likely the Info.plist is missing // (Hopefully this never happens) deleteSuc = [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:nil]; - registerPath((char*)appPath.fileSystemRepresentation, 1, YES); + registerPath(appPath, YES, YES); return 0; } @@ -839,7 +841,7 @@ int uninstallTrollStore(BOOL unregister) if(unregister) { - registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 1, YES); + registerPath(trollStoreAppPath(), YES, YES); } return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil]; @@ -902,15 +904,19 @@ int installTrollStore(NSString* pathToTar) return ret; } -void refreshAppRegistrations() +void refreshAppRegistrations(BOOL system) { - //registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 1, YES); - registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 0, YES); + // avoid registering TrollStore itself as user ever + if(system) + { + registerPath(trollStoreAppPath(), NO, system); + } + // the reason why there is even an option to register everything as user + // is because it fixes an issue where app permissions would reset during an icon cache reload for(NSString* appPath in trollStoreInstalledAppBundlePaths()) { - //registerPath((char*)appPath.fileSystemRepresentation, 1, YES); - registerPath((char*)appPath.fileSystemRepresentation, 0, YES); + registerPath(appPath, NO, system); } } @@ -1081,7 +1087,7 @@ void cleanRestrictions(void) [valuesArrM enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString* value, NSUInteger idx, BOOL *stop) { - if(![value hasPrefix:@"com.apple."]) + if(!isRemovableSystemApp(value)) { [valuesArrM removeObjectAtIndex:idx]; changed = YES; @@ -1152,12 +1158,13 @@ int MAIN_NAME(int argc, char *argv[], char *envp[]) installLdid(ldidPath); } else if([cmd isEqualToString:@"refresh"]) { - refreshAppRegistrations(); + refreshAppRegistrations(YES); } else if([cmd isEqualToString:@"refresh-all"]) { cleanRestrictions(); + refreshAppRegistrations(NO); // <- fix app permissions resetting [[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES]; - refreshAppRegistrations(); + refreshAppRegistrations(YES); killall(@"backboardd", YES); } else if([cmd isEqualToString:@"install-persistence-helper"]) { @@ -1181,7 +1188,7 @@ int MAIN_NAME(int argc, char *argv[], char *envp[]) NSString* trollStoreMark = [[appPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"_TrollStore"]; if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark]) { - registerPath((char*)appPath.fileSystemRepresentation, 0, [newRegistration isEqualToString:@"System"]); + registerPath(appPath, NO, [newRegistration isEqualToString:@"System"]); } } else if([cmd isEqualToString:@"url-scheme"]) { diff --git a/RootHelper/main.m-system b/RootHelper/main.m-system index d9bb9f5..3164c2b 100644 --- a/RootHelper/main.m-system +++ b/RootHelper/main.m-system @@ -188,7 +188,7 @@ BOOL installApp(NSString* appPath, NSString* appId, BOOL sign, NSError** error) NSLog(@"installApp copied app? %d, adding to uicache now...", suc); - registerPath((char*)newAppPath.UTF8String, 0); + registerPath(newAppPath, NO); return YES; } @@ -198,7 +198,7 @@ BOOL uninstallApp(NSString* appId, NSError** error) NSString* appPath = appPathForAppId(appId, error); if(!appPath) return NO; - registerPath((char*)appPath.UTF8String, 1); + registerPath(appPath, YES); return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error]; } @@ -244,7 +244,7 @@ void uninstallAllApps(void) for(NSString* appId in items) { NSString* appPath = appPathForAppId(appId, nil); - registerPath((char*)appPath.UTF8String, 1); + registerPath(appPath, YES); } [[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil]; @@ -255,7 +255,7 @@ BOOL uninstallTrollStore(void) NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"]; if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO; - registerPath((char*)trollStore.UTF8String, 1); + registerPath(trollStore, YES); return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil]; } diff --git a/RootHelper/uicache.h b/RootHelper/uicache.h index 128391e..cc1591b 100644 --- a/RootHelper/uicache.h +++ b/RootHelper/uicache.h @@ -1 +1 @@ -extern void registerPath(char *path, int unregister, BOOL system); \ No newline at end of file +extern void registerPath(NSString* path, BOOL unregister, BOOL system); \ No newline at end of file diff --git a/RootHelper/uicache.m b/RootHelper/uicache.m index 70fe8bc..d05af82 100644 --- a/RootHelper/uicache.m +++ b/RootHelper/uicache.m @@ -4,6 +4,7 @@ #import #import "dlfcn.h" #import +#import // uicache on steroids @@ -90,10 +91,9 @@ NSDictionary* constructEnvironmentVariablesForContainerPath(NSString* containerP }; } -void registerPath(char* cPath, int unregister, BOOL system) +void registerPath(NSString* path, BOOL unregister, BOOL system) { - if(!cPath) return; - NSString* path = [NSString stringWithUTF8String:cPath]; + if(!path) return; loadMCMFramework(); LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace]; @@ -140,7 +140,7 @@ void registerPath(char* cPath, int unregister, BOOL system) dictToRegister[@"Container"] = containerPath; dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath); } - dictToRegister[@"IsDeletable"] = @NO; + dictToRegister[@"IsDeletable"] = @(![appBundleID isEqualToString:@"com.opa334.TrollStore"] && kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_15_0); dictToRegister[@"Path"] = path; dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements)); dictToRegister[@"SignerOrganization"] = @"Apple Inc."; @@ -159,7 +159,7 @@ void registerPath(char* cPath, int unregister, BOOL system) // Add group containers NSDictionary* appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO); - NSDictionary* systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO); + NSDictionary* systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, YES); NSMutableDictionary* groupContainers = [NSMutableDictionary new]; [groupContainers addEntriesFromDictionary:appGroupContainers]; [groupContainers addEntriesFromDictionary:systemGroupContainers]; diff --git a/Shared/TSUtil.h b/Shared/TSUtil.h index b52d6e7..38dede7 100644 --- a/Shared/TSUtil.h +++ b/Shared/TSUtil.h @@ -19,6 +19,8 @@ extern NSArray* trollStoreInstalledAppContainerPaths(); extern NSString* trollStorePath(); extern NSString* trollStoreAppPath(); +extern BOOL isRemovableSystemApp(NSString* appId); + #import @interface UIAlertController (Private) diff --git a/Shared/TSUtil.m b/Shared/TSUtil.m index 96d6688..8bdfe02 100644 --- a/Shared/TSUtil.m +++ b/Shared/TSUtil.m @@ -326,6 +326,11 @@ NSString* trollStoreAppPath() return [trollStorePath() stringByAppendingPathComponent:@"TrollStore.app"]; } +BOOL isRemovableSystemApp(NSString* appId) +{ + return [[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appId]]; +} + LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes) { __block LSApplicationProxy* outProxy; diff --git a/TrollHelper/TSHRootViewController.m b/TrollHelper/TSHRootViewController.m index b027fed..a46bdb5 100644 --- a/TrollHelper/TSHRootViewController.m +++ b/TrollHelper/TSHRootViewController.m @@ -84,7 +84,7 @@ lastGroupSpecifier = utilitiesGroupSpecifier; - if(isInstalled) + if(isInstalled || trollStoreInstalledAppContainerPaths().count) { PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations" target:self @@ -97,7 +97,9 @@ [refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"]; refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrationsPressed); [_specifiers addObject:refreshAppRegistrationsSpecifier]; - + } + if(isInstalled) + { PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore" target:self set:nil diff --git a/TrollStore/TSSettingsListController.m b/TrollStore/TSSettingsListController.m index 2b6f7e6..6782f9f 100644 --- a/TrollStore/TSSettingsListController.m +++ b/TrollStore/TSSettingsListController.m @@ -329,7 +329,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void); { if(appProxy.installed && !appProxy.restricted) { - if([appProxy.bundleURL.path hasPrefix:@"/private/var/containers"]) + if([[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appProxy.bundleIdentifier]]) { NSURL* trollStoreMarkURL = [appProxy.bundleURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"_TrollStore"]; if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])