Skip to content
This repository has been archived by the owner on Nov 22, 2022. It is now read-only.

Commit

Permalink
Remove autoreleasepool{} in main constructor and fix the memory doubl…
Browse files Browse the repository at this point in the history
…e release issue. Thus making dumpdecrypted usable again
  • Loading branch information
Naville committed Aug 21, 2016
1 parent b7e7846 commit 05e4af6
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export CFLAGS=-Wp,"-DWTFJHTWEAKNAME=@\"WTFJH\",-DPROTOTYPE,"-DWTFJHHostName=@\"NavRMBP\"
export CFLAGS=-Wp,"-DWTFJHTWEAKNAME=@\"WTFJH\","-DWTFJHHostName=@\"NavRMBP\"
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = WTFJH
SUBSTRATE ?= yes
Expand Down
7 changes: 5 additions & 2 deletions ThirdPartyTemplate.xm
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ extern void init_TEMPLATENAME_hook(){
WTSave;
WTRelease;
//End
[SDData release];
[randomPath release];


return;
[curName release];
break;
}
[curName release];

}
#elif
Expand Down
6 changes: 6 additions & 0 deletions ThirdPartyTools/dumpdecrypted/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include $(THEOS)/makefiles/common.mk
ADDITIONAL_LDFLAGS = -Wl,-segalign,4000
TWEAK_NAME = dumpdecrypted
dumpdecrypted_FILES = dumpdecrypted.m

include $(THEOS_MAKE_PATH)/tweak.mk
4 changes: 4 additions & 0 deletions ThirdPartyTools/dumpdecrypted/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#CarinaTT/dumpdecrypted
This is a fork of dumpdecrypted by *CarinaTT*

Was about to do the dirty work myself until i saw this. Thanks for saving me quite some time >_<
260 changes: 260 additions & 0 deletions ThirdPartyTools/dumpdecrypted/dumpdecrypted.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
//
// dumpdecrypted.m
// dumpdecrypted
//
// Created by Carina on 15/2/5.
// Copyright (c) 2015 Carina. All rights reserved.
//

#import <Foundation/Foundation.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>

#define RMASLRCenter @"com.naville.wtfjh.rmaslr"
struct ProgramVars {
struct mach_header* mh;
int* NXArgcPtr;
const char*** NXArgvPtr;
const char*** environPtr;
const char** __prognamePtr;
};

#define swap32(value) (((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24) )

