Skip to content

Commit

Permalink
Fix invalid code signature caused by entitlements in frameworks
Browse files Browse the repository at this point in the history
Removed profile wrapper class as it's no longer used
  • Loading branch information
khanhduytran0 committed Apr 21, 2024
1 parent 5229b30 commit 018f22d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 70 deletions.
38 changes: 0 additions & 38 deletions AltStoreCore/ALTProvisioningProfileWrapper.h

This file was deleted.

23 changes: 0 additions & 23 deletions AltStoreCore/ALTProvisioningProfileWrapper.m

This file was deleted.

3 changes: 2 additions & 1 deletion LCRootViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"];
Expand Down
96 changes: 89 additions & 7 deletions LCUtils.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#import "AltStoreCore/ALTSigner.h"
#import "AltStoreCore/ALTProvisioningProfileWrapper.h"
#import "LCUtils.h"

#include <dlfcn.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include <sys/sysctl.h>

@implementation LCUtils

Expand Down Expand Up @@ -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];
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)\" \
Expand Down

0 comments on commit 018f22d

Please sign in to comment.