This commit is contained in:
opa334 2022-11-29 23:46:01 +01:00
parent c572b1b84c
commit 67ec5ff14f
8 changed files with 49 additions and 33 deletions

View File

@ -48,25 +48,27 @@ NSArray<LSApplicationProxy*>* applicationsWithGroupId(NSString* groupId)
return enumerator.allObjects; return enumerator.allObjects;
} }
NSSet<NSString*>* appleURLSchemes(void) NSSet<NSString*>* systemURLSchemes(void)
{ {
LSEnumerator* enumerator = [LSEnumerator enumeratorForApplicationProxiesWithOptions:0]; LSEnumerator* enumerator = [LSEnumerator enumeratorForApplicationProxiesWithOptions:0];
enumerator.predicate = [NSPredicate predicateWithFormat:@"bundleIdentifier BEGINSWITH 'com.apple'"];
NSMutableSet* systemURLSchemes = [NSMutableSet new]; NSMutableSet* systemURLSchemesSet = [NSMutableSet new];
LSApplicationProxy* proxy; LSApplicationProxy* proxy;
while(proxy = [enumerator nextObject]) 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<NSString*>* immutableAppBundleIdentifiers(void) NSSet<NSString*>* immutableAppBundleIdentifiers(void)
@ -535,7 +537,7 @@ void applyPatchesToInfoDictionary(NSString* appPath)
infoDictM[@"SBAppUsesLocalNotifications"] = @1; infoDictM[@"SBAppUsesLocalNotifications"] = @1;
// Remove system claimed URL schemes if existant // Remove system claimed URL schemes if existant
NSSet* appleSchemes = appleURLSchemes(); NSSet* appleSchemes = systemURLSchemes();
NSArray* CFBundleURLTypes = infoDictM[@"CFBundleURLTypes"]; NSArray* CFBundleURLTypes = infoDictM[@"CFBundleURLTypes"];
if([CFBundleURLTypes isKindOfClass:[NSArray class]]) if([CFBundleURLTypes isKindOfClass:[NSArray class]])
{ {
@ -705,7 +707,7 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate)
if(suc) if(suc)
{ {
NSLog(@"[installApp] App %@ installed, adding to icon cache now...", appId); NSLog(@"[installApp] App %@ installed, adding to icon cache now...", appId);
registerPath((char*)newAppBundlePath.fileSystemRepresentation, 0, YES); registerPath(newAppBundlePath, NO, YES);
return 0; return 0;
} }
else else
@ -724,7 +726,7 @@ int uninstallApp(NSString* appPath, NSString* appId)
// Most likely the Info.plist is missing // Most likely the Info.plist is missing
// (Hopefully this never happens) // (Hopefully this never happens)
deleteSuc = [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:nil]; deleteSuc = [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:nil];
registerPath((char*)appPath.fileSystemRepresentation, 1, YES); registerPath(appPath, YES, YES);
return 0; return 0;
} }
@ -839,7 +841,7 @@ int uninstallTrollStore(BOOL unregister)
if(unregister) if(unregister)
{ {
registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 1, YES); registerPath(trollStoreAppPath(), YES, YES);
} }
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil]; return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
@ -902,15 +904,19 @@ int installTrollStore(NSString* pathToTar)
return ret; return ret;
} }
void refreshAppRegistrations() void refreshAppRegistrations(BOOL system)
{ {
//registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 1, YES); // avoid registering TrollStore itself as user ever
registerPath((char*)trollStoreAppPath().fileSystemRepresentation, 0, YES); 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()) for(NSString* appPath in trollStoreInstalledAppBundlePaths())
{ {
//registerPath((char*)appPath.fileSystemRepresentation, 1, YES); registerPath(appPath, NO, system);
registerPath((char*)appPath.fileSystemRepresentation, 0, YES);
} }
} }
@ -1081,7 +1087,7 @@ void cleanRestrictions(void)
[valuesArrM enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString* value, NSUInteger idx, BOOL *stop) [valuesArrM enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString* value, NSUInteger idx, BOOL *stop)
{ {
if(![value hasPrefix:@"com.apple."]) if(!isRemovableSystemApp(value))
{ {
[valuesArrM removeObjectAtIndex:idx]; [valuesArrM removeObjectAtIndex:idx];
changed = YES; changed = YES;
@ -1152,12 +1158,13 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
installLdid(ldidPath); installLdid(ldidPath);
} else if([cmd isEqualToString:@"refresh"]) } else if([cmd isEqualToString:@"refresh"])
{ {
refreshAppRegistrations(); refreshAppRegistrations(YES);
} else if([cmd isEqualToString:@"refresh-all"]) } else if([cmd isEqualToString:@"refresh-all"])
{ {
cleanRestrictions(); cleanRestrictions();
refreshAppRegistrations(NO); // <- fix app permissions resetting
[[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES]; [[LSApplicationWorkspace defaultWorkspace] _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:YES];
refreshAppRegistrations(); refreshAppRegistrations(YES);
killall(@"backboardd", YES); killall(@"backboardd", YES);
} else if([cmd isEqualToString:@"install-persistence-helper"]) } 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"]; NSString* trollStoreMark = [[appPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"_TrollStore"];
if([[NSFileManager defaultManager] fileExistsAtPath:trollStoreMark]) 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"]) } else if([cmd isEqualToString:@"url-scheme"])
{ {

View File

@ -188,7 +188,7 @@ BOOL installApp(NSString* appPath, NSString* appId, BOOL sign, NSError** error)
NSLog(@"installApp copied app? %d, adding to uicache now...", suc); NSLog(@"installApp copied app? %d, adding to uicache now...", suc);
registerPath((char*)newAppPath.UTF8String, 0); registerPath(newAppPath, NO);
return YES; return YES;
} }
@ -198,7 +198,7 @@ BOOL uninstallApp(NSString* appId, NSError** error)
NSString* appPath = appPathForAppId(appId, error); NSString* appPath = appPathForAppId(appId, error);
if(!appPath) return NO; if(!appPath) return NO;
registerPath((char*)appPath.UTF8String, 1); registerPath(appPath, YES);
return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error]; return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
} }
@ -244,7 +244,7 @@ void uninstallAllApps(void)
for(NSString* appId in items) for(NSString* appId in items)
{ {
NSString* appPath = appPathForAppId(appId, nil); NSString* appPath = appPathForAppId(appId, nil);
registerPath((char*)appPath.UTF8String, 1); registerPath(appPath, YES);
} }
[[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil]; [[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil];
@ -255,7 +255,7 @@ BOOL uninstallTrollStore(void)
NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"]; NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO; if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO;
registerPath((char*)trollStore.UTF8String, 1); registerPath(trollStore, YES);
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil]; return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
} }

