diff --git a/Clutch/BundleDumpOperation.m b/Clutch/BundleDumpOperation.m index 5d643d5e..ffba2911 100644 --- a/Clutch/BundleDumpOperation.m +++ b/Clutch/BundleDumpOperation.m @@ -181,90 +181,89 @@ - (void)main { #pragma mark "stripping" headers in FAT binary if ([_headersToStrip count] > 0) { NSFileHandle *_dumpHandle = [[NSFileHandle alloc]initWithFileDescriptor:fileno(fopen(_binaryDumpPath.UTF8String, "r+"))]; - - NSData *buffer = [_dumpHandle readDataOfLength:4096]; + uint32_t magic = [_dumpHandle intAtOffset:0]; + NSData *buffer = [_dumpHandle readDataOfLength:4096]; + + [_dumpHandle closeFile]; + + bool shouldSwap = magic == MH_CIGAM || magic == MH_CIGAM_64 || magic == FAT_CIGAM; +#define SWAP(NUM) (shouldSwap ? CFSwapInt32(NUM) : NUM) + NSMutableArray* _headersToKeep = [NSMutableArray new]; struct fat_header fat = *(struct fat_header *)buffer.bytes; - fat.nfat_arch = CFSwapInt32(fat.nfat_arch); - - //bunch of zeroes - char data[20]; - memset(data,'\0',sizeof(data)); + fat.nfat_arch = SWAP(fat.nfat_arch); int offset = sizeof(struct fat_header); for (int i = 0; i < fat.nfat_arch; i++) { struct fat_arch arch = *(struct fat_arch *)([buffer bytes] + offset); - NSNumber* archOffset = [NSNumber numberWithUnsignedInt:CFSwapInt32(arch.offset)]; - NSLog(@"current offset %u", CFSwapInt32(arch.offset)); + NSNumber* archOffset = [NSNumber numberWithUnsignedInt:SWAP(arch.offset)]; + NSLog(@"current offset %u", SWAP(arch.offset)); if ([_headersToStrip containsObject:archOffset]) { - NSLog(@"arch to strip %u %u", CFSwapInt32(arch.cpusubtype), CFSwapInt32(arch.cputype)); + NSLog(@"arch to strip %u %u", SWAP(arch.cpusubtype), SWAP(arch.cputype)); } else { NSValue* archValue = [NSValue value:&arch withObjCType:@encode(struct fat_arch)]; [_headersToKeep addObject:archValue]; - //NSLog(@"storing the arch we want to keep %u", CFSwapInt32(arch.cpusubtype)); + NSLog(@"storing the arch we want to keep %u", SWAP(arch.cpusubtype)); } - - [_dumpHandle replaceBytesInRange:NSMakeRange(offset, sizeof(struct fat_arch)) withBytes:&data]; //blank all the archs offset += sizeof(struct fat_arch); } +#pragma mark lipo ftw + + [[NSFileManager defaultManager]moveItemAtPath:_binaryDumpPath toPath:[_binaryDumpPath stringByAppendingPathExtension:@"fatty"] error:nil]; + NSFileHandle *_fattyHandle = [[NSFileHandle alloc]initWithFileDescriptor:fileno(fopen([_binaryDumpPath stringByAppendingPathExtension:@"fatty"].UTF8String, "r+"))]; + + [[NSFileManager defaultManager] createFileAtPath:_binaryDumpPath contents:nil attributes:nil]; + _dumpHandle = [[NSFileHandle alloc]initWithFileDescriptor:fileno(fopen(_binaryDumpPath.UTF8String, "r+"))]; + + [_dumpHandle replaceBytesInRange:NSMakeRange(0, sizeof(uint32_t)) withBytes:&magic]; + //skip 4 bytes for magic, 4 bytes of nfat_arch - uint32_t nfat_arch = CFSwapInt32([_headersToKeep count]); + uint32_t nfat_arch = SWAP([_headersToKeep count]); [_dumpHandle replaceBytesInRange:NSMakeRange(sizeof(uint32_t), sizeof(uint32_t)) withBytes:&nfat_arch]; - //NSLog(@"changing nfat_arch to %u %u", nfat_arch, CFSwapInt32(nfat_arch)); - + NSLog(@"changing nfat_arch to %u", SWAP(nfat_arch)); offset = sizeof(struct fat_header); - for (NSValue* archValue in _headersToKeep) { + for (int i = 0,macho_offset = 0; i < _headersToKeep.count; i++) { + NSValue* archValue = _headersToKeep[i]; struct fat_arch keepArch; [archValue getValue:&keepArch]; - NSLog(@"headers to keep: %u %u", CFSwapInt32(keepArch.cpusubtype), CFSwapInt32(keepArch.cputype)); + NSLog(@"headers to keep: %u %u", SWAP(keepArch.cpusubtype), SWAP(keepArch.cputype)); + + int origOffset = SWAP(keepArch.offset); + + if (!macho_offset) { + macho_offset = pow(2.0, SWAP(keepArch.align)); + } + + keepArch.offset = SWAP(macho_offset); + + [_fattyHandle seekToFileOffset:origOffset]; + + NSData *machOData = [_fattyHandle readDataOfLength:SWAP(keepArch.size)]; + [_dumpHandle replaceBytesInRange:NSMakeRange(offset, sizeof(struct fat_arch)) withBytes:&keepArch]; + [_dumpHandle replaceBytesInRange:NSMakeRange(macho_offset, SWAP(keepArch.size)) withBytes:[machOData bytes]]; offset += sizeof(struct fat_arch); + macho_offset += SWAP(keepArch.size); } + + [_dumpHandle closeFile]; + [_fattyHandle closeFile]; + + [[NSFileManager defaultManager]removeItemAtPath:[_binaryDumpPath stringByAppendingPathExtension:@"fatty"] error:nil]; VERBOSE(@"Finished 'stripping' binary %@", originalBinary); VERBOSE(@"Note: This binary will be missing some undecryptable architectures\n"); - - - [_dumpHandle closeFile]; - } + } #pragma mark checking if everything's fine if (dumpCount == (numHeaders-_headersToStrip.count)) { - /* - - // codesign properly - - NSLog(@"extracting entitlements"); - - NSString *entitlementsPath = [_binaryDumpPath stringByAppendingPathExtension:@"plist"]; - - FILE *fp = fopen(entitlementsPath.UTF8String , "r+"); - - char entitlementsArgv[] = {[[NSProcessInfo processInfo].arguments[0] UTF8String], - "-e", - originalBinary.binaryPath.UTF8String, - NULL}; - - int result = ldid_main(3, entitlementsArgv, fp); - - NSLog(@"entitlements ok"); - - fclose(fp); - - char *codesignArgv[] = {[[NSProcessInfo processInfo].arguments[0] UTF8String], - [@"-S" stringByAppendingString:entitlementsPath].UTF8String, - _binaryDumpPath.UTF8String, - NULL}; - - result = ldid_main(3, codesignArgv, fp);*/ - NSString *_localPath = [originalBinary.binaryPath stringByReplacingOccurrencesOfString:_application.bundleContainerURL.path withString:@""]; _localPath = [_application.zipPrefix stringByAppendingPathComponent:_localPath]; diff --git a/Clutch/Clutch-Prefix.pch b/Clutch/Clutch-Prefix.pch index c1d7448a..2cd100fc 100644 --- a/Clutch/Clutch-Prefix.pch +++ b/Clutch/Clutch-Prefix.pch @@ -21,7 +21,7 @@ #import #endif -#define CLUTCH_VERSION @"2.0 RC7" +#define CLUTCH_VERSION @"2.0 RC8" # define SUCCESS(M, ...) fprintf(stderr, "\033[1;35m%s\033[0m\n",[[NSString stringWithFormat:M, ##__VA_ARGS__] UTF8String]); # define SUCCESS_OUT(M, ...) fprintf(stdout, "\033[1;35m%s\033[0m\n",[[NSString stringWithFormat:M, ##__VA_ARGS__] UTF8String]); diff --git a/Clutch/Makefile b/Clutch/Makefile index ac0daf68..9b84628d 100644 --- a/Clutch/Makefile +++ b/Clutch/Makefile @@ -1,10 +1,11 @@ # Target specific variables TARGET := clutch +IPHONEOS_DEPLOYMENT_TARGET = 6.0 ENTITLEMENTS := Clutch.entitlements PCH := Clutch-Prefix.pch SRC_DIRS := MiniZip CFLAGS += -fmodules -fobjc-arc -I.. -LDFLAGS += -lz -F/System/Library/PrivateFrameworks -F /System/Library/Frameworks -framework AppSupport -framework Foundation -framework MobileCoreServices +LDFLAGS += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) -lz -F/System/Library/PrivateFrameworks -F /System/Library/Frameworks -framework AppSupport -framework Foundation -framework MobileCoreServices LDLIBS = -lncurses # Macro to find all source files in a directory @@ -24,7 +25,7 @@ CLANGXX := $(XCRUN) clang++ ARCHFLAGS := -arch armv7 -arch armv7s -arch arm64 CC := $(CLANG) $(ARCHFLAGS) LD := $(CLANGXX) $(ARCHFLAGS) -CFLAGS += -include $(PCH) -I. $(foreach sd,$(SRC_DIRS),-I$(sd)) -UNDEBUG +CFLAGS += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) -include $(PCH) -I. $(foreach sd,$(SRC_DIRS),-I$(sd)) -UNDEBUG CODESIGN := $(XCRUN) codesign CSFLAGS := -fs-