Compare commits

..

No commits in common. "9e27e74fc9f26b65fc31132c87fc929a521ca0d5" and "3fe3e7f241e436bb8b3c35d94746057e280a9a4a" have entirely different histories.

8 changed files with 184 additions and 215 deletions

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstoreroothelper Package: com.opa334.trollstoreroothelper
Name: trollstoreroothelper Name: trollstoreroothelper
Version: 2.0.6 Version: 2.0.5
Architecture: iphoneos-arm Architecture: iphoneos-arm
Description: An awesome tool of some sort!! Description: An awesome tool of some sort!!
Maintainer: opa334 Maintainer: opa334

View File

@ -562,89 +562,29 @@ int signApp(NSString* appPath)
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", mainExecutablePath); NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", mainExecutablePath);
}*/ }*/
NSURL* fileURL; int (^signFile)(NSString *, NSDictionary *) = ^(NSString *filePath, NSDictionary *entitlements) {
NSDirectoryEnumerator *enumerator; NSLog(@"Checking %@", filePath);
// Due to how the new CT bug works, in order for data containers to work properly we need to add the
// com.apple.private.security.container-required=<bundle-identifier> entitlement to every binary inside a bundle
// For this we will want to first collect info about all the bundles in the app by seeking for Info.plist files and adding the ent to the main binary
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
if ([filePath.lastPathComponent isEqualToString:@"Info.plist"]) {
NSDictionary *infoDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
if (!infoDict) continue;
NSString *bundleId = infoDict[@"CFBundleIdentifier"];
NSString *bundleExecutable = infoDict[@"CFBundleExecutable"];
if (!bundleId || !bundleExecutable) continue;
NSString *bundleMainExecutablePath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:bundleExecutable];
if (![[NSFileManager defaultManager] fileExistsAtPath:bundleMainExecutablePath]) continue;
NSString *packageType = infoDict[@"CFBundlePackageType"];
// We don't care about frameworks (yet)
if ([packageType isEqualToString:@"FMWK"]) continue;
NSMutableDictionary *entitlementsToUse = dumpEntitlementsFromBinaryAtPath(bundleMainExecutablePath).mutableCopy;
if (isSameFile(bundleMainExecutablePath, mainExecutablePath)) {
// In the case where the main executable of the app currently has no entitlements at all
// We want to ensure it gets signed with fallback entitlements
// These mimic the entitlements that Xcodes gives every app it signs
if (!entitlementsToUse) {
entitlementsToUse = @{
@"application-identifier" : @"TROLLTROLL.*",
@"com.apple.developer.team-identifier" : @"TROLLTROLL",
@"get-task-allow" : (__bridge id)kCFBooleanTrue,
@"keychain-access-groups" : @[
@"TROLLTROLL.*",
@"com.apple.token"
],
}.mutableCopy;
}
}
if (!entitlementsToUse) entitlementsToUse = [NSMutableDictionary new];
NSObject *containerRequiredO = entitlementsToUse[@"com.apple.private.security.container-required"];
BOOL containerRequired = YES;
if (containerRequiredO && [containerRequiredO isKindOfClass:[NSNumber class]]) {
containerRequired = [(NSNumber *)containerRequiredO boolValue];
}
else if (containerRequiredO && [containerRequiredO isKindOfClass:[NSString class]]) {
// Keep whatever is in it if it's a string...
containerRequired = NO;
}
if (containerRequired) {
NSObject *noContainerO = entitlementsToUse[@"com.apple.private.security.no-container"];
BOOL noContainer = NO;
if (noContainerO && [noContainerO isKindOfClass:[NSNumber class]]) {
noContainer = [(NSNumber *)noContainerO boolValue];
}
if (!noContainer) {
entitlementsToUse[@"com.apple.private.security.container-required"] = bundleId;
}
}
signAdhoc(bundleMainExecutablePath, entitlementsToUse);
}
}
// All entitlement related issues should be fixed at this point, so all we need to do is sign the entire bundle
// And then apply the CoreTrust bypass to all executables
// XXX: This only works because we're using ldid at the moment and that recursively signs everything
signAdhoc(appPath, nil);
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation); FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (fat) { if (fat) {
NSLog(@"%@ is binary", filePath); NSLog(@"%@ is binary", filePath);
fat_free(fat);
// First attempt ad hoc signing
int r = signAdhoc(filePath, entitlements);
if (r != 0) {
// If it doesn't work it's not a big deal, that usually happens when the binary had the bypass applied already (Don't ask me why)
NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r);
}
else {
NSLog(@"[%@] Adhoc signing worked!\n", filePath);
}
fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (!fat) return 175; // This should never happen, if it does then everything is fucked
// Now apply CoreTrust bypass to best slice
MachO *machoForExtraction = fat_find_preferred_slice(fat); MachO *machoForExtraction = fat_find_preferred_slice(fat);
if (machoForExtraction) { if (machoForExtraction) {
// Extract best slice
NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
MemoryStream *sliceStream = macho_get_stream(machoForExtraction); MemoryStream *sliceStream = macho_get_stream(machoForExtraction);
MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND); MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND);
@ -652,10 +592,12 @@ int signApp(NSString* appPath)
memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream)); memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream));
memory_stream_free(sliceOutStream); memory_stream_free(sliceOutStream);
// Now we have the best slice at tmpPath, which we will apply the bypass to, then copy it over the original file // Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy over the original file
// We loose all other slices doing that but they aren't a loss as they wouldn't run either way
NSLog(@"[%@] Adhoc signing...", filePath);
NSLog(@"[%@] Applying CoreTrust bypass...", filePath); NSLog(@"[%@] Applying CoreTrust bypass...", filePath);
int r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation); r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation);
if (r == 0) { if (r == 0) {
NSLog(@"[%@] Applied CoreTrust bypass!", filePath); NSLog(@"[%@] Applied CoreTrust bypass!", filePath);
} }
@ -672,9 +614,39 @@ int signApp(NSString* appPath)
} }
fat_free(fat); fat_free(fat);
} }
return 0;
};
NSURL* fileURL;
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
{
NSString *filePath = fileURL.path;
if (isSameFile(filePath, mainExecutablePath)) {
// Skip main executable, we will sign it at the end
continue;
}
int r = signFile(filePath, nil);
if (r != 0) return r;
} }
return 0; // In the case where the main executable currently has no entitlements at all
// We want to ensure it gets signed with fallback entitlements
// These mimic the entitlements that Xcodes gives every app it signs
NSDictionary *entitlementsToUse = nil;
NSDictionary* mainExecutableEntitlements = dumpEntitlementsFromBinaryAtPath(mainExecutablePath);
if (!mainExecutableEntitlements) {
entitlementsToUse = @{
@"application-identifier" : @"TROLLTROLL.*",
@"com.apple.developer.team-identifier" : @"TROLLTROLL",
@"get-task-allow" : (__bridge id)kCFBooleanTrue,
@"keychain-access-groups" : @[
@"TROLLTROLL.*",
@"com.apple.token"
],
};
}
return signFile(mainExecutablePath, entitlementsToUse);
} }
#endif #endif

