mirror of https://github.com/opa334/TrollStore.git
Remove all mentions of ldid
This commit is contained in:
parent
1ebcb73375
commit
68abdf124b
|
@ -236,105 +236,6 @@ void setTSURLSchemeState(BOOL newState, NSString* customAppPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void installLdid(NSString* ldidToCopyPath, NSString* ldidVersion)
|
|
||||||
{
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return;
|
|
||||||
|
|
||||||
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
|
||||||
NSString* ldidVersionPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
|
|
||||||
if([[NSFileManager defaultManager] fileExistsAtPath:ldidPath])
|
|
||||||
{
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:ldidPath error:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] copyItemAtPath:ldidToCopyPath toPath:ldidPath error:nil];
|
|
||||||
|
|
||||||
NSData* ldidVersionData = [ldidVersion dataUsingEncoding:NSUTF8StringEncoding];
|
|
||||||
[ldidVersionData writeToFile:ldidVersionPath atomically:YES];
|
|
||||||
|
|
||||||
chmod(ldidPath.fileSystemRepresentation, 0755);
|
|
||||||
chmod(ldidVersionPath.fileSystemRepresentation, 0644);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL isLdidInstalled(void)
|
|
||||||
{
|
|
||||||
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
|
||||||
return [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
int runLdid(NSArray* args, NSString** output, NSString** errorOutput)
|
|
||||||
{
|
|
||||||
NSString* ldidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
|
||||||
NSMutableArray* argsM = args.mutableCopy ?: [NSMutableArray new];
|
|
||||||
[argsM insertObject:ldidPath.lastPathComponent atIndex:0];
|
|
||||||
|
|
||||||
NSUInteger argCount = [argsM count];
|
|
||||||
char **argsC = (char **)malloc((argCount + 1) * sizeof(char*));
|
|
||||||
|
|
||||||
for (NSUInteger i = 0; i < argCount; i++)
|
|
||||||
{
|
|
||||||
argsC[i] = strdup([[argsM objectAtIndex:i] UTF8String]);
|
|
||||||
}
|
|
||||||
argsC[argCount] = NULL;
|
|
||||||
|
|
||||||
posix_spawn_file_actions_t action;
|
|
||||||
posix_spawn_file_actions_init(&action);
|
|
||||||
|
|
||||||
int outErr[2];
|
|
||||||
pipe(outErr);
|
|
||||||
posix_spawn_file_actions_adddup2(&action, outErr[1], STDERR_FILENO);
|
|
||||||
posix_spawn_file_actions_addclose(&action, outErr[0]);
|
|
||||||
|
|
||||||
int out[2];
|
|
||||||
pipe(out);
|
|
||||||
posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO);
|
|
||||||
posix_spawn_file_actions_addclose(&action, out[0]);
|
|
||||||
|
|
||||||
pid_t task_pid;
|
|
||||||
int status = -200;
|
|
||||||
int spawnError = posix_spawn(&task_pid, [ldidPath fileSystemRepresentation], &action, NULL, (char* const*)argsC, NULL);
|
|
||||||
for (NSUInteger i = 0; i < argCount; i++)
|
|
||||||
{
|
|
||||||
free(argsC[i]);
|
|
||||||
}
|
|
||||||
free(argsC);
|
|
||||||
|
|
||||||
if(spawnError != 0)
|
|
||||||
{
|
|
||||||
NSLog(@"posix_spawn error %d\n", spawnError);
|
|
||||||
return spawnError;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (waitpid(task_pid, &status, 0) != -1) {
|
|
||||||
//printf("Child status %dn", WEXITSTATUS(status));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
perror("waitpid");
|
|
||||||
return -222;
|
|
||||||
}
|
|
||||||
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
|
||||||
|
|
||||||
close(outErr[1]);
|
|
||||||
close(out[1]);
|
|
||||||
|
|
||||||
NSString* ldidOutput = getNSStringFromFile(out[0]);
|
|
||||||
if(output)
|
|
||||||
{
|
|
||||||
*output = ldidOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* ldidErrorOutput = getNSStringFromFile(outErr[0]);
|
|
||||||
if(errorOutput)
|
|
||||||
{
|
|
||||||
*errorOutput = ldidErrorOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL certificateHasDataForExtensionOID(SecCertificateRef certificate, CFStringRef oidString)
|
BOOL certificateHasDataForExtensionOID(SecCertificateRef certificate, CFStringRef oidString)
|
||||||
{
|
{
|
||||||
if(certificate == NULL || oidString == NULL)
|
if(certificate == NULL || oidString == NULL)
|
||||||
|
@ -491,48 +392,8 @@ int signApp(NSString* appPath)
|
||||||
{
|
{
|
||||||
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", executablePath);
|
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", executablePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isLdidInstalled()) return 173;
|
|
||||||
|
|
||||||
NSString* certPath = [trollStoreAppPath() stringByAppendingPathComponent:@"cert.p12"];
|
|
||||||
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
|
|
||||||
NSString* errorOutput;
|
|
||||||
int ldidRet;
|
|
||||||
|
|
||||||
NSDictionary* entitlements = dumpEntitlements(codeRef);
|
|
||||||
CFRelease(codeRef);
|
|
||||||
|
|
||||||
if(!entitlements)
|
|
||||||
{
|
|
||||||
NSLog(@"app main binary has no entitlements, signing app with fallback entitlements...");
|
|
||||||
// app has no entitlements, sign with fallback entitlements
|
|
||||||
NSString* entitlementPath = [trollStoreAppPath() stringByAppendingPathComponent:@"fallback.entitlements"];
|
|
||||||
NSString* entitlementArg = [@"-S" stringByAppendingString:entitlementPath];
|
|
||||||
ldidRet = runLdid(@[entitlementArg, certArg, appPath], nil, &errorOutput);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// app has entitlements, keep them
|
|
||||||
ldidRet = runLdid(@[@"-s", certArg, appPath], nil, &errorOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSLog(@"ldid exited with status %d", ldidRet);
|
|
||||||
|
|
||||||
NSLog(@"- ldid error output start -");
|
|
||||||
|
|
||||||
printMultilineNSString(errorOutput);
|
|
||||||
|
|
||||||
NSLog(@"- ldid error output end -");
|
|
||||||
|
|
||||||
if(ldidRet == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return 175;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyPatchesToInfoDictionary(NSString* appPath)
|
void applyPatchesToInfoDictionary(NSString* appPath)
|
||||||
{
|
{
|
||||||
|
@ -587,7 +448,6 @@ void applyPatchesToInfoDictionary(NSString* appPath)
|
||||||
// 170: failed to create container for app bundle
|
// 170: failed to create container for app bundle
|
||||||
// 171: a non trollstore app with the same identifier is already installled
|
// 171: a non trollstore app with the same identifier is already installled
|
||||||
// 172: no info.plist found in app
|
// 172: no info.plist found in app
|
||||||
// 173: app is not signed and cannot be signed because ldid not installed or didn't work
|
|
||||||
// 174:
|
// 174:
|
||||||
int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, BOOL useInstalldMethod)
|
int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate, BOOL useInstalldMethod)
|
||||||
{
|
{
|
||||||
|
@ -935,39 +795,6 @@ int installTrollStore(NSString* pathToTar)
|
||||||
NSString* tmpTrollStorePath = [tmpPayloadPath stringByAppendingPathComponent:@"TrollStore.app"];
|
NSString* tmpTrollStorePath = [tmpPayloadPath stringByAppendingPathComponent:@"TrollStore.app"];
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStorePath]) return 1;
|
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStorePath]) return 1;
|
||||||
|
|
||||||
// Transfer existing ldid installation if it exists
|
|
||||||
// But only if the to-be-installed version of TrollStore is 1.5.0 or above
|
|
||||||
// This is to make it possible to downgrade to older versions still
|
|
||||||
|
|
||||||
NSString* toInstallInfoPlistPath = [tmpTrollStorePath stringByAppendingPathComponent:@"Info.plist"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:toInstallInfoPlistPath]) return 1;
|
|
||||||
|
|
||||||
NSDictionary* toInstallInfoDict = [NSDictionary dictionaryWithContentsOfFile:toInstallInfoPlistPath];
|
|
||||||
NSString* toInstallVersion = toInstallInfoDict[@"CFBundleVersion"];
|
|
||||||
|
|
||||||
NSComparisonResult result = [@"1.5.0" compare:toInstallVersion options:NSNumericSearch];
|
|
||||||
if(result != NSOrderedDescending)
|
|
||||||
{
|
|
||||||
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
|
|
||||||
NSString* existingLdidVersionPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidPath])
|
|
||||||
{
|
|
||||||
NSString* tmpLdidPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidPath])
|
|
||||||
{
|
|
||||||
[[NSFileManager defaultManager] copyItemAtPath:existingLdidPath toPath:tmpLdidPath error:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidVersionPath])
|
|
||||||
{
|
|
||||||
NSString* tmpLdidVersionPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidVersionPath])
|
|
||||||
{
|
|
||||||
[[NSFileManager defaultManager] copyItemAtPath:existingLdidVersionPath toPath:tmpLdidVersionPath error:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge existing URL scheme settings value
|
// Merge existing URL scheme settings value
|
||||||
if(!getTSURLSchemeState(nil))
|
if(!getTSURLSchemeState(nil))
|
||||||
{
|
{
|
||||||
|
@ -1247,13 +1074,6 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
|
||||||
}
|
}
|
||||||
uninstallTrollStore(YES);
|
uninstallTrollStore(YES);
|
||||||
}
|
}
|
||||||
else if([cmd isEqualToString:@"install-ldid"])
|
|
||||||
{
|
|
||||||
if(args.count < 3) return -3;
|
|
||||||
NSString* ldidPath = args[1];
|
|
||||||
NSString* ldidVersion = args[2];
|
|
||||||
installLdid(ldidPath, ldidVersion);
|
|
||||||
}
|
|
||||||
else if([cmd isEqualToString:@"refresh"])
|
else if([cmd isEqualToString:@"refresh"])
|
||||||
{
|
{
|
||||||
refreshAppRegistrations(YES);
|
refreshAppRegistrations(YES);
|
||||||
|
|
|
@ -1,351 +0,0 @@
|
||||||
#import <stdio.h>
|
|
||||||
#import "unarchive.h"
|
|
||||||
@import Foundation;
|
|
||||||
#import "uicache.h"
|
|
||||||
#import <sys/stat.h>
|
|
||||||
#import <dlfcn.h>
|
|
||||||
#import <spawn.h>
|
|
||||||
#import "path.h"
|
|
||||||
#import "CoreServices.h"
|
|
||||||
#import <objc/runtime.h>
|
|
||||||
|
|
||||||
#define kCFPreferencesNoContainer CFSTR("kCFPreferencesNoContainer")
|
|
||||||
|
|
||||||
typedef CFPropertyListRef (*_CFPreferencesCopyValueWithContainerType)(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
|
||||||
typedef void (*_CFPreferencesSetValueWithContainerType)(CFStringRef key, CFPropertyListRef value, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
|
||||||
typedef Boolean (*_CFPreferencesSynchronizeWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
|
||||||
typedef CFArrayRef (*_CFPreferencesCopyKeyListWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
|
||||||
typedef CFDictionaryRef (*_CFPreferencesCopyMultipleWithContainerType)(CFArrayRef keysToFetch, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
|
|
||||||
|
|
||||||
extern char*** _NSGetArgv();
|
|
||||||
NSString* safe_getExecutablePath()
|
|
||||||
{
|
|
||||||
char* executablePathC = **_NSGetArgv();
|
|
||||||
return [NSString stringWithUTF8String:executablePathC];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSDictionary* infoDictionaryForAppPath(NSString* appPath)
|
|
||||||
{
|
|
||||||
NSString* infoPlistPath = [appPath stringByAppendingPathComponent:@"Info.plist"];
|
|
||||||
return [NSDictionary dictionaryWithContentsOfFile:infoPlistPath];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* appIdForAppPath(NSString* appPath)
|
|
||||||
{
|
|
||||||
return infoDictionaryForAppPath(appPath)[@"CFBundleIdentifier"];
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* appPathForAppId(NSString* appId, NSError** error)
|
|
||||||
{
|
|
||||||
NSString* appPath = [TROLLSTORE_APPLICATIONS_PATH stringByAppendingPathComponent:appId];
|
|
||||||
|
|
||||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appPath error:error];
|
|
||||||
if(!items) return nil;
|
|
||||||
|
|
||||||
for(NSString* item in items)
|
|
||||||
{
|
|
||||||
if([item.pathExtension isEqualToString:@"app"])
|
|
||||||
{
|
|
||||||
return [appPath stringByAppendingPathComponent:item];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_file_content(int fd)
|
|
||||||
{
|
|
||||||
ssize_t num_read;
|
|
||||||
char line_buf[256];
|
|
||||||
int cur_pos = 0;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
num_read = read(fd, &c, sizeof(c));
|
|
||||||
if(num_read <= 0)
|
|
||||||
|
|
||||||
if(c == '\n' || cur_pos >= 255 || num_read <= 0)
|
|
||||||
{
|
|
||||||
line_buf[cur_pos] = '\n';
|
|
||||||
NSLog(@"%s", (char*)line_buf);
|
|
||||||
if(c == '\n') cur_pos++;
|
|
||||||
|
|
||||||
if(num_read > 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
line_buf[cur_pos++] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL signApp(NSString* appPath, NSError** error)
|
|
||||||
{
|
|
||||||
NSString* ldidPath = [[safe_getExecutablePath() stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"ldid"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath])
|
|
||||||
{
|
|
||||||
NSLog(@"WARNING: ldid not found, not signing application");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSString* certPath = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app/cert.p12"];
|
|
||||||
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
|
|
||||||
|
|
||||||
int out[2];
|
|
||||||
posix_spawn_file_actions_t action;
|
|
||||||
posix_spawn_file_actions_init(&action);
|
|
||||||
pipe(out);
|
|
||||||
posix_spawn_file_actions_adddup2(&action, out[1], STDERR_FILENO);
|
|
||||||
posix_spawn_file_actions_addclose(&action, out[0]);
|
|
||||||
|
|
||||||
char* args[] = { "ldid", "-S", "-M", (char*)certArg.UTF8String, (char*)appPath.UTF8String, NULL };
|
|
||||||
|
|
||||||
NSLog(@"%@ ldid -S -M %@ %@", ldidPath, certArg, appPath);
|
|
||||||
|
|
||||||
pid_t task_pid;
|
|
||||||
int status = -200;
|
|
||||||
int spawnError = posix_spawn(&task_pid, [ldidPath UTF8String], &action, NULL, args, NULL);
|
|
||||||
|
|
||||||
if(spawnError != 0)
|
|
||||||
{
|
|
||||||
NSLog(@"posix_spawn error %d\n", spawnError);
|
|
||||||
return spawnError;
|
|
||||||
}
|
|
||||||
|
|
||||||
waitpid(task_pid, &status, WEXITED);
|
|
||||||
|
|
||||||
NSLog(@"ldid exited with status %d", status);
|
|
||||||
|
|
||||||
waitpid(task_pid, &status, 0);
|
|
||||||
|
|
||||||
NSLog(@"ldid exited with status %d", status);
|
|
||||||
|
|
||||||
NSLog(@"ldid output:");
|
|
||||||
|
|
||||||
close(out[1]);
|
|
||||||
dump_file_content(out[0]);
|
|
||||||
|
|
||||||
NSLog(@"end ldid output:");
|
|
||||||
|
|
||||||
return status == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL installApp(NSString* appPath, NSString* appId, BOOL sign, NSError** error)
|
|
||||||
{
|
|
||||||
if(sign)
|
|
||||||
{
|
|
||||||
// if it fails to sign, we don't care
|
|
||||||
signApp(appPath, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL existed;
|
|
||||||
NSError* mcmError;
|
|
||||||
MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:&existed error:&mcmError];
|
|
||||||
NSLog(@"installApp appContainer: %@, mcmError: %@", appContainer, mcmError);
|
|
||||||
if(!appContainer || mcmError)
|
|
||||||
{
|
|
||||||
if(error) *error = mcmError;
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: if TrollStore, preserve by moving it into appPath if needed ldid if needed
|
|
||||||
|
|
||||||
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
|
|
||||||
if(existed)
|
|
||||||
{
|
|
||||||
// trying to update an app not installed by TrollStore... bailing out
|
|
||||||
if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
|
|
||||||
{
|
|
||||||
NSLog(@"installApp already installed and not a TrollStore app... bailing out");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// update existing app... clean old app directory
|
|
||||||
NSLog(@"installApp found existing TrollStore app, cleaning directory");
|
|
||||||
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:appContainer.url includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
|
||||||
NSURL* fileURL;
|
|
||||||
while(fileURL = [enumerator nextObject])
|
|
||||||
{
|
|
||||||
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
|
|
||||||
|
|
||||||
NSString* newAppPath = [appContainer.url.path stringByAppendingPathComponent:appPath.lastPathComponent];
|
|
||||||
|
|
||||||
NSLog(@"installApp new app path: %@", newAppPath);
|
|
||||||
|
|
||||||
BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appPath toPath:newAppPath error:error];
|
|
||||||
|
|
||||||
NSLog(@"installApp copied app? %d, adding to uicache now...", suc);
|
|
||||||
|
|
||||||
registerPath(newAppPath, NO);
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL uninstallApp(NSString* appId, NSError** error)
|
|
||||||
{
|
|
||||||
NSString* appPath = appPathForAppId(appId, error);
|
|
||||||
if(!appPath) return NO;
|
|
||||||
|
|
||||||
registerPath(appPath, YES);
|
|
||||||
|
|
||||||
return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL installIpa(NSString* ipaPath, NSError** error)
|
|
||||||
{
|
|
||||||
BOOL suc = NO;
|
|
||||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
|
||||||
|
|
||||||
suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:error];
|
|
||||||
if(!suc) return NO;
|
|
||||||
|
|
||||||
extract(ipaPath, tmpPath);
|
|
||||||
|
|
||||||
NSString* tmpPayloadPath = [tmpPath stringByAppendingPathComponent:@"Payload"];
|
|
||||||
|
|
||||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpPayloadPath error:error];
|
|
||||||
if(!items) return NO;
|
|
||||||
|
|
||||||
NSString* tmpAppPath;
|
|
||||||
for(NSString* item in items)
|
|
||||||
{
|
|
||||||
if([item.pathExtension isEqualToString:@"app"])
|
|
||||||
{
|
|
||||||
tmpAppPath = [tmpPayloadPath stringByAppendingPathComponent:item];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!tmpAppPath) return NO;
|
|
||||||
|
|
||||||
NSString* appId = appIdForAppPath(tmpAppPath);
|
|
||||||
|
|
||||||
suc = installApp(tmpAppPath, appId, YES, error);
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
|
|
||||||
|
|
||||||
return suc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninstallAllApps(void)
|
|
||||||
{
|
|
||||||
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TROLLSTORE_APPLICATIONS_PATH error:nil];
|
|
||||||
for(NSString* appId in items)
|
|
||||||
{
|
|
||||||
NSString* appPath = appPathForAppId(appId, nil);
|
|
||||||
registerPath(appPath, YES);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL uninstallTrollStore(void)
|
|
||||||
{
|
|
||||||
NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO;
|
|
||||||
|
|
||||||
registerPath(trollStore, YES);
|
|
||||||
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL installTrollStore(NSString* pathToTar)
|
|
||||||
{
|
|
||||||
_CFPreferencesSetValueWithContainerType _CFPreferencesSetValueWithContainer = (_CFPreferencesSetValueWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSetValueWithContainer");
|
|
||||||
_CFPreferencesSynchronizeWithContainerType _CFPreferencesSynchronizeWithContainer = (_CFPreferencesSynchronizeWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSynchronizeWithContainer");
|
|
||||||
_CFPreferencesSetValueWithContainer(CFSTR("SBShowNonDefaultSystemApps"), kCFBooleanTrue, CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
|
|
||||||
_CFPreferencesSynchronizeWithContainer(CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
|
|
||||||
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:pathToTar]) return NO;
|
|
||||||
if(![pathToTar.pathExtension isEqualToString:@"tar"]) return NO;
|
|
||||||
|
|
||||||
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
|
|
||||||
BOOL suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:nil];
|
|
||||||
if(!suc) return NO;
|
|
||||||
|
|
||||||
extract(pathToTar, tmpPath);
|
|
||||||
|
|
||||||
NSLog(@"installTrollStore extracted %@ to %@", pathToTar, tmpPath);
|
|
||||||
|
|
||||||
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return NO;
|
|
||||||
|
|
||||||
NSLog(@"installTrollStore temp TrollStore path: %@", tmpTrollStore);
|
|
||||||
|
|
||||||
NSString* tmpTrollStoreMain = [tmpTrollStore stringByAppendingPathComponent:@"TrollStore"];
|
|
||||||
NSString* tmpTrollStoreRootHelper = [tmpTrollStore stringByAppendingPathComponent:@"trollstorehelper"];
|
|
||||||
NSString* tmpTrollStoreLdid = [tmpTrollStore stringByAppendingPathComponent:@"ldid"];
|
|
||||||
|
|
||||||
// make executable
|
|
||||||
chmod(tmpTrollStoreMain.UTF8String, 0755);
|
|
||||||
chmod(tmpTrollStoreRootHelper.UTF8String, 0755);
|
|
||||||
chmod(tmpTrollStoreLdid.UTF8String, 0755);
|
|
||||||
|
|
||||||
// set owners
|
|
||||||
chown(tmpTrollStoreMain.UTF8String, 33, 33);
|
|
||||||
chown(tmpTrollStoreRootHelper.UTF8String, 0, 0); // set root helper binary owner to root
|
|
||||||
chown(tmpTrollStoreLdid.UTF8String, 0, 0);
|
|
||||||
|
|
||||||
NSLog(@"installTrollStore extracted and prepared TrollStore app, now installing...");
|
|
||||||
|
|
||||||
installApp(tmpTrollStore, @"com.apple.TrollStore", NO, nil);
|
|
||||||
|
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[], char *envp[]) {
|
|
||||||
@autoreleasepool {
|
|
||||||
if(argc <= 1) return -1;
|
|
||||||
|
|
||||||
NSLog(@"trollstore helper go, uid: %d, gid: %d", getuid(), getgid());
|
|
||||||
NSLog(@"ok %d", argc);
|
|
||||||
|
|
||||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
|
||||||
[mcmBundle load];
|
|
||||||
|
|
||||||
BOOL suc = NO;
|
|
||||||
NSError* error;
|
|
||||||
|
|
||||||
NSString* cmd = [NSString stringWithUTF8String:argv[1]];
|
|
||||||
if([cmd isEqualToString:@"install"])
|
|
||||||
{
|
|
||||||
if(argc <= 2) return -2;
|
|
||||||
NSString* ipaPath = [NSString stringWithUTF8String:argv[2]];
|
|
||||||
suc = installIpa(ipaPath, &error);
|
|
||||||
} else if([cmd isEqualToString:@"uninstall"])
|
|
||||||
{
|
|
||||||
if(argc <= 2) return -2;
|
|
||||||
NSString* appId = [NSString stringWithUTF8String:argv[2]];
|
|
||||||
suc = uninstallApp(appId, &error);
|
|
||||||
} else if([cmd isEqualToString:@"install-trollstore"])
|
|
||||||
{
|
|
||||||
if(argc <= 2) return -2;
|
|
||||||
NSString* tsTar = [NSString stringWithUTF8String:argv[2]];
|
|
||||||
suc = installTrollStore(tsTar);
|
|
||||||
NSLog(@"installed troll store? %d", suc);
|
|
||||||
} else if([cmd isEqualToString:@"uninstall-trollstore"])
|
|
||||||
{
|
|
||||||
uninstallTrollStore();
|
|
||||||
uninstallAllApps();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!suc)
|
|
||||||
{
|
|
||||||
NSLog(@"error: %@", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !suc;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,7 +12,6 @@ extern int spawnRoot(NSString* path, NSArray* args, NSString** stdOut, NSString*
|
||||||
extern void killall(NSString* processName, BOOL softly);
|
extern void killall(NSString* processName, BOOL softly);
|
||||||
extern void respring(void);
|
extern void respring(void);
|
||||||
extern void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion));
|
extern void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVersion));
|
||||||
extern void fetchLatestLdidVersion(void (^completionHandler)(NSString* latestVersion));
|
|
||||||
|
|
||||||
extern NSArray* trollStoreInstalledAppBundlePaths();
|
extern NSArray* trollStoreInstalledAppBundlePaths();
|
||||||
extern NSArray* trollStoreInstalledAppContainerPaths();
|
extern NSArray* trollStoreInstalledAppContainerPaths();
|
||||||
|
|
|
@ -308,11 +308,6 @@ void fetchLatestTrollStoreVersion(void (^completionHandler)(NSString* latestVers
|
||||||
github_fetchLatestVersion(@"opa334/TrollStore", completionHandler);
|
github_fetchLatestVersion(@"opa334/TrollStore", completionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchLatestLdidVersion(void (^completionHandler)(NSString* latestVersion))
|
|
||||||
{
|
|
||||||
github_fetchLatestVersion(@"opa334/ldid", completionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSArray* trollStoreInstalledAppContainerPaths()
|
NSArray* trollStoreInstalledAppContainerPaths()
|
||||||
{
|
{
|
||||||
NSMutableArray* appContainerPaths = [NSMutableArray new];
|
NSMutableArray* appContainerPaths = [NSMutableArray new];
|
||||||
|
|
|
@ -191,7 +191,6 @@
|
||||||
<key>TSRootBinaries</key>
|
<key>TSRootBinaries</key>
|
||||||
<array>
|
<array>
|
||||||
<string>trollstorehelper</string>
|
<string>trollstorehelper</string>
|
||||||
<string>ldid</string>
|
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -47,14 +47,11 @@ extern NSUserDefaults* trollStoreUserDefaults();
|
||||||
case 172:
|
case 172:
|
||||||
errorDescription = @"The app does not contain an Info.plist file.";
|
errorDescription = @"The app does not contain an Info.plist file.";
|
||||||
break;
|
break;
|
||||||
case 173:
|
|
||||||
errorDescription = @"The app is not signed with a fake CoreTrust certificate and ldid is not installed. Install ldid in the settings tab and try again.";
|
|
||||||
break;
|
|
||||||
case 174:
|
case 174:
|
||||||
errorDescription = @"The app's main executable does not exist.";
|
errorDescription = @"The app's main executable does not exist.";
|
||||||
break;
|
break;
|
||||||
case 175:
|
case 175:
|
||||||
errorDescription = @"Failed to sign the app. ldid returned a non zero status code.";
|
errorDescription = @"Failed to sign the app.";
|
||||||
break;
|
break;
|
||||||
case 176:
|
case 176:
|
||||||
errorDescription = @"The app's Info.plist is missing required values.";
|
errorDescription = @"The app's Info.plist is missing required values.";
|
||||||
|
|
|
@ -9,6 +9,4 @@
|
||||||
|
|
||||||
+ (void)handleAppInstallFromRemoteURL:(NSURL*)remoteURL completion:(void (^)(BOOL, NSError*))completion;
|
+ (void)handleAppInstallFromRemoteURL:(NSURL*)remoteURL completion:(void (^)(BOOL, NSError*))completion;
|
||||||
|
|
||||||
+ (void)installLdid;
|
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -187,48 +187,4 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)installLdid
|
|
||||||
{
|
|
||||||
fetchLatestLdidVersion(^(NSString* latestVersion)
|
|
||||||
{
|
|
||||||
if(!latestVersion) return;
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^
|
|
||||||
{
|
|
||||||
NSURL* ldidURL = [NSURL URLWithString:@"https://github.com/opa334/ldid/releases/latest/download/ldid"];
|
|
||||||
NSURLRequest* ldidRequest = [NSURLRequest requestWithURL:ldidURL];
|
|
||||||
|
|
||||||
[TSPresentationDelegate startActivity:@"Installing ldid"];
|
|
||||||
|
|
||||||
NSURLSessionDownloadTask* downloadTask = [NSURLSession.sharedSession downloadTaskWithRequest:ldidRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error)
|
|
||||||
{
|
|
||||||
if(error)
|
|
||||||
{
|
|
||||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error downloading ldid: %@", error] preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
|
||||||
[errorAlert addAction:closeAction];
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^
|
|
||||||
{
|
|
||||||
[TSPresentationDelegate stopActivityWithCompletion:^
|
|
||||||
{
|
|
||||||
[TSPresentationDelegate presentViewController:errorAlert animated:YES completion:nil];
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if(location)
|
|
||||||
{
|
|
||||||
spawnRoot(rootHelperPath(), @[@"install-ldid", location.path, latestVersion], nil, nil);
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^
|
|
||||||
{
|
|
||||||
[TSPresentationDelegate stopActivityWithCompletion:nil];
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"TrollStoreReloadSettingsNotification" object:nil userInfo:nil];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
[downloadTask resume];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -72,21 +72,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to auto install ldid if either it doesn't exist
|
|
||||||
// or if it's the one from an old TrollStore version that's no longer supported
|
|
||||||
- (void)handleLdidCheck
|
|
||||||
{
|
|
||||||
NSString* tsAppPath = [NSBundle mainBundle].bundlePath;
|
|
||||||
|
|
||||||
NSString* ldidPath = [tsAppPath stringByAppendingPathComponent:@"ldid"];
|
|
||||||
NSString* ldidVersionPath = [tsAppPath stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
|
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath] || ![[NSFileManager defaultManager] fileExistsAtPath:ldidVersionPath])
|
|
||||||
{
|
|
||||||
[TSInstallationController installLdid];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
|
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
|
||||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||||
|
@ -102,10 +87,6 @@
|
||||||
{
|
{
|
||||||
[self handleURLContexts:connectionOptions.URLContexts scene:(UIWindowScene*)scene];
|
[self handleURLContexts:connectionOptions.URLContexts scene:(UIWindowScene*)scene];
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
[self handleLdidCheck];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,5 @@
|
||||||
{
|
{
|
||||||
PSSpecifier* _installPersistenceHelperSpecifier;
|
PSSpecifier* _installPersistenceHelperSpecifier;
|
||||||
NSString* _newerVersion;
|
NSString* _newerVersion;
|
||||||
NSString* _newerLdidVersion;
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
|
@ -32,26 +32,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchLatestLdidVersion(^(NSString* latestVersion)
|
|
||||||
{
|
|
||||||
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
NSString* ldidVersion = nil;
|
|
||||||
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
|
|
||||||
if(ldidVersionData)
|
|
||||||
{
|
|
||||||
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(![latestVersion isEqualToString:ldidVersion])
|
|
||||||
{
|
|
||||||
_newerLdidVersion = latestVersion;
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^
|
|
||||||
{
|
|
||||||
[self reloadSpecifiers];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableArray*)specifiers
|
- (NSMutableArray*)specifiers
|
||||||
|
@ -110,81 +90,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||||
|
|
||||||
[_specifiers addObject:rebuildIconCacheSpecifier];
|
[_specifiers addObject:rebuildIconCacheSpecifier];
|
||||||
|
|
||||||
NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid"];
|
|
||||||
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
|
|
||||||
BOOL ldidInstalled = [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
|
|
||||||
|
|
||||||
NSString* ldidVersion = nil;
|
|
||||||
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
|
|
||||||
if(ldidVersionData)
|
|
||||||
{
|
|
||||||
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
|
|
||||||
}
|
|
||||||
|
|
||||||
PSSpecifier* signingGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
|
||||||
signingGroupSpecifier.name = @"Signing";
|
|
||||||
|
|
||||||
if(ldidInstalled)
|
|
||||||
{
|
|
||||||
[signingGroupSpecifier setProperty:@"ldid is installed and allows TrollStore to install unsigned IPA files." forKey:@"footerText"];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
[signingGroupSpecifier setProperty:@"In order for TrollStore to be able to install unsigned IPAs, ldid has to be installed using this button. It can't be directly included in TrollStore because of licensing issues." forKey:@"footerText"];
|
|
||||||
}
|
|
||||||
|
|
||||||
[_specifiers addObject:signingGroupSpecifier];
|
|
||||||
|
|
||||||
if(ldidInstalled)
|
|
||||||
{
|
|
||||||
NSString* installedTitle = @"ldid: Installed";
|
|
||||||
if(ldidVersion)
|
|
||||||
{
|
|
||||||
installedTitle = [NSString stringWithFormat:@"%@ (%@)", installedTitle, ldidVersion];
|
|
||||||
}
|
|
||||||
|
|
||||||
PSSpecifier* ldidInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:installedTitle
|
|
||||||
target:self
|
|
||||||
set:nil
|
|
||||||
get:nil
|
|
||||||
detail:nil
|
|
||||||
cell:PSStaticTextCell
|
|
||||||
edit:nil];
|
|
||||||
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
|
|
||||||
ldidInstalledSpecifier.identifier = @"ldidInstalled";
|
|
||||||
[_specifiers addObject:ldidInstalledSpecifier];
|
|
||||||
|
|
||||||
if(_newerLdidVersion && ![_newerLdidVersion isEqualToString:ldidVersion])
|
|
||||||
{
|
|
||||||
NSString* updateTitle = [NSString stringWithFormat:@"Update to %@", _newerLdidVersion];
|
|
||||||
PSSpecifier* ldidUpdateSpecifier = [PSSpecifier preferenceSpecifierNamed:updateTitle
|
|
||||||
target:self
|
|
||||||
set:nil
|
|
||||||
get:nil
|
|
||||||
detail:nil
|
|
||||||
cell:PSButtonCell
|
|
||||||
edit:nil];
|
|
||||||
ldidUpdateSpecifier.identifier = @"updateLdid";
|
|
||||||
[ldidUpdateSpecifier setProperty:@YES forKey:@"enabled"];
|
|
||||||
ldidUpdateSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
|
|
||||||
[_specifiers addObject:ldidUpdateSpecifier];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PSSpecifier* installLdidSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install ldid"
|
|
||||||
target:self
|
|
||||||
set:nil
|
|
||||||
get:nil
|
|
||||||
detail:nil
|
|
||||||
cell:PSButtonCell
|
|
||||||
edit:nil];
|
|
||||||
installLdidSpecifier.identifier = @"installLdid";
|
|
||||||
[installLdidSpecifier setProperty:@YES forKey:@"enabled"];
|
|
||||||
installLdidSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
|
|
||||||
[_specifiers addObject:installLdidSpecifier];
|
|
||||||
}
|
|
||||||
|
|
||||||
PSSpecifier* persistenceGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
PSSpecifier* persistenceGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||||
persistenceGroupSpecifier.name = @"Persistence";
|
persistenceGroupSpecifier.name = @"Persistence";
|
||||||
[_specifiers addObject:persistenceGroupSpecifier];
|
[_specifiers addObject:persistenceGroupSpecifier];
|
||||||
|
@ -288,7 +193,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||||
[_specifiers addObject:installAlertConfigurationSpecifier];
|
[_specifiers addObject:installAlertConfigurationSpecifier];
|
||||||
|
|
||||||
PSSpecifier* otherGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
PSSpecifier* otherGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||||
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@lunotech11, @SerenaKit, @tylinux: Various contributions\n@ProcursusTeam: uicache and ldid build\n@cstar_ow: uicache\n@saurik: ldid", [self getTrollStoreVersion]] forKey:@"footerText"];
|
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@lunotech11, @SerenaKit, @tylinux: Various contributions\n@ProcursusTeam: uicache\n@cstar_ow: uicache", [self getTrollStoreVersion]] forKey:@"footerText"];
|
||||||
[_specifiers addObject:otherGroupSpecifier];
|
[_specifiers addObject:otherGroupSpecifier];
|
||||||
|
|
||||||
PSSpecifier* advancedLinkSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Advanced"
|
PSSpecifier* advancedLinkSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Advanced"
|
||||||
|
@ -348,11 +253,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
|
||||||
respring();
|
respring();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)installOrUpdateLdidPressed
|
|
||||||
{
|
|
||||||
[TSInstallationController installLdid];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)installPersistenceHelperPressed
|
- (void)installPersistenceHelperPressed
|
||||||
{
|
{
|
||||||
NSMutableArray* appCandidates = [NSMutableArray new];
|
NSMutableArray* appCandidates = [NSMutableArray new];
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
|
|
||||||
4. Wait a few seconds, your device should respring and TrollStore will be installed.
|
4. Wait a few seconds, your device should respring and TrollStore will be installed.
|
||||||
|
|
||||||
5. Open the TrollStore app and press "Install ldid" in the Settings tab, then read the information under "Persistence", the TrollHelper app on the home screen will be your persistence helper.
|
5. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
||||||
|
|
||||||
6. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
|
||||||
|
|
||||||
## Unjailbreaking while retaining TrollStore
|
## Unjailbreaking while retaining TrollStore
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,6 @@
|
||||||
|
|
||||||
7. You can now either delete the "GTA Car Tracker" app, or register it as the persistence helper by opening it and tapping the option at the bottom. If you do this, don't delete the app.
|
7. You can now either delete the "GTA Car Tracker" app, or register it as the persistence helper by opening it and tapping the option at the bottom. If you do this, don't delete the app.
|
||||||
|
|
||||||
8. Open the TrollStore app and press "Install ldid" in the Settings tab, then read the information under "Persistence", and install the Persistence Helper into a system app if you want persistence (not needed if you registered the GTA Car Tracker app as the persistence helper in step 7).
|
8. Open the TrollStore app and read the information under "Persistence", and install the Persistence Helper into a system app if you want persistence (not needed if you registered the GTA Car Tracker app as the persistence helper in step 7).
|
||||||
|
|
||||||
9. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
9. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
||||||
|
|
|
@ -20,6 +20,6 @@
|
||||||
|
|
||||||
7. You can now either delete the "GTA Car Tracker" app, or register it as the persistence helper by opening it and tapping the option at the bottom. If you do this, don't delete the app.
|
7. You can now either delete the "GTA Car Tracker" app, or register it as the persistence helper by opening it and tapping the option at the bottom. If you do this, don't delete the app.
|
||||||
|
|
||||||
8. Open the TrollStore app and press "Install ldid" in the Settings tab, then read the information under "Persistence", and install the Persistence Helper into a system app if you want persistence (not needed if you registered the GTA Car Tracker app as the persistence helper in step 7).
|
8. Open the TrollStore app and read the information under "Persistence", and install the Persistence Helper into a system app if you want persistence (not needed if you registered the GTA Car Tracker app as the persistence helper in step 7).
|
||||||
|
|
||||||
9. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
9. Done, you can now share IPA files with TrollStore and they will be permanently installed on your device.
|
||||||
|
|
Loading…
Reference in New Issue