Skip to content

Commit

Permalink
more bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ttwj committed Jun 11, 2015
1 parent 132bee3 commit 47494cc
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 12 deletions.
1 change: 0 additions & 1 deletion Clutch/ARM64Dumper.m
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ - (BOOL)dumpBinary {

if ((err = task_for_pid(mach_task_self(), pid, &port) != KERN_SUCCESS)) {
ERROR(@"Could not obtain mach port, did you sign with proper entitlements?");
sleep(60);
goto gotofail;
}

Expand Down
4 changes: 3 additions & 1 deletion Clutch/ARMDumper.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,11 @@ - (BOOL)dumpBinary {
break;
}

NSLog(@"binary path %@", swappedBinaryPath);

// we need to have all of these
if (!foundCrypt || !foundSignature || !foundStartText) {
DumperDebugLog(@"dumping binary: some load commands were not found %@ %@ %@",foundCrypt?@"YES":@"NO",foundSignature?@"YES":@"NO",foundStartText?@"YES":@"NO");
ERROR(@"dumping binary: some load commands were not found %@ %@ %@",foundCrypt?@"YES":@"NO",foundSignature?@"YES":@"NO",foundStartText?@"YES":@"NO");
return NO;
}

Expand Down
9 changes: 7 additions & 2 deletions Clutch/ApplicationsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//

#define applistCachePath @"/tmp/applist-cache.clutch"
#define applistCachePath @"applist-cache.plist"
#define dumpedAppPath @"/etc/dumped.clutch"

#import <dlfcn.h>
Expand Down Expand Up @@ -129,12 +129,17 @@ - (NSDictionary *)_allApplications
Application *app =[[Application alloc]initWithBundleInfo:bundleInfo];
returnValue[proxy.bundleIdentifier] = app;
[self cacheBundle:bundleInfo];

}
}
}

}
[_cachedApps writeToFile:applistCachePath atomically:YES];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(queue, ^{
[_cachedApps writeToFile:applistCachePath atomically:YES];
});

return [returnValue copy];
}

Expand Down
2 changes: 1 addition & 1 deletion Clutch/Clutch-Prefix.pch
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#define CLUTCH_VERSION @"2.0 RC3"

# define SUCCESS(M, ...) fprintf(stderr, "\033[0;31mDONE\033[0m: %s\n",[[NSString stringWithFormat:M, ##__VA_ARGS__] UTF8String]);
# define SUCCESS(M, ...) fprintf(stderr, "\033[1;31mDONE\033[0m: %s\n",[[NSString stringWithFormat:M, ##__VA_ARGS__] UTF8String]);

#ifdef DEBUG
# define FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // shortened path of __FILE__ is there is one
Expand Down
2 changes: 1 addition & 1 deletion Clutch/ClutchBundle.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ - (void)prepareForDump {
thin_header _thinHeader = headers[i];

NSString *rpath = self.parentBundle ? [self.parentBundle.bundlePath stringByAppendingPathComponent:@"Frameworks"] : [self.bundlePath stringByAppendingPathComponent:@"Frameworks"] ;

NSLog(@"checking rpath for %@", self.executable.binaryPath);
insertRPATHIntoBinary(rpath, data, _thinHeader);
}

Expand Down
99 changes: 97 additions & 2 deletions Clutch/Dumper.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ - (pid_t)posix_spawn:(NSString *)binaryPath disableASLR:(BOOL)yrn suspend:(BOOL)

posix_spawnattr_destroy (&attr);

NSLog(@"got the pid %u %@", pid, binaryPath);l
NSLog(@"got the pid %u %@", pid, binaryPath);

return pid;
}
Expand All @@ -123,7 +123,7 @@ - (BOOL)dumpBinary
return NO;
}

- (void)swapArch
/*- (void)swapArch
{
thin_header macho = _thinHeader;
Expand Down Expand Up @@ -167,8 +167,11 @@ - (void)swapArch
struct fat_arch keep_arch;
char data[20];
NSLog(@"sizeof struct fat_arch %lu", sizeof(struct fat_arch));
memset(data,'\0',sizeof(data));
struct fat_arch fat_arches[20]; //don't think an app can have more than 20
for (int i = 0; i < fat.nfat_arch; i++) {
struct fat_arch arch;
arch = *(struct fat_arch *)([buffer bytes] + offset);
Expand All @@ -194,6 +197,98 @@ - (void)swapArch
DumperLog(@"wrote new header to binary!");
}*/