View File

@ -11,27 +11,33 @@
extern NSSet<NSString*>* immutableAppBundleIdentifiers(void); extern NSSet<NSString*>* immutableAppBundleIdentifiers(void);
extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString* binaryPath); extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString* binaryPath);
NSDictionary *constructGroupsContainersForEntitlements(NSDictionary *entitlements, BOOL systemGroups) { NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlements, BOOL systemGroups)
if (!entitlements) return nil; {
if(!entitlements) return nil;
NSString *entitlementForGroups; NSString* entitlementForGroups;
Class mcmClass; Class mcmClass;
if (systemGroups) { if(systemGroups)
{
entitlementForGroups = @"com.apple.security.system-groups"; entitlementForGroups = @"com.apple.security.system-groups";
mcmClass = [MCMSystemDataContainer class]; mcmClass = [MCMSystemDataContainer class];
} }
else { else
{
entitlementForGroups = @"com.apple.security.application-groups"; entitlementForGroups = @"com.apple.security.application-groups";
mcmClass = [MCMSharedDataContainer class]; mcmClass = [MCMSharedDataContainer class];
} }
NSArray *groupIDs = entitlements[entitlementForGroups]; NSArray* groupIDs = entitlements[entitlementForGroups];
if (groupIDs && [groupIDs isKindOfClass:[NSArray class]]) { if(groupIDs && [groupIDs isKindOfClass:[NSArray class]])
NSMutableDictionary *groupContainers = [NSMutableDictionary new]; {
NSMutableDictionary* groupContainers = [NSMutableDictionary new];
for (NSString *groupID in groupIDs) { for(NSString* groupID in groupIDs)
MCMContainer *container = [mcmClass containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil]; {
if (container.url) { MCMContainer* container = [mcmClass containerWithIdentifier:groupID createIfNecessary:YES existed:nil error:nil];
if(container.url)
{
groupContainers[groupID] = container.url.path; groupContainers[groupID] = container.url.path;
} }
} }
@ -42,98 +48,100 @@ NSDictionary *constructGroupsContainersForEntitlements(NSDictionary *entitlement
return nil; return nil;
} }
BOOL constructContainerizationForEntitlements(NSDictionary *entitlements, NSString **customContainerOut) { BOOL constructContainerizationForEntitlements(NSDictionary* entitlements)
NSNumber *noContainer = entitlements[@"com.apple.private.security.no-container"]; {
if (noContainer && [noContainer isKindOfClass:[NSNumber class]]) { NSNumber* noContainer = entitlements[@"com.apple.private.security.no-container"];
if (noContainer.boolValue) { if(noContainer && [noContainer isKindOfClass:[NSNumber class]])
{
if(noContainer.boolValue)
{
return NO; return NO;
} }
} }
NSObject *containerRequired = entitlements[@"com.apple.private.security.container-required"]; NSNumber* containerRequired = entitlements[@"com.apple.private.security.container-required"];
if (containerRequired && [containerRequired isKindOfClass:[NSNumber class]]) { if(containerRequired && [containerRequired isKindOfClass:[NSNumber class]])
if (!((NSNumber *)containerRequired).boolValue) { {
if(!containerRequired.boolValue)
{
return NO; return NO;
} }
} }
else if (containerRequired && [containerRequired isKindOfClass:[NSString class]]) {
*customContainerOut = (NSString *)containerRequired;
}
return YES; return YES;
} }
NSString *constructTeamIdentifierForEntitlements(NSDictionary *entitlements) { NSString* constructTeamIdentifierForEntitlements(NSDictionary* entitlements)
NSString *teamIdentifier = entitlements[@"com.apple.developer.team-identifier"]; {
if (teamIdentifier && [teamIdentifier isKindOfClass:[NSString class]]) { NSString* teamIdentifier = entitlements[@"com.apple.developer.team-identifier"];
if(teamIdentifier && [teamIdentifier isKindOfClass:[NSString class]])
{
return teamIdentifier; return teamIdentifier;
} }
return nil; return nil;
} }
NSDictionary *constructEnvironmentVariablesForContainerPath(NSString *containerPath, BOOL isContainerized) { NSDictionary* constructEnvironmentVariablesForContainerPath(NSString* containerPath)
NSString *homeDir = isContainerized ? containerPath : @"/var/mobile"; {
NSString *tmpDir = isContainerized ? [containerPath stringByAppendingPathComponent:@"tmp"] : @"/var/tmp"; NSString* tmpDir = [containerPath stringByAppendingPathComponent:@"tmp"];
return @{ return @{
@"CFFIXED_USER_HOME" : homeDir, @"CFFIXED_USER_HOME" : containerPath,
@"HOME" : homeDir, @"HOME" : containerPath,
@"TMPDIR" : tmpDir @"TMPDIR" : tmpDir
}; };
} }
void registerPath(NSString *path, BOOL unregister, BOOL forceSystem) { void registerPath(NSString* path, BOOL unregister, BOOL system)
if (!path) return; {
if(!path) return;
LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace]; LSApplicationWorkspace* workspace = [LSApplicationWorkspace defaultWorkspace];
if (unregister && ![[NSFileManager defaultManager] fileExistsAtPath:path]) { if(unregister && ![[NSFileManager defaultManager] fileExistsAtPath:path])
LSApplicationProxy *app = [LSApplicationProxy applicationProxyForIdentifier:path]; {
if (app.bundleURL) { LSApplicationProxy* app = [LSApplicationProxy applicationProxyForIdentifier:path];
if(app.bundleURL)
{
path = [app bundleURL].path; path = [app bundleURL].path;
} }
} }
path = path.stringByResolvingSymlinksInPath.stringByStandardizingPath; path = [path stringByResolvingSymlinksInPath];
NSDictionary *appInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]]; NSDictionary* appInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingPathComponent:@"Info.plist"]];
NSString *appBundleID = [appInfoPlist objectForKey:@"CFBundleIdentifier"]; NSString* appBundleID = [appInfoPlist objectForKey:@"CFBundleIdentifier"];
if([immutableAppBundleIdentifiers() containsObject:appBundleID.lowercaseString]) return; if([immutableAppBundleIdentifiers() containsObject:appBundleID.lowercaseString]) return;
if (appBundleID && !unregister) { if(appBundleID && !unregister)
NSString *appExecutablePath = [path stringByAppendingPathComponent:appInfoPlist[@"CFBundleExecutable"]]; {
NSDictionary *entitlements = dumpEntitlementsFromBinaryAtPath(appExecutablePath); MCMContainer* appContainer = [NSClassFromString(@"MCMAppDataContainer") containerWithIdentifier:appBundleID createIfNecessary:YES existed:nil error:nil];
NSString* containerPath = [appContainer url].path;
NSString *appDataContainerID = appBundleID; NSMutableDictionary* dictToRegister = [NSMutableDictionary dictionary];
BOOL appContainerized = constructContainerizationForEntitlements(entitlements, &appDataContainerID);
MCMContainer *appDataContainer = [NSClassFromString(@"MCMAppDataContainer") containerWithIdentifier:appDataContainerID createIfNecessary:YES existed:nil error:nil];
NSString *containerPath = [appDataContainer url].path;
BOOL isRemovableSystemApp = [[NSFileManager defaultManager] fileExistsAtPath:[@"/System/Library/AppSignatures" stringByAppendingPathComponent:appBundleID]];
BOOL registerAsUser = [path hasPrefix:@"/var/containers"] && !isRemovableSystemApp && !forceSystem;
NSMutableDictionary *dictToRegister = [NSMutableDictionary dictionary];
// Add entitlements // Add entitlements
if (entitlements) { NSString* appExecutablePath = [path stringByAppendingPathComponent:appInfoPlist[@"CFBundleExecutable"]];
NSDictionary* entitlements = dumpEntitlementsFromBinaryAtPath(appExecutablePath);
if(entitlements)
{
dictToRegister[@"Entitlements"] = entitlements; dictToRegister[@"Entitlements"] = entitlements;
} }
// Misc // Misc
dictToRegister[@"ApplicationType"] = registerAsUser ? @"User" : @"System"; dictToRegister[@"ApplicationType"] = system ? @"System" : @"User";
dictToRegister[@"CFBundleIdentifier"] = appBundleID; dictToRegister[@"CFBundleIdentifier"] = appBundleID;
dictToRegister[@"CodeInfoIdentifier"] = appBundleID; dictToRegister[@"CodeInfoIdentifier"] = appBundleID;
dictToRegister[@"CompatibilityState"] = @0; dictToRegister[@"CompatibilityState"] = @0;
dictToRegister[@"IsContainerized"] = @(appContainerized); if(containerPath)
if (containerPath) { {
dictToRegister[@"Container"] = containerPath; dictToRegister[@"Container"] = containerPath;
dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath, appContainerized); dictToRegister[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(containerPath);
} }
dictToRegister[@"IsDeletable"] = @(registerAsUser || isRemovableSystemApp); dictToRegister[@"IsDeletable"] = @(![appBundleID isEqualToString:@"com.opa334.TrollStore"] && kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_15_0);
dictToRegister[@"Path"] = path; dictToRegister[@"Path"] = path;
dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements));
dictToRegister[@"SignerOrganization"] = @"Apple Inc."; dictToRegister[@"SignerOrganization"] = @"Apple Inc.";
dictToRegister[@"SignatureVersion"] = @132352; dictToRegister[@"SignatureVersion"] = @132352;
dictToRegister[@"SignerIdentity"] = @"Apple iPhone OS Application Signing"; dictToRegister[@"SignerIdentity"] = @"Apple iPhone OS Application Signing";
@ -144,21 +152,24 @@ void registerPath(NSString *path, BOOL unregister, BOOL forceSystem) {
dictToRegister[@"FamilyID"] = @0; dictToRegister[@"FamilyID"] = @0;
dictToRegister[@"IsOnDemandInstallCapable"] = @0; dictToRegister[@"IsOnDemandInstallCapable"] = @0;
NSString *teamIdentifier = constructTeamIdentifierForEntitlements(entitlements); NSString* teamIdentifier = constructTeamIdentifierForEntitlements(entitlements);
if (teamIdentifier) dictToRegister[@"TeamIdentifier"] = teamIdentifier; if(teamIdentifier) dictToRegister[@"TeamIdentifier"] = teamIdentifier;
// Add group containers // Add group containers
NSDictionary *appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO); NSDictionary* appGroupContainers = constructGroupsContainersForEntitlements(entitlements, NO);
NSDictionary *systemGroupContainers = constructGroupsContainersForEntitlements(entitlements, YES); 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];
if (groupContainers.count) { if(groupContainers.count)
if (appGroupContainers.count) { {
if(appGroupContainers.count)
{
dictToRegister[@"HasAppGroupContainers"] = @YES; dictToRegister[@"HasAppGroupContainers"] = @YES;
} }
if (systemGroupContainers.count) { if(systemGroupContainers.count)
{
dictToRegister[@"HasSystemGroupContainers"] = @YES; dictToRegister[@"HasSystemGroupContainers"] = @YES;
} }
dictToRegister[@"GroupContainers"] = groupContainers.copy; dictToRegister[@"GroupContainers"] = groupContainers.copy;
@ -166,29 +177,29 @@ void registerPath(NSString *path, BOOL unregister, BOOL forceSystem) {
// Add plugins // Add plugins
NSString *pluginsPath = [path stringByAppendingPathComponent:@"PlugIns"]; NSString* pluginsPath = [path stringByAppendingPathComponent:@"PlugIns"];
NSArray *plugins = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pluginsPath error:nil]; NSArray* plugins = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pluginsPath error:nil];
NSMutableDictionary *bundlePlugins = [NSMutableDictionary dictionary]; NSMutableDictionary* bundlePlugins = [NSMutableDictionary dictionary];
for (NSString *pluginName in plugins) { for (NSString* pluginName in plugins)
NSString *pluginPath = [pluginsPath stringByAppendingPathComponent:pluginName]; {
NSString* pluginPath = [pluginsPath stringByAppendingPathComponent:pluginName];
NSDictionary *pluginInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[pluginPath stringByAppendingPathComponent:@"Info.plist"]]; NSDictionary* pluginInfoPlist = [NSDictionary dictionaryWithContentsOfFile:[pluginPath stringByAppendingPathComponent:@"Info.plist"]];
NSString *pluginBundleID = [pluginInfoPlist objectForKey:@"CFBundleIdentifier"]; NSString* pluginBundleID = [pluginInfoPlist objectForKey:@"CFBundleIdentifier"];
if (!pluginBundleID) continue; if(!pluginBundleID) continue;
NSString *pluginExecutablePath = [pluginPath stringByAppendingPathComponent:pluginInfoPlist[@"CFBundleExecutable"]]; MCMContainer* pluginContainer = [NSClassFromString(@"MCMPluginKitPluginDataContainer") containerWithIdentifier:pluginBundleID createIfNecessary:YES existed:nil error:nil];
NSDictionary *pluginEntitlements = dumpEntitlementsFromBinaryAtPath(pluginExecutablePath); NSString* pluginContainerPath = [pluginContainer url].path;
NSString *pluginDataContainerID = pluginBundleID;
BOOL pluginContainerized = constructContainerizationForEntitlements(pluginEntitlements, &pluginDataContainerID);
MCMContainer *pluginContainer = [NSClassFromString(@"MCMPluginKitPluginDataContainer") containerWithIdentifier:pluginDataContainerID createIfNecessary:YES existed:nil error:nil]; NSMutableDictionary* pluginDict = [NSMutableDictionary dictionary];
NSString *pluginContainerPath = [pluginContainer url].path;
NSMutableDictionary *pluginDict = [NSMutableDictionary dictionary];
// Add entitlements // Add entitlements
if (pluginEntitlements) {
NSString* pluginExecutablePath = [pluginPath stringByAppendingPathComponent:pluginInfoPlist[@"CFBundleExecutable"]];
NSDictionary* pluginEntitlements = dumpEntitlementsFromBinaryAtPath(pluginExecutablePath);
if(pluginEntitlements)
{
pluginDict[@"Entitlements"] = pluginEntitlements; pluginDict[@"Entitlements"] = pluginEntitlements;
} }
@ -198,33 +209,36 @@ void registerPath(NSString *path, BOOL unregister, BOOL forceSystem) {
pluginDict[@"CFBundleIdentifier"] = pluginBundleID; pluginDict[@"CFBundleIdentifier"] = pluginBundleID;
pluginDict[@"CodeInfoIdentifier"] = pluginBundleID; pluginDict[@"CodeInfoIdentifier"] = pluginBundleID;
pluginDict[@"CompatibilityState"] = @0; pluginDict[@"CompatibilityState"] = @0;
if(pluginContainerPath)
pluginDict[@"IsContainerized"] = @(pluginContainerized); {
if (pluginContainerPath) {
pluginDict[@"Container"] = pluginContainerPath; pluginDict[@"Container"] = pluginContainerPath;
pluginDict[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(pluginContainerPath, pluginContainerized); pluginDict[@"EnvironmentVariables"] = constructEnvironmentVariablesForContainerPath(pluginContainerPath);
} }
pluginDict[@"Path"] = pluginPath; pluginDict[@"Path"] = pluginPath;
pluginDict[@"PluginOwnerBundleID"] = appBundleID; pluginDict[@"PluginOwnerBundleID"] = appBundleID;
pluginDict[@"IsContainerized"] = @(constructContainerizationForEntitlements(pluginEntitlements));
pluginDict[@"SignerOrganization"] = @"Apple Inc."; pluginDict[@"SignerOrganization"] = @"Apple Inc.";
pluginDict[@"SignatureVersion"] = @132352; pluginDict[@"SignatureVersion"] = @132352;
pluginDict[@"SignerIdentity"] = @"Apple iPhone OS Application Signing"; pluginDict[@"SignerIdentity"] = @"Apple iPhone OS Application Signing";
NSString *pluginTeamIdentifier = constructTeamIdentifierForEntitlements(pluginEntitlements); NSString* pluginTeamIdentifier = constructTeamIdentifierForEntitlements(pluginEntitlements);
if (pluginTeamIdentifier) pluginDict[@"TeamIdentifier"] = pluginTeamIdentifier; if(pluginTeamIdentifier) pluginDict[@"TeamIdentifier"] = pluginTeamIdentifier;
// Add plugin group containers // Add plugin group containers
NSDictionary *pluginAppGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, NO); NSDictionary* pluginAppGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, NO);
NSDictionary *pluginSystemGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, YES); NSDictionary* pluginSystemGroupContainers = constructGroupsContainersForEntitlements(pluginEntitlements, YES);
NSMutableDictionary *pluginGroupContainers = [NSMutableDictionary new]; NSMutableDictionary* pluginGroupContainers = [NSMutableDictionary new];
[pluginGroupContainers addEntriesFromDictionary:pluginAppGroupContainers]; [pluginGroupContainers addEntriesFromDictionary:pluginAppGroupContainers];
[pluginGroupContainers addEntriesFromDictionary:pluginSystemGroupContainers]; [pluginGroupContainers addEntriesFromDictionary:pluginSystemGroupContainers];
if (pluginGroupContainers.count) { if(pluginGroupContainers.count)
if (pluginAppGroupContainers.count) { {
if(pluginAppGroupContainers.count)
{
pluginDict[@"HasAppGroupContainers"] = @YES; pluginDict[@"HasAppGroupContainers"] = @YES;
} }
if (pluginSystemGroupContainers.count) { if(pluginSystemGroupContainers.count)
{
pluginDict[@"HasSystemGroupContainers"] = @YES; pluginDict[@"HasSystemGroupContainers"] = @YES;
} }
pluginDict[@"GroupContainers"] = pluginGroupContainers.copy; pluginDict[@"GroupContainers"] = pluginGroupContainers.copy;
@ -234,13 +248,17 @@ void registerPath(NSString *path, BOOL unregister, BOOL forceSystem) {
} }
[dictToRegister setObject:bundlePlugins forKey:@"_LSBundlePlugins"]; [dictToRegister setObject:bundlePlugins forKey:@"_LSBundlePlugins"];
if (![workspace registerApplicationDictionary:dictToRegister]) { if(![workspace registerApplicationDictionary:dictToRegister])
{
NSLog(@"Error: Unable to register %@", path); NSLog(@"Error: Unable to register %@", path);
} }
} else { }
NSURL *url = [NSURL fileURLWithPath:path]; else
if (![workspace unregisterApplication:url]) { {
NSLog(@"Error: Unable to register %@", path); NSURL* url = [NSURL fileURLWithPath:path];
if(![workspace unregisterApplication:url])
{
NSLog(@"Error: Unable to unregister %@", path);
} }
} }
} }

