From 5c5600e4bf514d1bb74a12be7ef5e6acc05743fb Mon Sep 17 00:00:00 2001 From: Anton Titkov Date: Fri, 17 Apr 2015 19:17:36 +0300 Subject: [PATCH] Clutch 2.0 RC --- Clutch.xcodeproj/project.pbxproj | 26 +++---- Clutch/Application.h | 10 --- Clutch/Application.m | 2 +- Clutch/ApplicationsManager.m | 8 +-- Clutch/Clutch-Prefix.pch | 2 +- Clutch/Device.h | 2 +- Clutch/Device.m | 2 +- Clutch/FinalizeDumpOperation.m | 6 +- Clutch/Framework64Dumper.m | 67 ++++++++++--------- Clutch/FrameworkDumper.m | 8 --- ...{Framework32Dumper.h => FrameworkLoader.h} | 4 +- ...{Framework32Dumper.m => FrameworkLoader.m} | 19 ++++-- Clutch/ZipOperation.m | 4 +- Clutch/main.m | 4 +- Clutch/scinfo.h | 2 +- Clutch/scinfo.m | 4 +- README.md | 4 +- 17 files changed, 88 insertions(+), 86 deletions(-) rename Clutch/{Framework32Dumper.h => FrameworkLoader.h} (86%) rename Clutch/{Framework32Dumper.m => FrameworkLoader.m} (93%) diff --git a/Clutch.xcodeproj/project.pbxproj b/Clutch.xcodeproj/project.pbxproj index 061ec615..dc8c18bc 100644 --- a/Clutch.xcodeproj/project.pbxproj +++ b/Clutch.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ 324EA63E1A89260A00844540 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 324EA63D1A89260A00844540 /* MobileCoreServices.framework */; }; 324EA6421A8926DC00844540 /* Application.m in Sources */ = {isa = PBXBuildFile; fileRef = 324EA6411A8926DC00844540 /* Application.m */; }; 3258FD641A90AAED007C2E66 /* Device.m in Sources */ = {isa = PBXBuildFile; fileRef = 3258FD631A90AAED007C2E66 /* Device.m */; }; - 326ABC8A1AD2B94000B21FCC /* Framework32Dumper.m in Sources */ = {isa = PBXBuildFile; fileRef = 326ABC891AD2B94000B21FCC /* Framework32Dumper.m */; }; + 326ABC8A1AD2B94000B21FCC /* FrameworkLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 326ABC891AD2B94000B21FCC /* FrameworkLoader.m */; }; 3274B9581ABEA6E100964049 /* ARMDumper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3274B9571ABEA6E100964049 /* ARMDumper.m */; }; 3274B9601ABEB00400964049 /* ARM64Dumper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3274B95F1ABEB00400964049 /* ARM64Dumper.m */; }; 3277BF991ACD50BD0060935A /* FrameworkDumper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3277BF981ACD50BD0060935A /* FrameworkDumper.m */; }; @@ -64,8 +64,8 @@ 324EA6471A892AAD00844540 /* FBApplicationInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBApplicationInfo.h; sourceTree = ""; }; 3258FD621A90AAED007C2E66 /* Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Device.h; sourceTree = ""; }; 3258FD631A90AAED007C2E66 /* Device.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Device.m; sourceTree = ""; }; - 326ABC881AD2B94000B21FCC /* Framework32Dumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Framework32Dumper.h; sourceTree = ""; }; - 326ABC891AD2B94000B21FCC /* Framework32Dumper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Framework32Dumper.m; sourceTree = ""; }; + 326ABC881AD2B94000B21FCC /* FrameworkLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameworkLoader.h; sourceTree = ""; }; + 326ABC891AD2B94000B21FCC /* FrameworkLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FrameworkLoader.m; sourceTree = ""; }; 3274B9551ABEA60500964049 /* BinaryDumpProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BinaryDumpProtocol.h; sourceTree = ""; }; 3274B9561ABEA6E100964049 /* ARMDumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMDumper.h; sourceTree = ""; }; 3274B9571ABEA6E100964049 /* ARMDumper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARMDumper.m; sourceTree = ""; }; @@ -198,26 +198,26 @@ 324EA62D1A89258000844540 /* Supporting Files */ = { isa = PBXGroup; children = ( - ADE1ED301AD1636D00398728 /* ProgressBar.h */, - ADE1ED311AD1636D00398728 /* ProgressBar.m */, - 328CCB711AD004FF00B21225 /* NSTask.h */, 328CCB3D1ACED00600B21225 /* SCInfoBuilder.h */, 328CCB3E1ACED00600B21225 /* SCInfoBuilder.m */, - 328CCB3B1ACECF5800B21225 /* README.md */, + 324EA6431A89270D00844540 /* Clutch.entitlements */, + 32BC93F11A8F3C0B00805D14 /* mach_vm.h */, + 328CCB711AD004FF00B21225 /* NSTask.h */, + ADE1ED301AD1636D00398728 /* ProgressBar.h */, + ADE1ED311AD1636D00398728 /* ProgressBar.m */, 328CCB351ACECEB500B21225 /* scinfo.h */, 328CCB361ACECEB500B21225 /* scinfo.m */, 32BC93E41A8E0E8B00805D14 /* sha1.c */, 32BC93E51A8E0E8B00805D14 /* sha1.h */, - 323C86AB1AC03E3F008949F2 /* .gitignore */, - 32BC93F11A8F3C0B00805D14 /* mach_vm.h */, 3282BE041A8D9A9100E5068A /* optool */, 32EFB6CD1A8A4F06005BB56C /* Zip */, 32FB77B11A89DC6600BB5ABC /* GBCLI */, 324EA6471A892AAD00844540 /* FBApplicationInfo.h */, 324EA6341A89258000844540 /* Clutch-Prefix.pch */, - 324EA6431A89270D00844540 /* Clutch.entitlements */, 328359DC1ACC118D003587F3 /* NSFileHandle+Private.h */, 328359DD1ACC118D003587F3 /* NSFileHandle+Private.m */, + 328CCB3B1ACECF5800B21225 /* README.md */, + 323C86AB1AC03E3F008949F2 /* .gitignore */, ); name = "Supporting Files"; sourceTree = ""; @@ -310,10 +310,10 @@ 3274B95F1ABEB00400964049 /* ARM64Dumper.m */, 3277BF971ACD50BD0060935A /* FrameworkDumper.h */, 3277BF981ACD50BD0060935A /* FrameworkDumper.m */, - 326ABC881AD2B94000B21FCC /* Framework32Dumper.h */, - 326ABC891AD2B94000B21FCC /* Framework32Dumper.m */, 328CCB381ACECF4100B21225 /* Framework64Dumper.h */, 328CCB391ACECF4100B21225 /* Framework64Dumper.m */, + 326ABC881AD2B94000B21FCC /* FrameworkLoader.h */, + 326ABC891AD2B94000B21FCC /* FrameworkLoader.m */, ); name = Dumpers; sourceTree = ""; @@ -429,7 +429,7 @@ 3282BB7C1A8C920D00E5068A /* FinalizeDumpOperation.m in Sources */, 32FB77C11A89F09300BB5ABC /* ClutchBundle.m in Sources */, 324EA6331A89258000844540 /* main.m in Sources */, - 326ABC8A1AD2B94000B21FCC /* Framework32Dumper.m in Sources */, + 326ABC8A1AD2B94000B21FCC /* FrameworkLoader.m in Sources */, 32FB77C41A89F13000BB5ABC /* Binary.m in Sources */, 323C86B11AC05AE4008949F2 /* Dumper.m in Sources */, 328359DE1ACC118D003587F3 /* NSFileHandle+Private.m in Sources */, diff --git a/Clutch/Application.h b/Clutch/Application.h index b8b14611..2a320df0 100755 --- a/Clutch/Application.h +++ b/Clutch/Application.h @@ -11,16 +11,6 @@ #import "Extension.h" #import "Framework.h" -@class Application; - -@protocol ApplicationDelegate - -- (void)crackingProcessStarted:(Application*)app; -- (void)application:(Application *)app crackingProcessStatusChanged:(NSString *)status progress:(float)progress; -- (void)crackingProcessFinished:(Application *)app; - -@end - @interface Application : ClutchBundle @property (readonly) BOOL hasAppleWatchApp; diff --git a/Clutch/Application.m b/Clutch/Application.m index 30b55a8c..53eb9238 100644 --- a/Clutch/Application.m +++ b/Clutch/Application.m @@ -137,7 +137,7 @@ - (void)dumpToDirectoryURL:(NSURL *)directoryURL onlyBinaries:(BOOL)yrn [self prepareForDump]; - // NSLog(@"SCInfo SINF for %@:\n %@",self,[SCInfoBuilder parseOriginaleSinfForBundle:self]); + NSLog(@"SCInfo SINF for %@:\n %@",self,[SCInfoBuilder parseOriginaleSinfForBundle:self]); [[NSFileManager defaultManager]createDirectoryAtPath:_workingPath withIntermediateDirectories:YES attributes:nil error:nil]; diff --git a/Clutch/ApplicationsManager.m b/Clutch/ApplicationsManager.m index 55207201..14a7fcde 100644 --- a/Clutch/ApplicationsManager.m +++ b/Clutch/ApplicationsManager.m @@ -7,7 +7,7 @@ // #define applistCachePath @"/etc/applist-cache.clutch" -#define crackedAppPath @"/etc/cracked.clutch" +#define dumpedAppPath @"/etc/dumped.clutch" #import #import "ApplicationsManager.h" @@ -128,10 +128,10 @@ - (NSDictionary *)installedApps return [self _allApplications]; } -- (NSArray *)crackedApps +- (NSArray *)dumpedApps { - NSString *crackedPath = @""; //[NSString stringWithFormat:@"%@/", [[Preferences sharedInstance] ipaDirectory]]; - NSArray *array=[[NSArray alloc]initWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:crackedPath error:nil]]; + NSString *dumpedPath = @""; //[NSString stringWithFormat:@"%@/", [[Preferences sharedInstance] ipaDirectory]]; + NSArray *array=[[NSArray alloc]initWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:dumpedPath error:nil]]; NSMutableArray *paths=[NSMutableArray new]; diff --git a/Clutch/Clutch-Prefix.pch b/Clutch/Clutch-Prefix.pch index f924177c..51656f40 100644 --- a/Clutch/Clutch-Prefix.pch +++ b/Clutch/Clutch-Prefix.pch @@ -7,7 +7,7 @@ #import #endif -#define CLUTCH_VERSION @"2.0 PB4" +#define CLUTCH_VERSION @"2.0 RC" #ifdef DEBUG # define FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // shortened path of __FILE__ is there is one diff --git a/Clutch/Device.h b/Clutch/Device.h index b0df055f..3cbd1ead 100644 --- a/Clutch/Device.h +++ b/Clutch/Device.h @@ -1,6 +1,6 @@ // // Device.h -// CrackAddict +// Clutch // // Created by Zorro on 14/11/13. // Copyright (c) 2013 AppAddict. All rights reserved. diff --git a/Clutch/Device.m b/Clutch/Device.m index c18353fd..cd8fcca6 100644 --- a/Clutch/Device.m +++ b/Clutch/Device.m @@ -1,6 +1,6 @@ // // Device.m -// CrackAddict +// Clutch // // Created by Zorro on 14/11/13. // Copyright (c) 2013 AppAddict. All rights reserved. diff --git a/Clutch/FinalizeDumpOperation.m b/Clutch/FinalizeDumpOperation.m index 5b638aec..25831945 100644 --- a/Clutch/FinalizeDumpOperation.m +++ b/Clutch/FinalizeDumpOperation.m @@ -155,11 +155,11 @@ - (void)main { // remove .ipa if failed [[NSFileManager defaultManager]removeItemAtPath:[_application.workingPath stringByAppendingPathComponent:_zipFilename] error:nil]; }else { - [[NSFileManager defaultManager] createDirectoryAtPath:@"/private/var/mobile/Documents/Cracked" withIntermediateDirectories:YES attributes:nil error:nil]; - [[NSFileManager defaultManager]moveItemAtPath:[_application.workingPath stringByAppendingPathComponent:_zipFilename] toPath:[@"/private/var/mobile/Documents/Cracked" stringByAppendingPathComponent:_zipFilename] error:nil]; + [[NSFileManager defaultManager] createDirectoryAtPath:@"/private/var/mobile/Documents/Dumped" withIntermediateDirectories:YES attributes:nil error:nil]; + [[NSFileManager defaultManager]moveItemAtPath:[_application.workingPath stringByAppendingPathComponent:_zipFilename] toPath:[@"/private/var/mobile/Documents/Dumped" stringByAppendingPathComponent:_zipFilename] error:nil]; } - gbprintln(@"%@: %@",status?@"DONE":@"FAILED",status?[@"/private/var/mobile/Documents/Cracked" stringByAppendingPathComponent:_zipFilename]:_application); + gbprintln(@"%@: %@",status?@"DONE":@"FAILED",status?[@"/private/var/mobile/Documents/Dumped" stringByAppendingPathComponent:_zipFilename]:_application); // Do the main work of the operation here. [self completeOperation]; diff --git a/Clutch/Framework64Dumper.m b/Clutch/Framework64Dumper.m index 990926d1..5c9afcc2 100644 --- a/Clutch/Framework64Dumper.m +++ b/Clutch/Framework64Dumper.m @@ -8,14 +8,7 @@ #import "Framework64Dumper.h" #import "Device.h" -#import -#import -#import -#import -#import -#import -#import -#import +#import @implementation Framework64Dumper @@ -134,34 +127,45 @@ - (BOOL)dumpBinary DumperLog(@"pages == 0"); return NO; } + + [newFileHandle closeFile]; - [newFileHandle seekToFileOffset:_thinHeader.offset]; + [self.originalFileHandle closeFile]; - void * handle = dlopen(swappedBinaryPath.UTF8String, RTLD_LAZY); + extern char **environ; + posix_spawnattr_t attr; - uint32_t imageCount = _dyld_image_count(); - uint32_t dyldIndex = -1; - for (uint32_t idx = 0; idx < imageCount; idx++) { - NSString *dyldPath = [NSString stringWithUTF8String:_dyld_get_image_name(idx)]; - - if ([swappedBinaryPath.lastPathComponent isEqualToString:dyldPath.lastPathComponent]) { - dyldIndex = idx; - break; - } - } + pid_t pid; - if (dyldIndex == -1) { - DumperLog(@"dlopen error: %s",dlerror()); - dlclose(handle); - return NO; - } + char *argv[] = {[[NSProcessInfo processInfo].arguments[0] UTF8String], + "-f", + swappedBinaryPath.UTF8String, + binaryDumpPath.UTF8String, + [NSString stringWithFormat:@"%u",(crypt.cryptsize + crypt.cryptoff)].UTF8String, + [NSString stringWithFormat:@"%u",pages].UTF8String, + [NSString stringWithFormat:@"%u",_thinHeader.header.ncmds].UTF8String, + [NSString stringWithFormat:@"%u",_thinHeader.offset].UTF8String, + NULL}; + + posix_spawnattr_init (&attr); + + size_t ocount = 0; - intptr_t dyldPointer = _dyld_get_image_vmaddr_slide(dyldIndex); + cpu_type_t cpu_type = CPU_TYPE_ARM64; - BOOL dumpResult = [self _dumpToFileHandle:newFileHandle withEncryptionInfoCommand:(crypt.cryptsize + crypt.cryptoff) pages:pages fromPort:mach_task_self() pid:[NSProcessInfo processInfo].processIdentifier aslrSlide:dyldPointer]; + posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount); - if (dlclose(handle)) { - DumperLog(@"dlclose error: %s",dlerror()); + int dumpResult = posix_spawnp(&pid, argv[0], NULL, &attr, argv, environ); + + if (dumpResult == 0) { + DumperDebugLog(@"Child pid: %i", pid); + if (waitpid(pid, &dumpResult, 0) != -1) { + DumperDebugLog(@"Child exited with status %i", dumpResult); + } else { + perror("waitpid"); + } + } else { + DumperDebugLog(@"posix_spawn: %s", strerror(dumpResult)); } if (![swappedBinaryPath isEqualToString:_originalBinary.binaryPath]) @@ -173,7 +177,10 @@ - (BOOL)dumpBinary if (![newSupf isEqualToString:_originalBinary.supfPath]) [[NSFileManager defaultManager]removeItemAtPath:newSupf error:nil]; - return dumpResult; + if (dumpResult == 0) + return YES; + + return NO; } @end diff --git a/Clutch/FrameworkDumper.m b/Clutch/FrameworkDumper.m index 1020404f..0bd1d6f1 100644 --- a/Clutch/FrameworkDumper.m +++ b/Clutch/FrameworkDumper.m @@ -8,14 +8,6 @@ #import "FrameworkDumper.h" #import "Device.h" -#import -#import -#import -#import -#import -#import -#import -#import #import @implementation FrameworkDumper diff --git a/Clutch/Framework32Dumper.h b/Clutch/FrameworkLoader.h similarity index 86% rename from Clutch/Framework32Dumper.h rename to Clutch/FrameworkLoader.h index 433d4788..a79eca9c 100644 --- a/Clutch/Framework32Dumper.h +++ b/Clutch/FrameworkLoader.h @@ -1,5 +1,5 @@ // -// Framework32Dumper.h +// FrameworkLoader.h // Clutch // // Created by Anton Titkov on 06.04.15. @@ -8,7 +8,7 @@ #import "Dumper.h" -@interface Framework32Dumper : Dumper +@interface FrameworkLoader : Dumper @property (assign) uint32_t ncmds; @property (assign) uint32_t offset; diff --git a/Clutch/Framework32Dumper.m b/Clutch/FrameworkLoader.m similarity index 93% rename from Clutch/Framework32Dumper.m rename to Clutch/FrameworkLoader.m index bd15259d..bcd7f43f 100644 --- a/Clutch/Framework32Dumper.m +++ b/Clutch/FrameworkLoader.m @@ -1,12 +1,12 @@ // -// Framework32Dumper.m +// FrameworkLoader.m // Clutch // // Created by Anton Titkov on 06.04.15. // // -#import "Framework32Dumper.h" +#import "FrameworkLoader.h" #import "Device.h" #import #import @@ -17,11 +17,17 @@ #import #import -@implementation Framework32Dumper +@interface FrameworkLoader () +{ + uint32_t _dyldImageIndex; +} +@end + +@implementation FrameworkLoader - (cpu_type_t)supportedCPUType { - return CPU_TYPE_ARM; + return CPU_TYPE_ARM | CPU_TYPE_ARM64; } - (BOOL)dumpBinary { @@ -53,6 +59,8 @@ - (BOOL)dumpBinary { return NO; } + _dyldImageIndex = dyldIndex; + intptr_t dyldPointer = _dyld_get_image_vmaddr_slide(dyldIndex); BOOL dumpResult = [self _dumpToFileHandle:newFileHandle withEncryptionInfoCommand:self.encryptionInfoCommand pages:self.pages fromPort:mach_task_self() pid:[NSProcessInfo processInfo].processIdentifier aslrSlide:dyldPointer]; @@ -66,8 +74,9 @@ - (BOOL)_dumpToFileHandle:(NSFileHandle *)fileHandle withEncryptionInfoCommand:( { void *checksum = malloc(pages * 20); // 160 bits for each hash (SHA1) + const struct mach_header *image_header = _dyld_get_image_header(_dyldImageIndex); - uint32_t headerProgress = sizeof(struct mach_header); + uint32_t headerProgress = sizeof(image_header); uint32_t i_lcmd = 0; kern_return_t err; diff --git a/Clutch/ZipOperation.m b/Clutch/ZipOperation.m index c03299a0..f4351c44 100644 --- a/Clutch/ZipOperation.m +++ b/Clutch/ZipOperation.m @@ -86,7 +86,9 @@ - (void)main { } if (!_application.parentBundle && [[NSFileManager defaultManager]fileExistsAtPath:[_application.bundleContainerURL URLByAppendingPathComponent:@"iTunesMetadata.plist" isDirectory:NO].path]) { - [_archive addFileToZip:[_application.bundleContainerURL URLByAppendingPathComponent:@"iTunesMetadata.plist" isDirectory:NO].path newname:@"iTunesMetadata.plist"]; + + // skip iTunesMetadata + // [_archive addFileToZip:[_application.bundleContainerURL URLByAppendingPathComponent:@"iTunesMetadata.plist" isDirectory:NO].path newname:@"iTunesMetadata.plist"]; } NSDirectoryEnumerator *dirEnumerator = [NSFileManager.defaultManager enumeratorAtURL:_application.bundleURL includingPropertiesForKeys:@[NSURLNameKey,NSURLIsDirectoryKey] options:nil errorHandler:^BOOL(NSURL *url, NSError *error) { diff --git a/Clutch/main.m b/Clutch/main.m index 8e43a18a..8c526ed7 100644 --- a/Clutch/main.m +++ b/Clutch/main.m @@ -10,7 +10,7 @@ #import "GBCli.h" #import "ApplicationsManager.h" #import "sha1.h" -#import "Framework32Dumper.h" +#import "FrameworkLoader.h" int main (int argc, const char * argv[]) { @@ -83,7 +83,7 @@ int main (int argc, const char * argv[]) if (([arguments[1]isEqualToString:@"--fmwk-dump"]||[arguments[1]isEqualToString:@"-f"]) && (arguments.count == 8)) { - Framework32Dumper *fmwk = [Framework32Dumper new]; + FrameworkLoader *fmwk = [FrameworkLoader new]; fmwk.binPath = arguments[2]; fmwk.dumpPath = arguments[3]; diff --git a/Clutch/scinfo.h b/Clutch/scinfo.h index 15dc2fe4..7cd466ca 100755 --- a/Clutch/scinfo.h +++ b/Clutch/scinfo.h @@ -6,5 +6,5 @@ void *create_atom(char *name, int len, void *content); void *coalesced_atom(int amount, uint32_t name, ...); void *combine_atoms(char *name, int amount, ...); -void *generate_sinf(int appid, char *cracker_name, int vendorID); +void *generate_sinf(int appid, char *person_name, int vendorID); void *generate_supp(uint32_t *suppsize); \ No newline at end of file diff --git a/Clutch/scinfo.m b/Clutch/scinfo.m index c25df6e9..7fb0d1e2 100755 --- a/Clutch/scinfo.m +++ b/Clutch/scinfo.m @@ -106,7 +106,7 @@ Generates SC_Info keys (.sinf and .supp) } // generate a fake .sinf file -void *generate_sinf(int appid, char *cracker_name, int vendorID) +void *generate_sinf(int appid, char *person_name, int vendorID) { // sinf.schi.righ is an atom of several misc. fields related to the application void *fakerigh = coalesced_atom(10, *(uint32_t *)"righ", @@ -144,7 +144,7 @@ Generates SC_Info keys (.sinf and .supp) char *name = malloc(256); memset(name, 0x0, 256); - memcpy(name, cracker_name, strlen(cracker_name)); + memcpy(name, person_name, strlen(person_name)); void *fakename = create_atom("name", 256, name); free(name); diff --git a/README.md b/README.md index 5199951d..1a74e291 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ Clutch ------------ -Introducing *Clutch*, the fastest and most advanced cracking utility for the iPhone, iPod Touch, and iPad. +Introducing *Clutch*, the fastest and most advanced dumping utility for the iPhone, iPod Touch, and iPad. Works with all devices, iOS versions, architecture types, with most binaries. +This product is meant only for educational purposes and security research. + Current version: 2.0