View File

@ -1 +1 @@
extern void registerPath(char *path, int unregister, BOOL system); extern void registerPath(NSString* path, BOOL unregister, BOOL system);

View File

@ -4,6 +4,7 @@
#import <objc/runtime.h> #import <objc/runtime.h>
#import "dlfcn.h" #import "dlfcn.h"
#import <TSUtil.h> #import <TSUtil.h>
#import <version.h>
// uicache on steroids // 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; if(!path) return;
NSString* path = [NSString stringWithUTF8String:cPath];
loadMCMFramework(); loadMCMFramework();
LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace]; LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace];
@ -140,7 +140,7 @@ void registerPath(char* cPath, int unregister, BOOL system)
dictToRegister[@"Container"] = containerPath; dictToRegister[@"Container"] = containerPath;
dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath); dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath);
} }
dictToRegister[@"IsDeletable"] = @NO; dictToRegister[@"IsDeletable"] = @(![appBundleID isEqualToString:@"com.opa334.TrollStore"] && kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_15_0);
dictToRegister[@"Path"] = path; dictToRegister[@"Path"] = path;
dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements)); dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements));
dictToRegister[@"SignerOrganization"] = @"Apple Inc."; dictToRegister[@"SignerOrganization"] = @"Apple Inc.";
@ -159,7 +159,7 @@ void registerPath(char* cPath, int unregister, BOOL system)
// Add group containers // Add group containers
NSDictionary* appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO); NSDictionary* appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO);
NSDictionary* systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO); NSDictionary* systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, YES);
NSMutableDictionary* groupContainers = [NSMutableDictionary new]; NSMutableDictionary* groupContainers = [NSMutableDictionary new];
[groupContainers addEntriesFromDictionary:appGroupContainers]; [groupContainers addEntriesFromDictionary:appGroupContainers];
[groupContainers addEntriesFromDictionary:systemGroupContainers]; [groupContainers addEntriesFromDictionary:systemGroupContainers];

View File

@ -19,6 +19,8 @@ extern NSArray* trollStoreInstalledAppContainerPaths();
extern NSString* trollStorePath(); extern NSString* trollStorePath();
extern NSString* trollStoreAppPath(); extern NSString* trollStoreAppPath();
extern BOOL isRemovableSystemApp(NSString* appId);
#import <UIKit/UIAlertController.h> #import <UIKit/UIAlertController.h>
@interface UIAlertController (Private) @interface UIAlertController (Private)

View File

@ -326,6 +326,11 @@ NSString* trollStoreAppPath()
return [trollStorePath() stringByAppendingPathComponent:@"TrollStore.app"]; return [trollStorePath() stringByAppendingPathComponent:@"TrollStore.app"];
} }
BOOL isRemovableSystemApp(NSString* appId)
{
return [[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appId]];
}
LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes) LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes)
{ {
__block LSApplicationProxy* outProxy; __block LSApplicationProxy* outProxy;

View File

@ -84,7 +84,7 @@
lastGroupSpecifier = utilitiesGroupSpecifier; lastGroupSpecifier = utilitiesGroupSpecifier;
if(isInstalled) if(isInstalled || trollStoreInstalledAppContainerPaths().count)
{ {
PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations" PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations"
target:self target:self
@ -97,7 +97,9 @@
[refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"]; [refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"];
refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrationsPressed); refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrationsPressed);
[_specifiers addObject:refreshAppRegistrationsSpecifier]; [_specifiers addObject:refreshAppRegistrationsSpecifier];
}
if(isInstalled)
{
PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore" PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore"
target:self target:self
set:nil set:nil

View File

@ -329,7 +329,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
{ {
if(appProxy.installed && !appProxy.restricted) 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"]; NSURL* trollStoreMarkURL = [appProxy.bundleURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"_TrollStore"];
if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil]) if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])