-(void)swapArch {

thin_header macho = _thinHeader;

DumperLog(@"swapping archs");

//time to swap
NSString* suffix = [NSString stringWithFormat:@"_%@", [Dumper readableArchFromHeader:_thinHeader]];

NSString *swappedBinaryPath = [_originalBinary.binaryPath stringByAppendingString:suffix];
NSString *newSinf = [_originalBinary.sinfPath.stringByDeletingPathExtension stringByAppendingString:[suffix stringByAppendingPathExtension:_originalBinary.sinfPath.pathExtension]];
NSString *newSupp = [_originalBinary.suppPath.stringByDeletingPathExtension stringByAppendingString:[suffix stringByAppendingPathExtension:_originalBinary.suppPath.pathExtension]];

NSString *newSupf;
if ([[NSFileManager defaultManager] fileExistsAtPath:_originalBinary.supfPath]) {
newSupf = [_originalBinary.supfPath.stringByDeletingPathExtension stringByAppendingString:[suffix stringByAppendingPathExtension:_originalBinary.supfPath.pathExtension]];
}

[[NSFileManager defaultManager] copyItemAtPath:_originalBinary.binaryPath toPath:swappedBinaryPath error:nil];
[[NSFileManager defaultManager] copyItemAtPath:_originalBinary.sinfPath toPath:newSinf error:nil];

[[NSFileManager defaultManager] copyItemAtPath:_originalBinary.suppPath toPath:newSupp error:nil];

if (newSupf) {
[[NSFileManager defaultManager] copyItemAtPath:_originalBinary.supfPath toPath:newSupf error:nil];
}

[self.originalFileHandle closeFile];
self.originalFileHandle = [[NSFileHandle alloc]initWithFileDescriptor:fileno(fopen(swappedBinaryPath.UTF8String, "r+"))];

uint32_t magic = [self.originalFileHandle intAtOffset:0];
bool shouldSwap = magic == FAT_CIGAM;
#define SWAP(NUM) (shouldSwap ? CFSwapInt32(NUM) : NUM)

NSData *buffer = [self.originalFileHandle readDataOfLength:4096];

struct fat_header fat = *(struct fat_header *)buffer.bytes;
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;
arch = *(struct fat_arch *)([buffer bytes] + offset);

if (!((SWAP(arch.cputype) == _thinHeader.header.cputype) && (SWAP(arch.cpusubtype) == _thinHeader.header.cpusubtype))) {

if (SWAP(arch.cputype) == CPU_TYPE_ARM) {
switch (SWAP(arch.cpusubtype)) {
case CPU_SUBTYPE_ARM_V6:
arch.cputype = SWAP(CPU_TYPE_I386);
arch.cpusubtype = SWAP(CPU_SUBTYPE_PENTIUM_3_XEON);
break;
case CPU_SUBTYPE_ARM_V7:
arch.cputype = SWAP(CPU_TYPE_I386);
arch.cpusubtype = SWAP(CPU_SUBTYPE_PENTIUM_4);
break;
case CPU_SUBTYPE_ARM_V7S:
arch.cputype = SWAP(CPU_TYPE_I386);
arch.cpusubtype = SWAP(CPU_SUBTYPE_ITANIUM);
break;
case CPU_SUBTYPE_ARM_V7K: // Apple Watch FTW
arch.cputype = SWAP(CPU_TYPE_I386);
arch.cpusubtype = SWAP(CPU_SUBTYPE_XEON);
break;
}
} else {

switch (SWAP(arch.cpusubtype)) {
case CPU_SUBTYPE_ARM64_ALL:
arch.cputype = SWAP(CPU_TYPE_X86_64);
arch.cpusubtype = SWAP(CPU_SUBTYPE_X86_64_ALL);
break;
case CPU_SUBTYPE_ARM64_V8:
arch.cputype = SWAP(CPU_TYPE_X86_64);
arch.cpusubtype = SWAP(CPU_SUBTYPE_X86_64_H);
break;
}

}

[self.originalFileHandle replaceBytesInRange:NSMakeRange(offset, sizeof(struct fat_arch)) withBytes:&arch];
}

offset += sizeof(struct fat_arch);
}


DumperLog(@"wrote new header to binary");

}

- (BOOL)_dumpToFileHandle:(NSFileHandle *)fileHandle withEncryptionInfoCommand:(uint32_t)togo pages:(uint32_t)pages fromPort:(mach_port_t)port pid:(pid_t)pid aslrSlide:(mach_vm_address_t)__text_start
Expand Down
7 changes: 5 additions & 2 deletions Clutch/FinalizeDumpOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ - (void)start {
}

self.completionBlock = ^{
exit(0);
CFRunLoopStop(CFRunLoopGetCurrent());
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"ending the thread bye bye");
CFRunLoopStop(CFRunLoopGetCurrent());
});

};

// If the operation is not canceled, begin executing the task.
Expand Down
2 changes: 1 addition & 1 deletion Clutch/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ int main (int argc, const char * argv[])
gettimeofday(&end, NULL);
int dif = diff_ms(end,start);
float sec = ((dif + 500.0f) / 1000.0f);
gbprintln(@"Finished dumping %@ in %u s", _selectedApp.bundleIdentifier, sec);
gbprintln(@"Finished dumping %@ in %f s", _selectedApp.bundleIdentifier, sec);



Expand Down
9 changes: 8 additions & 1 deletion Clutch/optool-operations.m
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,15 @@ BOOL binaryHasRPATH(NSMutableData *binary, NSString *dylib, uint32_t *lastOffset

// Loop through compatible LC_LOAD commands until we find one which points
// to the given dylib and tell the caller where it is and if it exists
bool foundRPATH = NO;
for (int i = 0; i < macho.header.ncmds; i++) {
if (binary.currentOffset >= binary.length ||
binary.currentOffset > macho.offset + macho.size + macho.header.sizeofcmds)
break;

uint32_t cmd = [binary intAtOffset:binary.currentOffset];
uint32_t size = [binary intAtOffset:binary.currentOffset + 4];


switch (cmd) {
case LC_RPATH: {
Expand All @@ -264,6 +266,7 @@ BOOL binaryHasRPATH(NSMutableData *binary, NSString *dylib, uint32_t *lastOffset

binary.currentOffset += size;
loadOffset = (unsigned int)binary.currentOffset;
foundRPATH = YES;
break;
}
default:
Expand All @@ -274,7 +277,11 @@ BOOL binaryHasRPATH(NSMutableData *binary, NSString *dylib, uint32_t *lastOffset

if (lastOffset != NULL)
*lastOffset = loadOffset;

if (!foundRPATH) {
NSLog(@"didn't find rpath, no injection!");
return YES;

}
return NO;
}

Expand Down

0 comments on commit 47494cc

Please sign in to comment.