diff --git a/README.md b/README.md index 87299e9..68b9127 100644 --- a/README.md +++ b/README.md @@ -157,17 +157,7 @@ When your app is not sandboxed, you can spawn other binaries using posix_spawn, ``` -Because a root binary needs special permissions, you need to specify all your root binaries in the Info.plist of your application like so: - -``` -TSRootBinaries - - roothelper1 - some/nested/roothelper - -``` - -Note: The paths in the TSRootBinaries array are relative to the location of the Info.plist, you can also include this key in other bundles such as app plugins. +You can also add your own binaries into your app bundle. Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L74) to spawn the binary as root. diff --git a/RootHelper/control b/RootHelper/control index 8dd998d..8595b77 100644 --- a/RootHelper/control +++ b/RootHelper/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstoreroothelper Name: trollstoreroothelper -Version: 1.3.2 +Version: 1.3.3 Architecture: iphoneos-arm Description: An awesome tool of some sort!! Maintainer: opa334 diff --git a/RootHelper/main.m b/RootHelper/main.m index 85f4501..6d5ebef 100644 --- a/RootHelper/main.m +++ b/RootHelper/main.m @@ -8,6 +8,8 @@ #import #import #import +#import +#import #import #import @@ -107,6 +109,51 @@ NSString* appPathForAppId(NSString* appId) return nil; } +BOOL isMachoFile(NSString* filePath) +{ + FILE* file = fopen(filePath.UTF8String, "r"); + if(!file) return NO; + + fseek(file, 0, SEEK_SET); + uint32_t magic; + fread(&magic, sizeof(uint32_t), 1, file); + fclose(file); + + return magic == FAT_MAGIC || magic == FAT_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64; +} + +void fixPermissionsOfAppBundle(NSString* appBundlePath) +{ + // Apply correct permissions (First run, set everything to 644, owner 33) + NSURL* fileURL; + NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appBundlePath] includingPropertiesForKeys:nil options:0 errorHandler:nil]; + while(fileURL = [enumerator nextObject]) + { + NSString* filePath = fileURL.path; + chown(filePath.UTF8String, 33, 33); + chmod(filePath.UTF8String, 0644); + } + + // Apply correct permissions (Second run, set executables and directories to 0755) + enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appBundlePath] includingPropertiesForKeys:nil options:0 errorHandler:nil]; + while(fileURL = [enumerator nextObject]) + { + NSString* filePath = fileURL.path; + + BOOL isDir; + [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir]; + + if(isDir || isMachoFile(filePath)) + { + chmod(filePath.UTF8String, 0755); + } + } + + // Set .app directory permissions too + chmod(appBundlePath.UTF8String, 0755); + chown(appBundlePath.UTF8String, 33, 33); +} + void installLdid(NSString* ldidToCopyPath) { if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return; @@ -386,25 +433,9 @@ int signApp(NSString* appPath) while(fileURL = [enumerator nextObject]) { NSString* filePath = fileURL.path; - - BOOL isDir; - [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir]; - - if([filePath.lastPathComponent isEqualToString:@"Info.plist"]) + if(isMachoFile(filePath)) { - NSDictionary* infoDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath]; - NSArray* tsRootBinaries = infoDictionary[@"TSRootBinaries"]; - if(tsRootBinaries && [tsRootBinaries isKindOfClass:[NSArray class]]) - { - for(NSString* rootBinary in tsRootBinaries) - { - if([rootBinary isKindOfClass:[NSString class]]) - { - NSString* rootBinaryPath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:rootBinary]; - storedEntitlements[rootBinaryPath] = dumpEntitlementsFromBinaryAtPath(rootBinaryPath); - } - } - } + storedEntitlements[filePath] = dumpEntitlementsFromBinaryAtPath(filePath); } } @@ -413,11 +444,15 @@ int signApp(NSString* appPath) [storedEntitlements enumerateKeysAndObjectsUsingBlock:^(NSString* binaryPath, NSDictionary* entitlements, BOOL* stop) { - NSString* tmpEntitlementPlistPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ent.xml"]; - [entitlements writeToURL:[NSURL fileURLWithPath:tmpEntitlementPlistPath] error:nil]; - NSString* tmpEntitlementArg = [@"-S" stringByAppendingString:tmpEntitlementPlistPath]; - runLdid(@[tmpEntitlementArg, certArg, binaryPath], nil, nil); - [[NSFileManager defaultManager] removeItemAtPath:tmpEntitlementPlistPath error:nil]; + NSDictionary* newEntitlements = dumpEntitlementsFromBinaryAtPath(binaryPath); + if(!newEntitlements || ![newEntitlements isEqualToDictionary:entitlements]) + { + NSString* tmpEntitlementPlistPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ent.xml"]; + [entitlements writeToURL:[NSURL fileURLWithPath:tmpEntitlementPlistPath] error:nil]; + NSString* tmpEntitlementArg = [@"-S" stringByAppendingString:tmpEntitlementPlistPath]; + runLdid(@[tmpEntitlementArg, certArg, binaryPath], nil, nil); + [[NSFileManager defaultManager] removeItemAtPath:tmpEntitlementPlistPath error:nil]; + } }]; } @@ -554,68 +589,7 @@ int installApp(NSString* appPath, BOOL sign, BOOL force) return 177; } - // Apply correct permissions (First run, set everything to 644, owner 33) - NSURL* fileURL; - NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil]; - while(fileURL = [enumerator nextObject]) - { - NSString* filePath = fileURL.path; - chown(filePath.UTF8String, 33, 33); - chmod(filePath.UTF8String, 0644); - NSLog(@"[installApp] setting %@ to chown(33,33) chmod(0644)", filePath); - } - - // Apply correct permissions (Second run, set executables and directories to 0755) - enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil]; - while(fileURL = [enumerator nextObject]) - { - NSString* filePath = fileURL.path; - - BOOL isDir; - [[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir]; - - if([filePath.lastPathComponent isEqualToString:@"Info.plist"]) - { - NSDictionary* infoDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath]; - NSString* executable = infoDictionary[@"CFBundleExecutable"]; - if(executable && [executable isKindOfClass:[NSString class]]) - { - NSString* executablePath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:executable]; - chmod(executablePath.UTF8String, 0755); - NSLog(@"[installApp] applied permissions for bundle executable %@", executablePath); - } - NSArray* tsRootBinaries = infoDictionary[@"TSRootBinaries"]; - if(tsRootBinaries && [tsRootBinaries isKindOfClass:[NSArray class]]) - { - for(NSString* rootBinary in tsRootBinaries) - { - if([rootBinary isKindOfClass:[NSString class]]) - { - NSString* rootBinaryPath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:rootBinary]; - if([[NSFileManager defaultManager] fileExistsAtPath:rootBinaryPath]) - { - chmod(rootBinaryPath.UTF8String, 0755); - chown(rootBinaryPath.UTF8String, 0, 0); - NSLog(@"[installApp] applied permissions for root binary %@", rootBinaryPath); - } - } - } - } - } - else if(!isDir && [filePath.pathExtension isEqualToString:@"dylib"]) - { - chmod(filePath.UTF8String, 0755); - } - else if(isDir) - { - // apparently all dirs are writable by default - chmod(filePath.UTF8String, 0755); - } - } - - // Set .app directory permissions too - chmod(appPath.UTF8String, 0755); - chown(appPath.UTF8String, 33, 33); + fixPermissionsOfAppBundle(appPath); // Wipe old version if needed if(existed) diff --git a/Shared/CoreServices.h b/Shared/CoreServices.h index 1120192..de33eef 100644 --- a/Shared/CoreServices.h +++ b/Shared/CoreServices.h @@ -24,9 +24,10 @@ - (BOOL)registerApplicationDictionary:(NSDictionary*)dict; - (BOOL)unregisterApplication:(id)arg1; - (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 internal:(BOOL)arg2 user:(BOOL)arg3; -- (BOOL)uninstallApplication:(NSString*)arg1 withOptions:(id)arg2; - (BOOL)openApplicationWithBundleID:(NSString *)arg1 ; - (void)enumerateApplicationsOfType:(NSUInteger)type block:(void (^)(LSApplicationProxy*))block; +- (BOOL)installApplication:(NSString*)pathToExtractedApp withOptions:(NSDictionary*)options; +- (BOOL)uninstallApplication:(NSString*)appId withOptions:(NSDictionary*)options; @end @interface LSEnumerator : NSEnumerator diff --git a/TrollHelper/Resources/Info.plist b/TrollHelper/Resources/Info.plist index 3c4f797..5341728 100644 --- a/TrollHelper/Resources/Info.plist +++ b/TrollHelper/Resources/Info.plist @@ -52,7 +52,7 @@ iPhoneOS CFBundleVersion - 1.3.2 + 1.3.3 LSRequiresIPhoneOS UIDeviceFamily diff --git a/TrollHelper/control b/TrollHelper/control index 92d5aec..57fd092 100644 --- a/TrollHelper/control +++ b/TrollHelper/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstorehelper Name: TrollStore Helper -Version: 1.3.2 +Version: 1.3.3 Architecture: iphoneos-arm Description: Helper utility to install and manage TrollStore! Maintainer: opa334 diff --git a/TrollStore/Resources/Info.plist b/TrollStore/Resources/Info.plist index 4624cd8..b82f0d8 100644 --- a/TrollStore/Resources/Info.plist +++ b/TrollStore/Resources/Info.plist @@ -50,7 +50,7 @@ iPhoneOS CFBundleVersion - 1.3.2 + 1.3.3 LSRequiresIPhoneOS UIDeviceFamily @@ -188,10 +188,5 @@ LSSupportsOpeningDocumentsInPlace - TSRootBinaries - - trollstorehelper - ldid - diff --git a/TrollStore/TSAppInfo.m b/TrollStore/TSAppInfo.m index 8872a8c..ae7c957 100644 --- a/TrollStore/TSAppInfo.m +++ b/TrollStore/TSAppInfo.m @@ -766,20 +766,6 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); NSString* version = [self versionString]; NSString* sizeString = [self sizeString]; - // Check if any bundle contains a root binary - __block BOOL containsRootBinary = NO; - [self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) { - if([key isEqualToString:@"TSRootBinaries"]) - { - NSArray* valueArr = (NSArray*)value; - if([valueArr isKindOfClass:NSArray.class]) - { - containsRootBinary = valueArr.count; - if(containsRootBinary) *stop = YES; - } - } - }]; - // Check if any bundles main binary runs unsandboxed __block BOOL isUnsandboxed = NO; [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) { @@ -811,7 +797,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); }]; // Check if any bundles main binary can spawn an external binary - __block BOOL canSpawnBinaries = NO; + __block BOOL isPlatformApplication = NO; [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) { if([key isEqualToString:@"platform-application"]) @@ -819,8 +805,8 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); NSNumber* valueNum = (NSNumber*)value; if(valueNum && [valueNum isKindOfClass:NSNumber.class]) { - canSpawnBinaries = valueNum.boolValue; - if(canSpawnBinaries) *stop = YES; + isPlatformApplication = valueNum.boolValue; + if(isPlatformApplication) *stop = YES; } } }]; @@ -1072,15 +1058,11 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); } [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nCapabilities" attributes:headerAttributes]]; - if(containsRootBinary && canSpawnBinaries && hasPersonaMngmt) + if(isPlatformApplication && isUnsandboxed && hasPersonaMngmt) { [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn its own embedded binaries with root privileges." attributes:bodyDangerAttributes]]; } - else if(canSpawnBinaries && hasPersonaMngmt) - { - [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as root, but does not contain any such binaries by itself." attributes:bodyWarningAttributes]]; - } - else if(canSpawnBinaries) + else if(isPlatformApplication && isUnsandboxed) { [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as the mobile user." attributes:bodyWarningAttributes]]; } @@ -1092,15 +1074,15 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size); if(allowedTccServices.count) { [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nPrivacy" attributes:headerAttributes]]; - [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access the following services without asking for permission:\n" attributes:bodyDangerAttributes]]; - [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedTccServices allObjects]] attributes:bodyAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access the following services without asking for permission:\n" attributes:bodyWarningAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedTccServices allObjects]] attributes:bodyWarningAttributes]]; } if (allowedMGKeys.count) { [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nDevice Info" attributes:headerAttributes]]; - [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access protected information about this device.\n" attributes:bodyWarningAttributes]]; - [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedMGKeys allObjects]] attributes:bodyAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access protected information about this device:\n" attributes:bodyWarningAttributes]]; + [description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedMGKeys allObjects]] attributes:bodyWarningAttributes]]; } if(unrestrictedContainerAccess || accessibleContainers.count) diff --git a/TrollStore/control b/TrollStore/control index 1b3bbe6..7260269 100644 --- a/TrollStore/control +++ b/TrollStore/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstore Name: TrollStore -Version: 1.3.2 +Version: 1.3.3 Architecture: iphoneos-arm Description: An awesome application! Maintainer: opa334