diff --git a/Exploits/fastPathSign/src/adhoc.h b/Exploits/fastPathSign/src/adhoc.h deleted file mode 100644 index 6a491c1..0000000 --- a/Exploits/fastPathSign/src/adhoc.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -int binary_sign_adhoc(const char *path, bool preserveMetadata); \ No newline at end of file diff --git a/Exploits/fastPathSign/src/codesign.h b/Exploits/fastPathSign/src/codesign.h new file mode 100644 index 0000000..1432272 --- /dev/null +++ b/Exploits/fastPathSign/src/codesign.h @@ -0,0 +1,4 @@ +#import +#import + +int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements); \ No newline at end of file diff --git a/Exploits/fastPathSign/src/adhoc.m b/Exploits/fastPathSign/src/codesign.m similarity index 82% rename from Exploits/fastPathSign/src/adhoc.m rename to Exploits/fastPathSign/src/codesign.m index 1b37404..5d01c04 100644 --- a/Exploits/fastPathSign/src/adhoc.m +++ b/Exploits/fastPathSign/src/codesign.m @@ -89,7 +89,7 @@ extern const CFStringRef kSecCodeInfoResourceDirectory; /* Internal */ } #endif -int binary_sign_adhoc(const char *path, bool preserveMetadata) +int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements) { NSString *filePath = [NSString stringWithUTF8String:path]; OSStatus status = 0; @@ -99,8 +99,31 @@ int binary_sign_adhoc(const char *path, bool preserveMetadata) SecIdentityRef identity = (SecIdentityRef)kCFNull; NSMutableDictionary* parameters = [[NSMutableDictionary alloc] init]; parameters[(__bridge NSString*)kSecCodeSignerIdentity] = (__bridge id)identity; + uint64_t preserveMetadataFlags = 0; if (preserveMetadata) { - parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveEntitlements | kSecCSPreserveResourceRules); + preserveMetadataFlags = (kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveEntitlements | kSecCSPreserveResourceRules); + if (!customEntitlements) { + preserveMetadataFlags |= kSecCSPreserveEntitlements; + } + parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(preserveMetadataFlags); + } + + if (customEntitlements) { + NSError *error; + NSData *xmlData = [NSPropertyListSerialization dataWithPropertyList:customEntitlements format:NSPropertyListXMLFormat_v1_0 options:0 error:&error]; + if (!xmlData) { + NSLog(@"Failed to encode entitlements: %@", error); + return -1; + } + else { + // Super easy to use API, definitely not busted... + // Did I forget to mention it just segfaults if you don't add this prefix? + uint32_t entitlementsData[xmlData.length+8]; + entitlementsData[0] = OSSwapHostToBigInt32(0xFADE7171); + entitlementsData[1] = OSSwapHostToBigInt32(xmlData.length+8); + [xmlData getBytes:&entitlementsData[2] length:xmlData.length]; + parameters[(__bridge NSString*)kSecCodeSignerEntitlements] = [NSData dataWithBytes:entitlementsData length:xmlData.length+8]; + } } SecCodeSignerRef signerRef; @@ -137,4 +160,9 @@ int binary_sign_adhoc(const char *path, bool preserveMetadata) } return retval; +} + +NSDictionary *codesign_dump_entitlements(NSString *path) +{ + return nil; } \ No newline at end of file diff --git a/Exploits/fastPathSign/src/main.c b/Exploits/fastPathSign/src/main.m similarity index 75% rename from Exploits/fastPathSign/src/main.c rename to Exploits/fastPathSign/src/main.m index b9fc540..2dabe77 100644 --- a/Exploits/fastPathSign/src/main.c +++ b/Exploits/fastPathSign/src/main.m @@ -1,4 +1,4 @@ -#include "adhoc.h" +#include "codesign.h" #include "coretrust_bug.h" #include #include @@ -52,12 +52,22 @@ int apply_coretrust_bypass_wrapper(const char *inputPath, const char *outputPath int main(int argc, char *argv[]) { - if (argc != 2) return -1; + if (argc < 2) return -1; - char *machoPath = extract_preferred_slice(argv[1]); + char *input = argv[argc-1]; + + NSDictionary *customEntitlements = nil; + if (argc == 4) { + if (!strcmp(argv[1], "--entitlements")) { + NSString *entitlementsPath = [NSString stringWithUTF8String:argv[2]]; + customEntitlements = [NSDictionary dictionaryWithContentsOfFile:entitlementsPath]; + } + } + + char *machoPath = extract_preferred_slice(input); printf("Extracted best slice to %s\n", machoPath); - int r = binary_sign_adhoc(machoPath, true); + int r = codesign_sign_adhoc(machoPath, true, customEntitlements); if (r != 0) { printf("Failed adhoc signing (%d) Continuing anyways...\n", r); } @@ -72,8 +82,8 @@ int main(int argc, char *argv[]) { return -1; } - if (copyfile(machoPath, argv[1], 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) { - chmod(argv[1], 0755); + if (copyfile(machoPath, input, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) { + chmod(input, 0755); printf("Applied CoreTrust Bypass!\n"); } else { diff --git a/Makefile b/Makefile index f283912..1b2b67c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOPTARGETS := all clean -$(TOPTARGETS): pre_build make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e +$(TOPTARGETS): pre_build make_fastPathSign make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e pre_build: @rm -rf ./_build 2>/dev/null || true @@ -8,6 +8,8 @@ pre_build: make_external: +make_fastPathSign: + @$(MAKE) -C ./Exploits/fastPathSign $(MAKECMDGOALS) make_roothelper: @$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS) diff --git a/RootHelper/Makefile b/RootHelper/Makefile index aeb708b..f53fb33 100644 --- a/RootHelper/Makefile +++ b/RootHelper/Makefile @@ -1,14 +1,16 @@ TARGET := iphone:clang:16.4:14.0 ARCHS = arm64 +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign + include $(THEOS)/makefiles/common.mk TOOL_NAME = trollstorehelper -trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/adhoc.m +trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/codesign.m trollstorehelper_CFLAGS = -fobjc-arc -I../Shared $(shell pkg-config --cflags libcrypto) -Iexternal/include -I../Exploits/fastPathSign/src trollstorehelper_LDFLAGS = -Lexternal/lib -lcrypto -lchoma -trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist trollstorehelper_INSTALL_PATH = /usr/local/bin trollstorehelper_LIBRARIES = archive trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager diff --git a/RootHelper/external/lib/libchoma.a b/RootHelper/external/lib/libchoma.a index fdd802d..6048fae 100644 Binary files a/RootHelper/external/lib/libchoma.a and b/RootHelper/external/lib/libchoma.a differ diff --git a/RootHelper/main.m b/RootHelper/main.m index 89de375..4337fb6 100644 --- a/RootHelper/main.m +++ b/RootHelper/main.m @@ -11,7 +11,7 @@ #import #import #ifndef EMBEDDED_ROOT_HELPER -#import "adhoc.h" +#import "codesign.h" #import "coretrust_bug.h" #import #import @@ -398,45 +398,48 @@ int signApp(NSString* appPath) while(fileURL = [enumerator nextObject]) { NSString *filePath = fileURL.path; + NSLog(@"Checking %@", filePath); FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation); if (fat) { + NSLog(@"%@ is binary", filePath); // This is FAT or MachO, sign and apply CoreTrust bypass MachO *machoForExtraction = fat_find_preferred_slice(fat); if (machoForExtraction) { - NSLog(@"Starting signing of %@\n", filePath); NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; - MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND); MemoryStream *sliceStream = macho_get_stream(machoForExtraction); - memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream)); - memory_stream_free(sliceOutStream); + MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND); + if (sliceOutStream) { + memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream)); + memory_stream_free(sliceOutStream); - // Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy 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 - NSLog(@"[%@] Adhoc signing...", filePath); + NSLog(@"[%@] Adhoc signing...", filePath); - // First attempt ad hoc signing - int r = binary_sign_adhoc(tmpPath.fileSystemRepresentation, true); - if (r != 0) { - NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r); + // First attempt ad hoc signing + int r = codesign_sign_adhoc(tmpPath.fileSystemRepresentation, true, nil); + if (r != 0) { + NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r); + } + else { + NSLog(@"[%@] Adhoc signing worked!\n", filePath); + } + + NSLog(@"[%@] Applying CoreTrust bypass...", filePath); + r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation); + if (r == 0) { + NSLog(@"[%@] Applied CoreTrust bypass!", filePath); + } + else { + NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath); + fat_free(fat); + return 175; + } + + // tempFile is now signed, overwrite original file at filePath with it + [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; + [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:nil]; } - else { - NSLog(@"[%@] Adhoc signing worked!\n", filePath); - } - - NSLog(@"[%@] Applying CoreTrust bypass...", filePath); - r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation); - if (r == 0) { - NSLog(@"[%@] Applied CoreTrust bypass!", filePath); - } - else { - NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath); - fat_free(fat); - return 175; - } - - // tempFile is now signed, overwrite original file at filePath with it - [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; - [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:nil]; } fat_free(fat); } diff --git a/TrollHelper/Makefile b/TrollHelper/Makefile index ba488f3..deeb2ed 100644 --- a/TrollHelper/Makefile +++ b/TrollHelper/Makefile @@ -2,6 +2,9 @@ export EMBEDDED_ROOT_HELPER ?= 0 TARGET := iphone:clang:16.4:14.0 INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper +ARCHS = arm64 + +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign include $(THEOS)/makefiles/common.mk @@ -11,7 +14,7 @@ TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared -TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +TrollStorePersistenceHelper_CODESIGN_FLAGS = --entitlements entitlements.plist ifeq ($(EMBEDDED_ROOT_HELPER),1) TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1 diff --git a/TrollStore/Makefile b/TrollStore/Makefile index ee5038f..d0c62e2 100644 --- a/TrollStore/Makefile +++ b/TrollStore/Makefile @@ -1,5 +1,8 @@ TARGET := iphone:clang:16.4:14.0 INSTALL_TARGET_PROCESSES = TrollStore +ARCHS = arm64 + +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign include $(THEOS)/makefiles/common.mk @@ -10,6 +13,6 @@ TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager TrollStore_LIBRARIES = archive TrollStore_CFLAGS = -fobjc-arc -I../Shared -TrollStore_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +TrollStore_CODESIGN_FLAGS = --entitlements entitlements.plist include $(THEOS_MAKE_PATH)/application.mk