diff --git a/Helper/control b/Helper/control index d89e573..be35717 100644 --- a/Helper/control +++ b/Helper/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstoreroothelper Name: trollstoreroothelper -Version: 1.0.3 +Version: 1.0.6 Architecture: iphoneos-arm Description: An awesome tool of some sort!! Maintainer: opa334 diff --git a/Helper/main.m b/Helper/main.m index 75b9ef0..6228fa7 100644 --- a/Helper/main.m +++ b/Helper/main.m @@ -8,52 +8,10 @@ #import #import "CoreServices.h" #import "Shared.h" -#import -#import -#import -#import -#import -#import -#import -#import #import #import - -#ifdef __LP64__ -#define segment_command_universal segment_command_64 -#define mach_header_universal mach_header_64 -#define MH_MAGIC_UNIVERSAL MH_MAGIC_64 -#define MH_CIGAM_UNIVERSAL MH_CIGAM_64 -#else -#define segment_command_universal segment_command -#define mach_header_universal mach_header -#define MH_MAGIC_UNIVERSAL MH_MAGIC -#define MH_CIGAM_UNIVERSAL MH_CIGAM -#endif - -#define SWAP32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0xff0000) >> 8) | (((x) & 0xff00) << 8) | (((x) & 0xff) << 24)) -uint32_t s32(uint32_t toSwap, BOOL shouldSwap) -{ - return shouldSwap ? SWAP32(toSwap) : toSwap; -} - -#define CPU_SUBTYPE_ARM64E_NEW_ABI 0x80000002 - -struct CSSuperBlob { - uint32_t magic; - uint32_t length; - uint32_t count; -}; - -struct CSBlob { - uint32_t type; - uint32_t offset; -}; - -#define CS_MAGIC_EMBEDDED_SIGNATURE 0xfade0cc0 -#define CS_MAGIC_EMBEDDED_SIGNATURE_REVERSED 0xc00cdefa -#define CS_MAGIC_EMBEDDED_ENTITLEMENTS 0xfade7171 +#import extern mach_msg_return_t SBReloadIconForIdentifier(mach_port_t machport, const char* identifier); @@ -65,6 +23,27 @@ extern NSString* BKSOpenApplicationOptionKeyActivateForEvent; extern void BKSTerminateApplicationForReasonAndReportWithDescription(NSString *bundleID, int reasonID, bool report, NSString *description); +typedef CF_OPTIONS(uint32_t, SecCSFlags) { + kSecCSDefaultFlags = 0 +}; + + +#define kSecCSRequirementInformation 1 << 2 +#define kSecCSSigningInformation 1 << 1 + +typedef struct __SecCode const *SecStaticCodeRef; + +extern CFStringRef kSecCodeInfoEntitlementsDict; +extern CFStringRef kSecCodeInfoCertificates; +extern CFStringRef kSecPolicyAppleiPhoneApplicationSigning; +extern CFStringRef kSecPolicyAppleiPhoneProfileApplicationSigning; +extern CFStringRef kSecPolicyLeafMarkerOid; + +OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes, SecStaticCodeRef *staticCode); +OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags, CFDictionaryRef *information); +CFDataRef SecCertificateCopyExtensionValue(SecCertificateRef certificate, CFTypeRef extensionOID, bool *isCritical); +void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value); + #define kCFPreferencesNoContainer CFSTR("kCFPreferencesNoContainer") typedef CFPropertyListRef (*_CFPreferencesCopyValueWithContainerType)(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath); @@ -221,117 +200,219 @@ int runLdid(NSArray* args, NSString** output, NSString** errorOutput) return WEXITSTATUS(status); } -NSDictionary* dumpEntitlements(NSString* binaryPath) +SecStaticCodeRef getStaticCodeRef(NSString *binaryPath) { - char* entitlementsData = NULL; - uint32_t entitlementsLength = 0; - - FILE* machoFile = fopen(binaryPath.UTF8String, "rb"); - struct mach_header_universal header; - fread(&header,sizeof(header),1,machoFile); - - if(header.magic == FAT_MAGIC || header.magic == FAT_CIGAM) + if(binaryPath == nil) { - fseek(machoFile,0,SEEK_SET); - - struct fat_header fatHeader; - fread(&fatHeader,sizeof(fatHeader),1,machoFile); - - BOOL swpFat = fatHeader.magic == FAT_CIGAM; - - for(int i = 0; i < s32(fatHeader.nfat_arch, swpFat); i++) - { - struct fat_arch fatArch; - fseek(machoFile,sizeof(fatHeader) + sizeof(fatArch) * i,SEEK_SET); - fread(&fatArch,sizeof(fatArch),1,machoFile); - - if(s32(fatArch.cputype, swpFat) != CPU_TYPE_ARM64) - { - continue; - } - - fseek(machoFile,s32(fatArch.offset, swpFat),SEEK_SET); - struct mach_header_universal header; - fread(&header,sizeof(header),1,machoFile); - - BOOL swp = header.magic == MH_CIGAM_UNIVERSAL; - - // This code is cursed, don't stare at it too long or it will stare back at you - uint32_t offset = s32(fatArch.offset, swpFat) + sizeof(header); - for(int c = 0; c < s32(header.ncmds, swp); c++) - { - fseek(machoFile,offset,SEEK_SET); - struct load_command cmd; - fread(&cmd,sizeof(cmd),1,machoFile); - uint32_t normalizedCmd = s32(cmd.cmd,swp); - if(normalizedCmd == LC_CODE_SIGNATURE) - { - struct linkedit_data_command codeSignCommand; - fseek(machoFile,offset,SEEK_SET); - fread(&codeSignCommand,sizeof(codeSignCommand),1,machoFile); - uint32_t codeSignCmdOffset = s32(fatArch.offset, swpFat) + s32(codeSignCommand.dataoff, swp); - fseek(machoFile, codeSignCmdOffset, SEEK_SET); - struct CSSuperBlob superBlob; - fread(&superBlob, sizeof(superBlob), 1, machoFile); - if(SWAP32(superBlob.magic) == CS_MAGIC_EMBEDDED_SIGNATURE) - { - uint32_t itemCount = SWAP32(superBlob.count); - for(int i = 0; i < itemCount; i++) - { - fseek(machoFile, codeSignCmdOffset + sizeof(superBlob) + i * sizeof(struct CSBlob),SEEK_SET); - struct CSBlob blob; - fread(&blob, sizeof(struct CSBlob), 1, machoFile); - fseek(machoFile, codeSignCmdOffset + SWAP32(blob.offset),SEEK_SET); - uint32_t blobMagic; - fread(&blobMagic, sizeof(uint32_t), 1, machoFile); - if(SWAP32(blobMagic) == CS_MAGIC_EMBEDDED_ENTITLEMENTS) - { - uint32_t entitlementsLengthTmp; - fread(&entitlementsLengthTmp, sizeof(uint32_t), 1, machoFile); - entitlementsLength = SWAP32(entitlementsLengthTmp); - entitlementsData = malloc(entitlementsLength - 8); - fread(&entitlementsData[0], entitlementsLength - 8, 1, machoFile); - break; - } - } - } - - break; - } - - offset += cmd.cmdsize; - } - } + return NULL; } - - fclose(machoFile); - - NSData* entitlementsNSData = nil; - - if(entitlementsData) + + CFURLRef binaryURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (__bridge CFStringRef)binaryPath, kCFURLPOSIXPathStyle, false); + if(binaryURL == NULL) { - entitlementsNSData = [NSData dataWithBytes:entitlementsData length:entitlementsLength]; - free(entitlementsData); + NSLog(@"[getStaticCodeRef] failed to get URL to binary %@", binaryPath); + return NULL; } - - if(entitlementsNSData) + + SecStaticCodeRef codeRef = NULL; + OSStatus result; + + result = SecStaticCodeCreateWithPathAndAttributes(binaryURL, kSecCSDefaultFlags, NULL, &codeRef); + + CFRelease(binaryURL); + + if(result != errSecSuccess) { - NSDictionary* plist = [NSPropertyListSerialization propertyListWithData:entitlementsNSData options:NSPropertyListImmutable format:nil error:nil]; - NSLog(@"%@ dumped entitlements %@", binaryPath, plist); - return plist; + NSLog(@"[getStaticCodeRef] failed to create static code for binary %@", binaryPath); + return NULL; + } + + return codeRef; +} + +NSDictionary* dumpEntitlements(SecStaticCodeRef codeRef) +{ + if(codeRef == NULL) + { + NSLog(@"[dumpEntitlements] attempting to dump entitlements without a StaticCodeRef"); + return nil; + } + + CFDictionaryRef signingInfo = NULL; + OSStatus result; + + result = SecCodeCopySigningInformation(codeRef, kSecCSRequirementInformation, &signingInfo); + + if(result != errSecSuccess) + { + NSLog(@"[dumpEntitlements] failed to copy signing info from static code"); + return nil; + } + + NSDictionary *entitlementsNSDict = nil; + + CFDictionaryRef entitlements = CFDictionaryGetValue(signingInfo, kSecCodeInfoEntitlementsDict); + if(entitlements == NULL) + { + NSLog(@"[dumpEntitlements] no entitlements specified"); + } + else if(CFGetTypeID(entitlements) != CFDictionaryGetTypeID()) + { + NSLog(@"[dumpEntitlements] invalid entitlements"); } else { - NSLog(@"Failed to dump entitlements of %@... This is bad", binaryPath); + entitlementsNSDict = (__bridge NSDictionary *)(entitlements); + NSLog(@"[dumpEntitlements] dumped %@", entitlementsNSDict); } - return nil; + CFRelease(signingInfo); + return entitlementsNSDict; +} + +NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString *binaryPath) +{ + // This function is intended for one-shot checks. Main-event functions should retain/release their own SecStaticCodeRefs + + if(binaryPath == nil) + { + return nil; + } + + SecStaticCodeRef codeRef = getStaticCodeRef(binaryPath); + if(codeRef == NULL) + { + return nil; + } + + NSDictionary *entitlements = dumpEntitlements(codeRef); + CFRelease(codeRef); + + return entitlements; +} + +BOOL certificateHasDataForExtensionOID(SecCertificateRef certificate, CFStringRef oidString) +{ + if(certificate == NULL || oidString == NULL) + { + NSLog(@"[certificateHasDataForExtensionOID] attempted to check null certificate or OID"); + return NO; + } + + CFDataRef extensionData = SecCertificateCopyExtensionValue(certificate, oidString, NULL); + if(extensionData != NULL) + { + CFRelease(extensionData); + return YES; + } + + return NO; +} + +BOOL codeCertChainContainsFakeAppStoreExtensions(SecStaticCodeRef codeRef) +{ + if(codeRef == NULL) + { + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] attempted to check cert chain of null static code object"); + return NO; + } + + CFDictionaryRef signingInfo = NULL; + OSStatus result; + + result = SecCodeCopySigningInformation(codeRef, kSecCSSigningInformation, &signingInfo); + + if(result != errSecSuccess) + { + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] failed to copy signing info from static code"); + return NO; + } + + CFArrayRef certificates = CFDictionaryGetValue(signingInfo, kSecCodeInfoCertificates); + if(certificates == NULL || CFArrayGetCount(certificates) == 0) + { + return NO; + } + + // If we match the standard Apple policy, we are signed properly, but we haven't been deliberately signed with a custom root + + SecPolicyRef appleAppStorePolicy = SecPolicyCreateWithProperties(kSecPolicyAppleiPhoneApplicationSigning, NULL); + + SecTrustRef trust = NULL; + SecTrustCreateWithCertificates(certificates, appleAppStorePolicy, &trust); + + if(SecTrustEvaluateWithError(trust, nil)) + { + CFRelease(trust); + CFRelease(appleAppStorePolicy); + CFRelease(signingInfo); + + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] found certificate extension, but was issued by Apple (App Store)"); + return NO; + } + + // We haven't matched Apple, so keep going. Is the app profile signed? + + CFRelease(appleAppStorePolicy); + + SecPolicyRef appleProfileSignedPolicy = SecPolicyCreateWithProperties(kSecPolicyAppleiPhoneProfileApplicationSigning, NULL); + if(SecTrustSetPolicies(trust, appleProfileSignedPolicy) != errSecSuccess) + { + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] error replacing trust policy to check for profile-signed app"); + CFRelease(trust); + CFRelease(signingInfo); + return NO; + } + + if(SecTrustEvaluateWithError(trust, nil)) + { + CFRelease(trust); + CFRelease(appleProfileSignedPolicy); + CFRelease(signingInfo); + + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] found certificate extension, but was issued by Apple (profile-signed)"); + return NO; + } + + // Still haven't matched Apple. Are we using a custom root that would take the App Store fastpath? + CFRelease(appleProfileSignedPolicy); + + // Cert chain should be of length 3 + if(CFArrayGetCount(certificates) != 3) + { + CFRelease(signingInfo); + + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] certificate chain length != 3"); + return NO; + } + + // AppleCodeSigning only checks for the codeSigning EKU by default + SecPolicyRef customRootPolicy = SecPolicyCreateWithProperties(kSecPolicyAppleCodeSigning, NULL); + SecPolicySetOptionsValue(customRootPolicy, CFSTR("LeafMarkerOid"), CFSTR("1.2.840.113635.100.6.1.3")); + + if(SecTrustSetPolicies(trust, customRootPolicy) != errSecSuccess) + { + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] error replacing trust policy to check for custom root"); + CFRelease(trust); + CFRelease(signingInfo); + return NO; + } + + // Need to add our certificate chain to the anchor as it is expected to be a self-signed root + SecTrustSetAnchorCertificates(trust, certificates); + + BOOL evaluatesToCustomAnchor = SecTrustEvaluateWithError(trust, nil); + NSLog(@"[codeCertChainContainsFakeAppStoreExtensions] app signed with non-Apple certificate %@ using valid custom certificates", evaluatesToCustomAnchor ? @"IS" : @"is NOT"); + + CFRelease(trust); + CFRelease(customRootPolicy); + CFRelease(signingInfo); + + return evaluatesToCustomAnchor; } BOOL signApp(NSString* appPath, NSError** error) { - if(!isLdidInstalled()) return NO; - NSDictionary* appInfoDict = [NSDictionary dictionaryWithContentsOfFile:[appPath stringByAppendingPathComponent:@"Info.plist"]]; if(!appInfoDict) return NO; @@ -339,13 +420,45 @@ BOOL signApp(NSString* appPath, NSError** error) NSString* executablePath = [appPath stringByAppendingPathComponent:executable]; if(![[NSFileManager defaultManager] fileExistsAtPath:executablePath]) return NO; + + NSObject *tsBundleIsPreSigned = appInfoDict[@"TSBundlePreSigned"]; + if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]]) + { + + // if TSBundlePreSigned = YES, this bundle has been externally signed so we can skip over signing it now + NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned; + if([tsBundleIsPreSignedNum boolValue] == YES) + { + NSLog(@"[signApp] taking fast path for app which declares it has already been signed (%@)", executablePath); + return YES; + } + } + + SecStaticCodeRef codeRef = getStaticCodeRef(executablePath); + if(codeRef != NULL) + { + if(codeCertChainContainsFakeAppStoreExtensions(codeRef)) + { + NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", executablePath); + CFRelease(codeRef); + return YES; + } + } + else + { + NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", executablePath); + } + + if(!isLdidInstalled()) return NO; NSString* certPath = [trollStoreAppPath() stringByAppendingPathComponent:@"cert.p12"]; NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath]; NSString* errorOutput; int ldidRet; - NSDictionary* entitlements = dumpEntitlements(executablePath); + NSDictionary* entitlements = dumpEntitlements(codeRef); + CFRelease(codeRef); + if(!entitlements) { NSLog(@"app main binary has no entitlements, signing app with fallback entitlements..."); @@ -371,9 +484,23 @@ BOOL signApp(NSString* appPath, NSError** error) return ldidRet == 0; } +void applyPatchesToInfoDictionary(NSString* appPath) +{ + NSURL* appURL = [NSURL fileURLWithPath:appPath]; + NSURL* infoPlistURL = [appURL URLByAppendingPathComponent:@"Info.plist"]; + NSMutableDictionary* infoDictM = [[NSDictionary dictionaryWithContentsOfURL:infoPlistURL error:nil] mutableCopy]; + if(!infoDictM) return; + + // enable notifications + infoDictM[@"SBAppUsesLocalNotifications"] = @1; + + [infoDictM writeToURL:infoPlistURL error:nil]; +} + // 170: failed to create container for app bundle // 171: a non trollstore app with the same identifier is already installled // 172: no info.plist found in app +// 173: app is not signed and cannot be signed because ldid not installed or didn't work int installApp(NSString* appPath, BOOL sign, BOOL force, NSError** error) { NSLog(@"[installApp force = %d]", force); @@ -381,10 +508,11 @@ int installApp(NSString* appPath, BOOL sign, BOOL force, NSError** error) NSString* appId = appIdForAppPath(appPath); if(!appId) return 172; + applyPatchesToInfoDictionary(appPath); + if(sign) { - // if it fails to sign, we don't care - signApp(appPath, error); + if(!signApp(appPath, error)) return 173; } BOOL existed; @@ -420,13 +548,25 @@ int installApp(NSString* appPath, BOOL sign, BOOL force, NSError** error) // Mark app as TrollStore app [[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil]; - // Apply correct permissions - NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil]; + // 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); + } + + // 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]; @@ -437,10 +577,15 @@ int installApp(NSString* appPath, BOOL sign, BOOL force, NSError** error) chmod(executablePath.UTF8String, 0755); } } - else if([filePath.pathExtension isEqualToString:@"dylib"]) + 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); + } } // chown 0 all root binaries @@ -502,17 +647,10 @@ int installApp(NSString* appPath, BOOL sign, BOOL force, NSError** error) } } -int uninstallApp(NSString* appId, NSError** error) +int uninstallApp(NSString* appPath, NSString* appId, NSError** error) { - NSString* appPath = appPathForAppId(appId, error); - if(!appPath) return 1; - LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:appId]; - NSLog(@"appProxy: %@", appProxy); - - MCMContainer *appContainer = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:appId createIfNecessary:NO existed:nil error:nil]; - NSLog(@"1"); NSString *containerPath = [appContainer url].path; if(containerPath) { @@ -524,8 +662,8 @@ int uninstallApp(NSString* appId, NSError** error) // delete group container paths [[appProxy groupContainerURLs] enumerateKeysAndObjectsUsingBlock:^(NSString* groupID, NSURL* groupURL, BOOL* stop) { - [[NSFileManager defaultManager] removeItemAtURL:groupURL error:nil]; NSLog(@"deleting %@", groupURL); + [[NSFileManager defaultManager] removeItemAtURL:groupURL error:nil]; }]; // delete app plugin paths @@ -534,15 +672,15 @@ int uninstallApp(NSString* appId, NSError** error) NSURL* pluginURL = pluginProxy.dataContainerURL; if(pluginURL) { - [[NSFileManager defaultManager] removeItemAtPath:pluginURL.path error:error]; - NSLog(@"deleting %@", pluginURL.path); + NSLog(@"deleting %@", pluginURL); + [[NSFileManager defaultManager] removeItemAtURL:pluginURL error:error]; } } // unregister app registerPath((char*)appPath.UTF8String, 1); - NSLog(@"deleting %@", [appPath stringByDeletingLastPathComponent]); + NSLog(@"deleting %@", [appPath stringByDeletingLastPathComponent]); // delete app BOOL deleteSuc = [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error]; if(deleteSuc) @@ -555,6 +693,22 @@ int uninstallApp(NSString* appId, NSError** error) } } +int uninstallAppByPath(NSString* appPath, NSError** error) +{ + if(!appPath) return 1; + NSString* appId = appIdForAppPath(appPath); + if(!appId) return 1; + return uninstallApp(appPath, appId, error); +} + +int uninstallAppById(NSString* appId, NSError** error) +{ + if(!appId) return 1; + NSString* appPath = appPathForAppId(appId, error); + if(!appPath) return 1; + return uninstallApp(appPath, appId, error); +} + // 166: IPA does not exist or is not accessible // 167: IPA does not appear to contain an app @@ -597,7 +751,7 @@ void uninstallAllApps(void) { for(NSString* appPath in trollStoreInstalledAppBundlePaths()) { - uninstallApp(appIdForAppPath(appPath), nil); + uninstallAppById(appIdForAppPath(appPath), nil); } } @@ -811,8 +965,13 @@ int main(int argc, char *argv[], char *envp[]) { { if(argc <= 2) return -3; NSString* appId = [NSString stringWithUTF8String:argv[2]]; - ret = uninstallApp(appId, &error); - } else if([cmd isEqualToString:@"install-trollstore"]) + ret = uninstallAppById(appId, &error); + } else if([cmd isEqualToString:@"uninstall-path"]) + { + if(argc <= 2) return -3; + NSString* appPath = [NSString stringWithUTF8String:argv[2]]; + ret = uninstallAppByPath(appPath, &error); + }else if([cmd isEqualToString:@"install-trollstore"]) { if(argc <= 2) return -3; NSString* tsTar = [NSString stringWithUTF8String:argv[2]]; diff --git a/Helper/uicache.m b/Helper/uicache.m index 1a2f8d9..6b5aa9a 100644 --- a/Helper/uicache.m +++ b/Helper/uicache.m @@ -6,7 +6,7 @@ // uicache on steroids -extern NSDictionary* dumpEntitlements(NSString* binaryPath); +extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString* binaryPath); NSDictionary* constructGroupsContainersForEntitlements(NSDictionary* entitlements, BOOL systemGroups) { @@ -118,7 +118,7 @@ void registerPath(char* cPath, int unregister) // Add entitlements NSString* appExecutablePath = [path stringByAppendingPathComponent:appInfoPlist[@"CFBundleExecutable"]]; - NSDictionary* entitlements = dumpEntitlements(appExecutablePath); + NSDictionary* entitlements = dumpEntitlementsFromBinaryAtPath(appExecutablePath); if(entitlements) { dictToRegister[@"Entitlements"] = entitlements; @@ -139,6 +139,9 @@ void registerPath(char* cPath, int unregister) dictToRegister[@"IsDeletable"] = @0; dictToRegister[@"Path"] = path; dictToRegister[@"IsContainerized"] = @(constructContainerizationForEntitlements(entitlements)); + dictToRegister[@"SignerOrganization"] = @"Apple Inc."; + dictToRegister[@"SignatureVersion"] = @132352; + dictToRegister[@"SignerIdentity"] = @"Apple iPhone OS Application Signing"; NSString* teamIdentifier = constructTeamIdentifierForEntitlements(entitlements); if(teamIdentifier) dictToRegister[@"TeamIdentifier"] = teamIdentifier; @@ -185,7 +188,7 @@ void registerPath(char* cPath, int unregister) // Add entitlements NSString* pluginExecutablePath = [pluginPath stringByAppendingPathComponent:pluginInfoPlist[@"CFBundleExecutable"]]; - NSDictionary* pluginEntitlements = dumpEntitlements(pluginExecutablePath); + NSDictionary* pluginEntitlements = dumpEntitlementsFromBinaryAtPath(pluginExecutablePath); if(pluginEntitlements) { pluginDict[@"Entitlements"] = pluginEntitlements; @@ -206,6 +209,9 @@ void registerPath(char* cPath, int unregister) pluginDict[@"Path"] = pluginPath; pluginDict[@"PluginOwnerBundleID"] = appBundleID; pluginDict[@"IsContainerized"] = @(constructContainerizationForEntitlements(pluginEntitlements)); + pluginDict[@"SignerOrganization"] = @"Apple Inc."; + pluginDict[@"SignatureVersion"] = @132352; + pluginDict[@"SignerIdentity"] = @"Apple iPhone OS Application Signing"; NSString* pluginTeamIdentifier = constructTeamIdentifierForEntitlements(pluginEntitlements); if(pluginTeamIdentifier) pluginDict[@"TeamIdentifier"] = pluginTeamIdentifier; @@ -247,4 +253,4 @@ void registerPath(char* cPath, int unregister) NSLog(@"Error: Unable to unregister %@", path); } } -} \ No newline at end of file +} diff --git a/Installer/TrollInstaller/TrollInstaller/exploit/IOGPU.c b/Installer/TrollInstaller/TrollInstaller/exploit/IOGPU.c index 8b847cd..9fd681c 100644 --- a/Installer/TrollInstaller/TrollInstaller/exploit/IOGPU.c +++ b/Installer/TrollInstaller/TrollInstaller/exploit/IOGPU.c @@ -55,6 +55,7 @@ int IOGPU_get_command_queue_extra_refills_needed(void) uname(&u); // iPhone 7 + // iPod 7 // iPhone 11 // iPhone 12 // iPhone 13 @@ -62,6 +63,7 @@ int IOGPU_get_command_queue_extra_refills_needed(void) // iPad Pro (10.5-inch, WiFi) if ( strstr(u.machine, "iPhone9,") + || strstr(u.machine, "iPod9,") || strstr(u.machine, "iPhone12,") || strstr(u.machine, "iPhone13,") || strstr(u.machine, "iPhone14,") diff --git a/Installer/TrollInstaller/TrollInstaller/exploit/kernel_base.c b/Installer/TrollInstaller/TrollInstaller/exploit/kernel_base.c index 5c40f51..4d67ec7 100644 --- a/Installer/TrollInstaller/TrollInstaller/exploit/kernel_base.c +++ b/Installer/TrollInstaller/TrollInstaller/exploit/kernel_base.c @@ -10,6 +10,7 @@ #include #include #include +#import extern void badLog(const char*, ...); @@ -53,18 +54,30 @@ uint64_t kernel_base_from_holder(mach_port_t holder, uint64_t holder_addr) struct utsname u; uname(&u); uint64_t off_task_bsd_info; - + #if __arm64e__ - if (strstr(u.machine, "iPhone14,")) + cpu_subtype_t cpuFamily = 0; + size_t cpuFamilySize = sizeof(cpuFamily); + sysctlbyname("hw.cpufamily", &cpuFamily, &cpuFamilySize, NULL, 0); + + bool isA15OrNewer; + if (cpuFamily == CPUFAMILY_ARM_BLIZZARD_AVALANCHE) { + isA15OrNewer = true; + } + else { + isA15OrNewer = false; + } + + if (isA15OrNewer) { off_task_bsd_info = 0x3c8; // ios15.1 a15 // proc_t::task_bsd_info } else { - off_task_bsd_info = 0x3b8; //; iOS15.1 a12 // proc_t::task_bsd_info + off_task_bsd_info = 0x3b8; //; iOS15.1 a12-a14 // proc_t::task_bsd_info } #else - off_task_bsd_info = 0x3A0; + off_task_bsd_info = 0x3A0; // a9-a11 #endif g_self_proc = xpaci(kread64(self_task + off_task_bsd_info)); diff --git a/PersistenceHelper/Resources/Info.plist b/PersistenceHelper/Resources/Info.plist index 597db31..15e42bc 100644 --- a/PersistenceHelper/Resources/Info.plist +++ b/PersistenceHelper/Resources/Info.plist @@ -52,7 +52,7 @@ iPhoneOS CFBundleVersion - 1.0.3 + 1.0.7 LSRequiresIPhoneOS UIDeviceFamily diff --git a/PersistenceHelper/control b/PersistenceHelper/control index 7315cc5..eb49441 100644 --- a/PersistenceHelper/control +++ b/PersistenceHelper/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstorehelper Name: TrollStore Helper -Version: 1.0.3 +Version: 1.0.7 Architecture: iphoneos-arm Description: Helper app to install and manage TrollStore! Maintainer: opa334 diff --git a/Store/Resources/Info.plist b/Store/Resources/Info.plist index a399920..4ad618f 100644 --- a/Store/Resources/Info.plist +++ b/Store/Resources/Info.plist @@ -50,7 +50,7 @@ iPhoneOS CFBundleVersion - 1.0.3 + 1.0.7 LSRequiresIPhoneOS UIDeviceFamily diff --git a/Store/TSAppTableViewController.m b/Store/TSAppTableViewController.m index cd11afc..72549ce 100644 --- a/Store/TSAppTableViewController.m +++ b/Store/TSAppTableViewController.m @@ -55,7 +55,15 @@ { NSString* appPath = [[TSApplicationsManager sharedInstance] installedAppPaths][indexPath.row]; NSString* appId = [[TSApplicationsManager sharedInstance] appIdForAppPath:appPath]; - [[TSApplicationsManager sharedInstance] uninstallApp:appId]; + + if(appId) + { + [[TSApplicationsManager sharedInstance] uninstallApp:appId]; + } + else + { + [[TSApplicationsManager sharedInstance] uninstallAppByPath:appPath]; + } } } diff --git a/Store/TSApplicationsManager.h b/Store/TSApplicationsManager.h index 2b238f7..b8f8a41 100644 --- a/Store/TSApplicationsManager.h +++ b/Store/TSApplicationsManager.h @@ -17,5 +17,6 @@ - (int)installIpa:(NSString*)pathToIpa force:(BOOL)force; - (int)installIpa:(NSString*)pathToIpa; - (int)uninstallApp:(NSString*)appId; +- (int)uninstallAppByPath:(NSString*)path; @end \ No newline at end of file diff --git a/Store/TSApplicationsManager.m b/Store/TSApplicationsManager.m index 957a3eb..328c7f9 100644 --- a/Store/TSApplicationsManager.m +++ b/Store/TSApplicationsManager.m @@ -72,6 +72,9 @@ case 172: errorDescription = @"The app does not seem to contain an Info.plist"; break; + case 173: + errorDescription = @"The app is not signed with a fake CoreTrust certificate and ldid does not seem to be installed. Make sure ldid is installed in the settings tab and try again."; + break; } NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}]; @@ -100,9 +103,18 @@ - (int)uninstallApp:(NSString*)appId { + if(!appId) return -200; int ret = spawnRoot(helperPath(), @[@"uninstall", appId]); [[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil]; return ret; } +- (int)uninstallAppByPath:(NSString*)path +{ + if(!path) return -200; + int ret = spawnRoot(helperPath(), @[@"uninstall-path", path]); + [[NSNotificationCenter defaultCenter] postNotificationName:@"ApplicationsChanged" object:nil]; + return ret; +} + @end \ No newline at end of file diff --git a/Store/TSSceneDelegate.m b/Store/TSSceneDelegate.m index 55b1a1d..a09325c 100644 --- a/Store/TSSceneDelegate.m +++ b/Store/TSSceneDelegate.m @@ -77,13 +77,8 @@ NSURL* url = context.URL; if (url != nil && [url isFileURL]) { [url startAccessingSecurityScopedResource]; - NSURL* tmpCopyURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:url.lastPathComponent]]; - - [[NSFileManager defaultManager] copyItemAtURL:url toURL:tmpCopyURL error:nil]; - void (^doneBlock)(BOOL) = ^(BOOL shouldExit) { - [[NSFileManager defaultManager] removeItemAtURL:tmpCopyURL error:nil]; [url stopAccessingSecurityScopedResource]; [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; @@ -105,7 +100,7 @@ { // Update TrollStore itself NSLog(@"Updating TrollStore..."); - int ret = spawnRoot(helperPath(), @[@"install-trollstore", tmpCopyURL.path]); + int ret = spawnRoot(helperPath(), @[@"install-trollstore", url.path]); doneBlock(ret == 0); NSLog(@"Updated TrollStore!"); } diff --git a/Store/TSSettingsListController.m b/Store/TSSettingsListController.m index 99a3d83..2885116 100644 --- a/Store/TSSettingsListController.m +++ b/Store/TSSettingsListController.m @@ -192,7 +192,7 @@ } PSSpecifier* otherGroupSpecifier = [PSSpecifier emptyGroupSpecifier]; - [otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022 Lars Fröder (opa334)\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@ProcursusTeam: uicache and ldid build\n@cstar_ow: uicache\n@saurik: ldid", getTrollStoreVersion()] forKey:@"footerText"]; + [otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022 Lars Fröder (opa334)\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@lunotech11: Some contributions\n@ProcursusTeam: uicache and ldid build\n@cstar_ow: uicache\n@saurik: ldid", getTrollStoreVersion()] forKey:@"footerText"]; [_specifiers addObject:otherGroupSpecifier]; // Uninstall TrollStore diff --git a/Store/control b/Store/control index 68b7e5c..c215f6c 100644 --- a/Store/control +++ b/Store/control @@ -1,6 +1,6 @@ Package: com.opa334.trollstore Name: TrollStore -Version: 1.0.3 +Version: 1.0.7 Architecture: iphoneos-arm Description: An awesome application! Maintainer: opa334 diff --git a/Store/entitlements.plist b/Store/entitlements.plist index e3a4663..b1b4f33 100644 --- a/Store/entitlements.plist +++ b/Store/entitlements.plist @@ -30,5 +30,7 @@ com.apple.private.uninstall.deletion + com.apple.private.security.storage.MobileDocuments + \ No newline at end of file