__attribute__((constructor))
void dumptofile(int argc, const char **argv, const char **envp, const char **apple, struct ProgramVars *pvars)
{
struct load_command *lc;
struct encryption_info_command *eic;
struct fat_header *fh;
struct fat_arch *arch;
// struct mach_header *mh;
char buffer[1024];
char rpath[4096],npath[4096]; /* should be big enough for PATH_MAX */
unsigned int fileoffs = 0;
off_t off_cryptid = 0, restsize;
int i,fd,outfd;
size_t r,n,toread;
char *tmp;

NSLog(@"mach-o decryption dumper\n\n");

NSLog(@"DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.\n\n");

/* detect if this is a arm64 binary */
if (pvars->mh->magic == MH_MAGIC_64) {
lc = (struct load_command *)((unsigned char *)pvars->mh + sizeof(struct mach_header_64));
NSLog(@"[+] detected 64bit ARM binary in memory.\n");
} else { /* we might want to check for other errors here, too */
lc = (struct load_command *)((unsigned char *)pvars->mh + sizeof(struct mach_header));
NSLog(@"[+] detected 32bit ARM binary in memory.\n");
}

/* searching all load commands for an LC_ENCRYPTION_INFO load command */
for (i=0; i<pvars->mh->ncmds; i++) {
/*NSLog(@"Load Command (%d): %08x\n", i, lc->cmd);*/

if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd == LC_ENCRYPTION_INFO_64) {
eic = (struct encryption_info_command *)lc;

/* If this load command is present, but data is not crypted then exit */
if (eic->cryptid == 0) {
break;
}
off_cryptid=(off_t)((void*)&eic->cryptid - (void*)pvars->mh);
NSLog(@"[+] offset to cryptid found: @%p(from %p) = %llx\n", &eic->cryptid, pvars->mh, off_cryptid);

NSLog(@"[+] Found encrypted data at address %08x of length %u bytes - type %u.\n", eic->cryptoff, eic->cryptsize, eic->cryptid);

if (realpath(argv[0], rpath) == NULL) {
strlcpy(rpath, argv[0], sizeof(rpath));
}

NSLog(@"[+] Opening %s for reading.\n", rpath);
fd = open(rpath, O_RDONLY);
if (fd == -1) {
NSLog(@"[-] Failed opening.\n");
return; //return; //_exit(1);
}

NSLog(@"[+] Reading header\n");
n = read(fd, (void *)buffer, sizeof(buffer));
if (n != sizeof(buffer)) {
NSLog(@"[W] Warning read only %zu bytes\n", n);
}

NSLog(@"[+] Detecting header type\n");
fh = (struct fat_header *)buffer;

/* Is this a FAT file - we assume the right endianess */
if (fh->magic == FAT_CIGAM) {
NSLog(@"[+] Executable is a FAT image - searching for right architecture\n");
arch = (struct fat_arch *)&fh[1];
for (i=0; i<swap32(fh->nfat_arch); i++) {
if ((pvars->mh->cputype == swap32(arch->cputype)) && (pvars->mh->cpusubtype == swap32(arch->cpusubtype))) {
fileoffs = swap32(arch->offset);
NSLog(@"[+] Correct arch is at offset %u in the file\n", fileoffs);
break;
}
arch++;
}
if (fileoffs == 0) {
NSLog(@"[-] Could not find correct arch in FAT image\n");
return; //return; //_exit(1);
}
} else if (fh->magic == MH_MAGIC || fh->magic == MH_MAGIC_64) {
NSLog(@"[+] Executable is a plain MACH-O image\n");
} else {
NSLog(@"[-] Executable is of unknown type\n");
return; //return; //_exit(1);
}

/* extract basename */
tmp = strrchr(rpath, '/');
if (tmp == NULL) {
NSLog(@"[-] Unexpected error with filename.\n");
return; //_exit(1);
}
/// app caches
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];

strlcpy(npath, cachePath.UTF8String, sizeof(npath));
strlcat(npath, tmp, sizeof(npath));
strlcat(npath, ".decrypted", sizeof(npath));
strlcpy(buffer, npath, sizeof(buffer));

NSLog(@"[+] Opening %s for writing.\n", npath);
outfd = open(npath, O_RDWR|O_CREAT|O_TRUNC, 0644);
if (outfd == -1) {
if (strncmp("/private/var/mobile/Applications/", rpath, 33) == 0) {
NSLog(@"[-] Failed opening. Most probably a sandbox issue. Trying something different.\n");

/* create new name */
strlcpy(npath, "/private/var/mobile/Applications/", sizeof(npath));
tmp = strchr(rpath+33, '/');
if (tmp == NULL) {
NSLog(@"[-] Unexpected error with filename.\n");
return; //_exit(1);
}
tmp++;
*tmp++ = 0;
strlcat(npath, rpath+33, sizeof(npath));
strlcat(npath, "tmp/", sizeof(npath));
strlcat(npath, buffer, sizeof(npath));
NSLog(@"[+] Opening %s for writing.\n", npath);
outfd = open(npath, O_RDWR|O_CREAT|O_TRUNC, 0644);
//Post Path Notification
NSString* NSpath=[[NSString stringWithUTF8String:npath] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:RMASLRCenter
object:nil
userInfo:[NSDictionary dictionaryWithObject:NSpath forKey:@"Path"]];

}
if (outfd == -1) {
perror("[-] Failed opening");
NSLog(@"\n");
return; //_exit(1);
}
}
else{
//First Path Got Right
NSString* NSpath=[[NSString stringWithUTF8String:npath] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:RMASLRCenter
object:nil
userInfo:[NSDictionary dictionaryWithObject:NSpath forKey:@"Path"]];

}

/* calculate address of beginning of crypted data */
n = fileoffs + eic->cryptoff;

restsize = lseek(fd, 0, SEEK_END) - n - eic->cryptsize;
lseek(fd, 0, SEEK_SET);
NSLog(@"[+] Copying the not encrypted start of the file\n");
/* first copy all the data before the encrypted data */
while (n > 0) {
toread = (n > sizeof(buffer)) ? sizeof(buffer) : n;
r = read(fd, buffer, toread);
if (r != toread) {
NSLog(@"[-] Error reading file\n");
return; //_exit(1);
}
n -= r;

r = write(outfd, buffer, toread);
if (r != toread) {
NSLog(@"[-] Error writing file\n");
return; //_exit(1);
}
}

/* now write the previously encrypted data */
NSLog(@"[+] Dumping the decrypted data into the file\n");
r = write(outfd, (unsigned char *)pvars->mh + eic->cryptoff, eic->cryptsize);
if (r != eic->cryptsize) {
NSLog(@"[-] Error writing file\n");
return; //_exit(1);
}

/* and finish with the remainder of the file */
n = (size_t)restsize;
lseek(fd, eic->cryptsize, SEEK_CUR);
NSLog(@"[+] Copying the not encrypted remainder of the file\n");
while (n > 0) {
toread = (n > sizeof(buffer)) ? sizeof(buffer) : n;
r = read(fd, buffer, toread);
if (r != toread) {
NSLog(@"[-] Error reading file\n");
return; //_exit(1);
}
n -= r;

r = write(outfd, buffer, toread);
if (r != toread) {
NSLog(@"[-] Error writing file\n");
return; //_exit(1);
}
}

if (off_cryptid) {
uint32_t zero=0;
off_cryptid+=fileoffs;
NSLog(@"[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset %llx\n", off_cryptid);
if (lseek(outfd, off_cryptid, SEEK_SET) != off_cryptid || write(outfd, &zero, 4) != 4) {
NSLog(@"[-] Error writing cryptid value\n");
}
}

NSLog(@"[+] Closing original file\n");
close(fd);
NSLog(@"[+] Closing dump file\n");
close(outfd);

return; //_exit(1);
}

