-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTweak.m
131 lines (116 loc) · 5.67 KB
/
Tweak.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Thanks https://bitbucket.org/lordscotland/dump/src/master/decrypt.c
#import <Foundation/Foundation.h>
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <mach-o/fat.h>
#import <mach-o/loader.h>
#import "SharedStrings.h"
static size_t stream_copy(FILE *src, FILE *dest, size_t maxlen) {
size_t nbytes = 0;
while (!feof(src)) {
char buf[8192];
bool end = (maxlen && nbytes + sizeof(buf) >= maxlen);
nbytes += fwrite(buf, 1, fread(buf, 1, end ? maxlen - nbytes : sizeof(buf), src), dest);
if (end) {
break;
}
}
return nbytes;
}
static __attribute__((constructor)) void _loadDump() {
@autoreleasepool {
NSDictionary *readDict = [NSDictionary dictionaryWithContentsOfFile:@kDictPath];
NSString *bundleID = NSBundle.mainBundle.bundleIdentifier;
NSString *topDecrytDir = readDict[bundleID];
if (!topDecrytDir) {
return;
}
NSDateFormatter *dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat = @"yyyy-MM-dd-HH-mm-ss";
NSString *dateID = [dateFormatter stringFromDate:NSDate.date];
NSString *basePath = [NSString stringWithFormat:@"%@/%@-%@", topDecrytDir, bundleID, dateID];
NSError *createErr = NULL;
[NSFileManager.defaultManager createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:NULL error:&createErr];
if (createErr) {
notify_post(kPostFailKey);
return;
}
NSDictionary *writeDict = @{ bundleID : basePath };
[writeDict writeToFile:[topDecrytDir stringByAppendingPathComponent:@"Info.plist"] atomically:YES];
Dl_info info;
void *self = dladdr(&_loadDump, &info) ? info.dli_fbase : NULL;
int i, imax = _dyld_image_count();
for (i = 0; i < imax; i++) {
const struct mach_header *mh = _dyld_get_image_header(i);
if (mh == self) {
continue;
}
size_t hsize = (mh->magic == MH_MAGIC_64) ? sizeof(struct mach_header_64) : sizeof(struct mach_header);
struct load_command *lc = (void *)((char *)mh + hsize);
struct encryption_info_command *eic = NULL;
int ncmds = mh->ncmds;
while (ncmds--) {
if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd == LC_ENCRYPTION_INFO_64) {
eic = (void *)lc;
break;
}
lc = (void *)((char *)lc + lc->cmdsize);
}
const char *fname = _dyld_get_image_name(i);
FILE *fh = fopen(fname, "rb");
if (fh) {
if (eic && eic->cryptid) {
uint32_t slice_offset, slice_size;
struct fat_header fat;
fread(&fat, sizeof(struct fat_header), 1, fh);
bool swap = (fat.magic == FAT_CIGAM);
if (swap || fat.magic == FAT_MAGIC) {
uint32_t narch = fat.nfat_arch;
cpu_type_t mtype = mh->cputype;
cpu_subtype_t msubtype = mh->cpusubtype;
if (swap) {
narch = __builtin_bswap32(narch);
mtype = __builtin_bswap32(mtype);
msubtype = __builtin_bswap32(msubtype);
}
while (narch--) {
struct fat_arch arch;
fread(&arch, sizeof(struct fat_arch), 1, fh);
if (arch.cputype == mtype && arch.cpusubtype == msubtype) {
slice_offset = swap ? __builtin_bswap32(arch.offset) : arch.offset;
slice_size = swap ? __builtin_bswap32(arch.size) : arch.size;
goto __writeFile;
}
}
} else if (fat.magic == mh->magic) {
slice_offset = slice_size = 0;
__writeFile : {
char *outname = strrchr(fname, '/');
NSString *outFileName = [NSString stringWithFormat:@"%@/%s.%d", basePath, (outname ? outname + 1 : fname), i];
FILE *outfh = fopen(outFileName.UTF8String, "wb");
if (outfh) {
struct encryption_info_command eic0 = { .cmd = eic->cmd, .cmdsize = eic->cmdsize };
size_t pos = fwrite(mh, 1, (char *)eic - (char *)mh, outfh);
pos += fwrite(&eic0, 1, sizeof(eic0), outfh);
pos += fwrite((char *)mh + pos, 1, hsize + mh->sizeofcmds - pos, outfh);
fseek(fh, slice_offset + pos, SEEK_SET);
if (eic->cryptoff > pos) {
pos += stream_copy(fh, outfh, eic->cryptoff - pos);
}
pos += fwrite((char *)mh + pos, 1, eic->cryptsize, outfh);
fseek(fh, eic->cryptsize, SEEK_CUR);
pos += stream_copy(fh, outfh, slice_size ? slice_size - pos : 0);
fclose(outfh);
} else {
perror("fopen");
}
}
}
}
fclose(fh);
}
}
notify_post(kPostDoneKey);
exit(0);
}
}