From 193cf947e222bb2daa8a38082ad09ced8d438da0 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Tue, 16 Dec 2014 18:24:52 -0800 Subject: [PATCH] Add support for dumping encrypted frameworks --- dumpdecrypted.c | 79 +++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/dumpdecrypted.c b/dumpdecrypted.c index 3313be2..4ed91d1 100644 --- a/dumpdecrypted.c +++ b/dumpdecrypted.c @@ -29,48 +29,49 @@ DISCLAIMER: This tool is only meant for security research purposes, not for appl #include #include #include +#include #include #include - -struct ProgramVars { - struct mach_header* mh; - int* NXArgcPtr; - const char*** NXArgvPtr; - const char*** environPtr; - const char** __prognamePtr; -}; +#include #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) -{ +void dumptofile(const char *path, const struct mach_header *mh) { 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_cryptid = 0, restsize; int i,fd,outfd,r,n,toread; char *tmp; - - printf("mach-o decryption dumper\n\n"); - - printf("DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.\n\n"); - + + if (realpath(path, rpath) == NULL) { + strlcpy(rpath, path, sizeof(rpath)); + } + + /* extract basename */ + tmp = strrchr(rpath, '/'); + printf("\n\n"); + if (tmp == NULL) { + printf("[-] Unexpected error with filename.\n"); + _exit(1); + } else { + printf("[+] Dumping %s\n", tmp+1); + } + /* 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)); + if (mh->magic == MH_MAGIC_64) { + lc = (struct load_command *)((unsigned char *)mh + sizeof(struct mach_header_64)); printf("[+] 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)); + lc = (struct load_command *)((unsigned char *)mh + sizeof(struct mach_header)); printf("[+] detected 32bit ARM binary in memory.\n"); } /* searching all load commands for an LC_ENCRYPTION_INFO load command */ - for (i=0; imh->ncmds; i++) { + for (i=0; incmds; i++) { /*printf("Load Command (%d): %08x\n", i, lc->cmd);*/ if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd == LC_ENCRYPTION_INFO_64) { @@ -80,15 +81,11 @@ void dumptofile(int argc, const char **argv, const char **envp, const char **app if (eic->cryptid == 0) { break; } - off_cryptid=(off_t)((void*)&eic->cryptid - (void*)pvars->mh); - printf("[+] offset to cryptid found: @%p(from %p) = %x\n", &eic->cryptid, pvars->mh, off_cryptid); + off_cryptid=(off_t)((void*)&eic->cryptid - (void*)mh); + printf("[+] offset to cryptid found: @%p(from %p) = %x\n", &eic->cryptid, mh, off_cryptid); printf("[+] 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)); - } - + printf("[+] Opening %s for reading.\n", rpath); fd = open(rpath, O_RDONLY); if (fd == -1) { @@ -110,7 +107,7 @@ void dumptofile(int argc, const char **argv, const char **envp, const char **app printf("[+] Executable is a FAT image - searching for right architecture\n"); arch = (struct fat_arch *)&fh[1]; for (i=0; infat_arch); i++) { - if ((pvars->mh->cputype == swap32(arch->cputype)) && (pvars->mh->cpusubtype == swap32(arch->cpusubtype))) { + if ((mh->cputype == swap32(arch->cputype)) && (mh->cpusubtype == swap32(arch->cpusubtype))) { fileoffs = swap32(arch->offset); printf("[+] Correct arch is at offset %u in the file\n", fileoffs); break; @@ -128,12 +125,6 @@ void dumptofile(int argc, const char **argv, const char **envp, const char **app _exit(1); } - /* extract basename */ - tmp = strrchr(rpath, '/'); - if (tmp == NULL) { - printf("[-] Unexpected error with filename.\n"); - _exit(1); - } strlcpy(npath, tmp+1, sizeof(npath)); strlcat(npath, ".decrypted", sizeof(npath)); strlcpy(buffer, npath, sizeof(buffer)); @@ -192,7 +183,7 @@ void dumptofile(int argc, const char **argv, const char **envp, const char **app /* now write the previously encrypted data */ printf("[+] Dumping the decrypted data into the file\n"); - r = write(outfd, (unsigned char *)pvars->mh + eic->cryptoff, eic->cryptsize); + r = write(outfd, (unsigned char *)mh + eic->cryptoff, eic->cryptsize); if (r != eic->cryptsize) { printf("[-] Error writing file\n"); _exit(1); @@ -231,12 +222,22 @@ void dumptofile(int argc, const char **argv, const char **envp, const char **app close(fd); printf("[+] Closing dump file\n"); close(outfd); - - _exit(1); } lc = (struct load_command *)((unsigned char *)lc+lc->cmdsize); } printf("[-] This mach-o file is not encrypted. Nothing was decrypted.\n"); - _exit(1); +} + +static void image_added(const struct mach_header *mh, intptr_t slide) { + Dl_info image_info; + int result = dladdr(mh, &image_info); + dumptofile(image_info.dli_fname, mh); +} + +__attribute__((constructor)) +static void dumpexecutable() { + printf("mach-o decryption dumper\n\n"); + printf("DISCLAIMER: This tool is only meant for security research purposes, not for application crackers."); + _dyld_register_func_for_add_image(&image_added); }