lc = (struct load_command *)((unsigned char *)lc+lc->cmdsize);
}
NSLog(@"[-] This mach-o file is not encrypted. Nothing was decrypted.\n");
//Direct Copy mainExecutable
NSURL* mainExeURL=[NSBundle mainBundle].executableURL;
NSString* NewPath=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NewPath=[NewPath stringByAppendingString:[[NSProcessInfo processInfo] processName]];
[[NSFileManager defaultManager] copyItemAtURL:mainExeURL toURL:[NSURL URLWithString:NewPath] error:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:RMASLRCenter
object:nil
userInfo:[NSDictionary dictionaryWithObject:NewPath forKey:@"Path"]];

[NewPath release];


//
return; //_exit(1);
}

1 change: 1 addition & 0 deletions ThirdPartyTools/dumpdecrypted/obj
4 changes: 1 addition & 3 deletions Tweak.xm
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ dlopen("/usr/lib/libsubstrate.dylib",RTLD_NOW|RTLD_GLOBAL);
[[NSNotificationCenter defaultCenter] postNotificationName:@"IBARevealRequestStop" object:nil];


NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// Only hook Apps the user has selected in WTFJH's settings panel
NSString *appId = [[NSBundle mainBundle] bundleIdentifier];
Expand All @@ -93,7 +93,6 @@ dlopen("/usr/lib/libsubstrate.dylib",RTLD_NOW|RTLD_GLOBAL);
id shouldHook = [[[NSMutableDictionary alloc] initWithContentsOfFile:preferenceFilePath] objectForKey:appId];
if ( (shouldHook == nil) || (! [shouldHook boolValue]) ) {
NSLog(@"WTFJH - Profiling disabled for %@", appId);
[pool drain];
return;
}
NSLog(@"WTFJH - Profiling enabled for %@", appId);
Expand Down Expand Up @@ -124,7 +123,6 @@ dlopen("/usr/lib/libsubstrate.dylib",RTLD_NOW|RTLD_GLOBAL);
NSLog(@"WTFJH - DB Initialization error; disabling hooks.");
}

[pool drain];
}


Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
440
443

0 comments on commit 05e4af6

Please sign in to comment.