From 01e601c82db4ca5c8fa998d78b5250936942b240 Mon Sep 17 00:00:00 2001 From: poomsmart Date: Wed, 14 Apr 2021 21:07:40 +0000 Subject: [uicache] Add support for listing installed applications back to iOS 6. --- uicache.mm | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/uicache.mm b/uicache.mm index 28ea420..7e4c830 100644 --- a/uicache.mm +++ b/uicache.mm @@ -122,14 +122,14 @@ @end -@interface LSApplicationState : NSObject +@interface _LSApplicationState : NSObject -(bool)isValid; @end @interface LSApplicationProxy : NSObject +(LSApplicationProxy*)applicationProxyForIdentifier:(NSString*)appid; -(NSString*)applicationIdentifier; --(LSApplicationState*)appState; +-(_LSApplicationState*)appState; -(NSURL*)bundleURL; -(NSURL*)containerURL; -(NSDate*)registeredDate; @@ -144,6 +144,7 @@ - (BOOL) installApplication:(id)application withOptions:(id)options; - (BOOL) _LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)system internal:(BOOL)internal user:(BOOL)user; - (NSArray*) allApplications; +- (NSArray*) installedApplications; @end @interface MCMAppDataContainer @@ -175,11 +176,41 @@ static Class $LSApplicationWorkspace; LSApplicationWorkspace *workspace; static bool force; +NSArray *getAllApplications() +{ + LSApplicationWorkspace *w = workspace ?: [LSApplicationWorkspace defaultWorkspace]; + if ([w respondsToSelector:@selector(allApplications)]) + return [w allApplications]; + else if ([w respondsToSelector:@selector(installedApplications)]) { + NSMutableArray *apps = [NSMutableArray array]; + for (NSString *applicationIdentifier in [w installedApplications]) { + [apps addObject:[LSApplicationProxy applicationProxyForIdentifier:applicationIdentifier]]; + } + return apps; + } + fprintf(stderr, "Error: This iOS version doesn't support listing all applications\n"); + return [NSArray array]; +} + +const char *getFileSystemRepresentation(NSURL *url) +{ + if ([url respondsToSelector:@selector(fileSystemRepresentation)]) + return [url fileSystemRepresentation]; + void *buffer = malloc(0x400); + if (buffer) { + UInt8 *data = (UInt8 *)[NSData dataWithBytesNoCopy:buffer length:0x400].bytes; + if (CFURLGetFileSystemRepresentation((__bridge CFURLRef)url, true, data, 0x400)) + return (const char *)buffer; + free(buffer); + } + return ""; +} + int list_all_apps(void) { - NSArray *allApps = [[LSApplicationWorkspace defaultWorkspace] allApplications]; + NSArray *allApps = getAllApplications(); for (LSApplicationProxy *app in allApps) { - printf("%s : %s\n", [[app applicationIdentifier] UTF8String], [[app bundleURL] fileSystemRepresentation]); + printf("%s : %s\n", [[app applicationIdentifier] UTF8String], getFileSystemRepresentation([app bundleURL])); } return 0; } @@ -189,15 +220,20 @@ int list_app(NSString *appid) { return 1; } LSApplicationProxy *app = [LSApplicationProxy applicationProxyForIdentifier:appid]; - LSApplicationState *appState = [app appState]; - if (![appState isValid]) { - fprintf(stderr, "Invalid appID provided: %s\n", appid.UTF8String); - return 1; + _LSApplicationState *appState = nil; + BOOL hasAppState = [app respondsToSelector:@selector(appState)]; + if (hasAppState) { + appState = [app appState]; + if (![appState isValid]) { + fprintf(stderr, "Invalid appID provided: %s\n", appid.UTF8String); + return 1; + } } printf("Information for %s\n", appid.UTF8String); - printf("State: %s\n", [[appState description] UTF8String]); - printf("Path: %s\n", [[app bundleURL] fileSystemRepresentation]); - printf("Container Path: %s\n", [[app containerURL] fileSystemRepresentation]); + if (hasAppState) + printf("State: %s\n", [[appState description] UTF8String]); + printf("Path: %s\n", getFileSystemRepresentation([app bundleURL])); + printf("Container Path: %s\n", getFileSystemRepresentation([app containerURL])); return 0; } @@ -218,7 +254,7 @@ bool appIsRegistered(NSString *path) @autoreleasepool { path = getAppPath(path); if (!path) return false; - for (LSApplicationProxy *app in [workspace allApplications]) { + for (LSApplicationProxy *app in getAllApplications()) { if ([path isEqualToString:[[app bundleURL] path]]) return true; } return false; @@ -235,7 +271,7 @@ bool unregisterPath(NSString *path) LSApplicationProxy *app = [LSApplicationProxy applicationProxyForIdentifier:path]; if (app) { url = [app bundleURL]; - if (verbose) fprintf(stderr, "Resolved bundle ID %s to path %s\n", path.UTF8String, [url fileSystemRepresentation]); + if (verbose) fprintf(stderr, "Resolved bundle ID %s to path %s\n", path.UTF8String, getFileSystemRepresentation(url)); path = [url path]; } } else { @@ -586,7 +622,7 @@ int optimized_uicache(void) { NSMutableArray *cleanup = [NSMutableArray new]; NSMutableArray *finds = [NSMutableArray new]; if (verbose>1) fprintf(stderr, "Enumerating apps\n"); - for (LSApplicationProxy *app in [workspace allApplications]) { + for (LSApplicationProxy *app in getAllApplications()) { NSString *path = [[app bundleURL] path]; if (![path hasPrefix:@"/Applications/"]) continue; if (verbose>1) fprintf(stderr, "Checking %s\n", path.lastPathComponent.UTF8String); -- cgit v1.2.3