View File

@ -52,7 +52,7 @@
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.0.6</string> <string>2.0.5</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstorehelper Package: com.opa334.trollstorehelper
Name: TrollStore Helper Name: TrollStore Helper
Version: 2.0.6 Version: 2.0.5
Architecture: iphoneos-arm Architecture: iphoneos-arm
Description: Helper utility to install and manage TrollStore! Description: Helper utility to install and manage TrollStore!
Maintainer: opa334 Maintainer: opa334

View File

@ -50,7 +50,7 @@
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.0.6</string> <string>2.0.5</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>

View File

@ -849,37 +849,16 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
__block NSMutableArray* accessibleContainers = [NSMutableArray new]; //array by design, should be ordered __block NSMutableArray* accessibleContainers = [NSMutableArray new]; //array by design, should be ordered
if(!unrestrictedContainerAccess) if(!unrestrictedContainerAccess)
{ {
__block NSString *dataContainer = nil;
// If com.apple.private.security.container-required Entitlement is a string, prefer it to CFBundleIdentifier
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) {
if([key isEqualToString:@"com.apple.private.security.container-required"])
{
NSString* valueString = (NSString*)value;
if(valueString && [valueString isKindOfClass:NSString.class])
{
dataContainer = valueString;
}
}
}];
// Else take CFBundleIdentifier
if (!dataContainer) {
[self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) { [self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) {
if([key isEqualToString:@"CFBundleIdentifier"]) if([key isEqualToString:@"CFBundleIdentifier"])
{ {
NSString* valueStr = (NSString*)value; NSString* valueStr = (NSString*)value;
if([valueStr isKindOfClass:NSString.class]) if([valueStr isKindOfClass:NSString.class])
{ {
dataContainer = valueStr; [accessibleContainers addObject:valueStr];
} }
} }
}]; }];
}
if (dataContainer) {
[accessibleContainers addObject:dataContainer];
}
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) [self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop)
{ {

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstore Package: com.opa334.trollstore
Name: TrollStore Name: TrollStore
Version: 2.0.6 Version: 2.0.5
Architecture: iphoneos-arm Architecture: iphoneos-arm
Description: An awesome application! Description: An awesome application!
Maintainer: opa334 Maintainer: opa334