diff --git a/AltStoreCore/ALTProvisioningProfileWrapper.h b/AltStoreCore/ALTProvisioningProfileWrapper.h deleted file mode 100644 index 554b7a9..0000000 --- a/AltStoreCore/ALTProvisioningProfileWrapper.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// ALTProvisioningProfile.h -// AltSign -// -// Created by Riley Testut on 5/22/19. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -#import - -#import "ALTProvisioningProfile.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ALTProvisioningProfileWrapper : NSObject - -@property (copy, nonatomic) NSString *name; -@property (copy, nonatomic, nullable) NSString *identifier; -@property (copy, nonatomic) NSUUID *UUID; - -@property (copy, nonatomic) NSString *bundleIdentifier; -@property (copy, nonatomic) NSString *teamIdentifier; - -@property (copy, nonatomic) NSDate *creationDate; -@property (copy, nonatomic) NSDate *expirationDate; - -@property (copy, nonatomic) NSDictionary *entitlements; -@property (copy, nonatomic) NSArray *certificates; -@property (copy, nonatomic) NSArray *deviceIDs; - -@property BOOL isFreeProvisioningProfile; - -@property (copy, nonatomic) NSData *data; - -- (nullable instancetype)initWithProfile:(ALTProvisioningProfile *)profile; -@end - -NS_ASSUME_NONNULL_END diff --git a/AltStoreCore/ALTProvisioningProfileWrapper.m b/AltStoreCore/ALTProvisioningProfileWrapper.m deleted file mode 100644 index cd08c6a..0000000 --- a/AltStoreCore/ALTProvisioningProfileWrapper.m +++ /dev/null @@ -1,23 +0,0 @@ -#import "ALTProvisioningProfileWrapper.h" - -@implementation ALTProvisioningProfileWrapper - -- (nullable instancetype)initWithProfile:(ALTProvisioningProfile *)profile { - self = [self init]; - self.name = profile.name; - self.identifier = profile.identifier; - self.UUID = profile.UUID; - self.name = profile.name; - self.bundleIdentifier = profile.bundleIdentifier; - self.teamIdentifier = profile.teamIdentifier; - self.creationDate = profile.creationDate; - self.expirationDate = profile.expirationDate; - self.entitlements = profile.entitlements; - self.certificates = profile.certificates; - self.deviceIDs = profile.deviceIDs; - self.isFreeProvisioningProfile = profile.isFreeProvisioningProfile; - self.data = profile.data; - return self; -} - -@end diff --git a/LCRootViewController.m b/LCRootViewController.m index bbb53ae..e83de3c 100644 --- a/LCRootViewController.m +++ b/LCRootViewController.m @@ -513,7 +513,8 @@ - (void)patchExecAndSignIfNeed:(NSIndexPath *)indexPath { // Sign app if JIT-less is set up if (LCUtils.certificateData) { - NSUInteger signID = LCUtils.certificateData.hash; + int signRevision = 1; + NSUInteger signID = LCUtils.certificateData.hash + signRevision; if ([info[@"LCJITLessSignID"] unsignedLongValue] != signID) { // We need to temporarily change bundle ID to LiveContainer to sign properly info[@"LCBundleIdentifier"] = info[@"CFBundleIdentifier"]; diff --git a/LCUtils.m b/LCUtils.m index 17366b0..c32ae68 100644 --- a/LCUtils.m +++ b/LCUtils.m @@ -1,7 +1,10 @@ #import "AltStoreCore/ALTSigner.h" -#import "AltStoreCore/ALTProvisioningProfileWrapper.h" #import "LCUtils.h" + #include +#include +#include +#include @implementation LCUtils @@ -33,18 +36,100 @@ + (NSData *)certificateData { return [NSUserDefaults.standardUserDefaults objectForKey:@"LCCertificateData"]; } ++ (void)removeCodeSignatureFromBundleURL:(NSURL *)appURL { + int32_t cpusubtype; + sysctlbyname("hw.cpusubtype", &cpusubtype, NULL, NULL, 0); + + NSDirectoryEnumerator *countEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:appURL includingPropertiesForKeys:@[NSURLIsRegularFileKey, NSURLFileSizeKey] + options:0 errorHandler:^BOOL(NSURL * _Nonnull url, NSError * _Nonnull error) { + if (error) { + NSLog(@"[Error] %@ (%@)", error, url); + return NO; + } + return YES; + }]; + + for (NSURL *fileURL in countEnumerator) { + NSNumber *isFile = nil; + if (![fileURL getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil] || !isFile.boolValue) { + continue; + } + + NSNumber *fileSize = nil; + [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil]; + if (fileSize.unsignedLongLongValue < 0x4000) { + continue; + } + + NSMutableData *data = [NSMutableData dataWithContentsOfURL:fileURL]; + const char *map = data.mutableBytes; + uint32_t magic = *(uint32_t *)map; + struct mach_header_64 *header = NULL; + + if (magic == FAT_CIGAM) { + // Find compatible slice + struct fat_header *fatHeader = (struct fat_header *)map; + struct fat_arch *arch = (struct fat_arch *)(map + sizeof(struct fat_header)); + struct fat_arch *chosenArch = NULL; + for (int i = 0; i < OSSwapInt32(fatHeader->nfat_arch); i++) { + if (OSSwapInt32(arch->cputype) == CPU_TYPE_ARM64) { + header = (struct mach_header_64 *)(map + OSSwapInt32(arch->offset)); + chosenArch = arch; + if (OSSwapInt32(arch->cpusubtype) == cpusubtype) { + break; + } + } + arch = (struct fat_arch *)((void *)arch + sizeof(struct fat_arch)); + } + if (header) { + // Extract slice + data = [data subdataWithRange:NSMakeRange(OSSwapInt32(chosenArch->offset), OSSwapInt32(chosenArch->size))].mutableCopy; + map = data.mutableBytes; + header = (struct mach_header_64 *)map; + } else { + continue; + } + } else if (magic == MH_MAGIC_64) { + header = (struct mach_header_64 *)map; + } + + if (!header || header->cputype != CPU_TYPE_ARM64 || header->filetype != MH_DYLIB) { + continue; + } + + uint8_t *imageHeaderPtr = (uint8_t *)header + sizeof(struct mach_header_64); + struct load_command *command = (struct load_command *)imageHeaderPtr; + for(int i = 0; i < header->ncmds > 0; i++) { + if (command->cmd == LC_CODE_SIGNATURE) { + struct linkedit_data_command *csCommand = (struct linkedit_data_command *)command; + void *csData = (void *)((uint8_t *)header + csCommand->dataoff); + // Nuke it. + NSLog(@"Removing code signature of %@", fileURL); + bzero(csData, csCommand->datasize); + [data writeToURL:fileURL atomically:YES]; + break; + } + command = (struct load_command *)((void *)command + command->cmdsize); + } + } +} + + (NSProgress *)signAppBundle:(NSString *)path completionHandler:(void (^)(BOOL success, NSError *error))completionHandler { NSError *error; // Remove PlugIns folder [NSFileManager.defaultManager removeItemAtPath:[path stringByAppendingPathComponent:@"PlugIns"] error:nil]; + // Remove code signature from all library files + NSURL *bundleURL = [NSURL fileURLWithPath:path]; + [self removeCodeSignatureFromBundleURL:bundleURL]; + // I'm too lazy to reimplement signer, so let's borrow everything from SideStore // For sure this will break in the future as SideStore team planned to rewrite it NSURL *appGroupPath = [NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:self.appGroupID]; NSURL *storeBundlePath = [appGroupPath URLByAppendingPathComponent:@"Apps/com.SideStore.SideStore/App.app"]; NSURL *storeFrameworksPath = [storeBundlePath URLByAppendingPathComponent:@"Frameworks"]; - NSURL *storeProfilePath = [storeBundlePath URLByAppendingPathComponent:@"embedded.mobileprovision"]; + NSURL *profilePath = [NSBundle.mainBundle URLForResource:@"embedded" withExtension:@"mobileprovision"]; // Load libraries from Documents, yeah [[NSBundle bundleWithURL:[storeFrameworksPath URLByAppendingPathComponent:@"OpenSSL.framework"]] loadAndReturnError:&error]; @@ -64,16 +149,13 @@ + (NSProgress *)signAppBundle:(NSString *)path completionHandler:(void (^)(BOOL } ALTCertificate *cert = [[NSClassFromString(@"ALTCertificate") alloc] initWithP12Data:self.certificateData password:@""]; - ALTProvisioningProfile *profile = [[NSClassFromString(@"ALTProvisioningProfile") alloc] initWithURL:storeProfilePath]; - - ALTProvisioningProfileWrapper *profileWrapper = [[ALTProvisioningProfileWrapper alloc] initWithProfile:profile]; - profileWrapper.bundleIdentifier = NSBundle.mainBundle.bundleIdentifier; + ALTProvisioningProfile *profile = [[NSClassFromString(@"ALTProvisioningProfile") alloc] initWithURL:profilePath]; ALTAccount *account = [NSClassFromString(@"ALTAccount") new]; ALTTeam *team = [[NSClassFromString(@"ALTTeam") alloc] initWithName:@"" identifier:@"" /*profile.teamIdentifier*/ type:ALTTeamTypeUnknown account:account]; ALTSigner *signer = [[NSClassFromString(@"ALTSigner") alloc] initWithTeam:team certificate:cert]; - return [signer signAppAtURL:[NSURL fileURLWithPath:path] provisioningProfiles:@[(id)profileWrapper] completionHandler:completionHandler]; + return [signer signAppAtURL:[NSURL fileURLWithPath:path] provisioningProfiles:@[(id)profile] completionHandler:completionHandler]; } #pragma mark Setup diff --git a/Makefile b/Makefile index e1b5b34..36f2897 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ CONFIG_BRANCH = $(shell git branch --show-current) CONFIG_COMMIT = $(shell git log --oneline | sed '2,10000000d' | cut -b 1-7) # Build the UI library -LiveContainerUI_FILES = LCAppDelegate.m LCJITLessSetupViewController.m LCRootViewController.m LCUtils.m MBRoundProgressView.m unarchive.m AppInfo.m AltStoreCore/ALTProvisioningProfileWrapper.m +LiveContainerUI_FILES = LCAppDelegate.m LCJITLessSetupViewController.m LCRootViewController.m LCUtils.m MBRoundProgressView.m unarchive.m AppInfo.m LiveContainerUI_CFLAGS = \ -fobjc-arc \ -DCONFIG_TYPE=\"$(CONFIG_TYPE)\" \