-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathbfdecrypt.m
196 lines (171 loc) · 9.67 KB
/
bfdecrypt.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
BF Decryptor - Decrypt iOS apps and repack them into an .ipa
https://github.com/BishopFox/bfinject
Carl Livitt @ Bishop Fox
*/
#include <stdio.h>
#include <unistd.h>
#include <mach/mach.h>
#include <mach-o/dyld.h>
#include <stdlib.h>
#include <dlfcn.h>
#import <UIKit/UIKit.h>
#include <stdint.h>
#include "DumpDecrypted.h"
#define PORT 31336
//#define DEBUG(...) NSLog(__VA_ARGS__);
#define DEBUG(...) {}
UIWindow *alertWindow = NULL;
UIWindow *kw = NULL;
UIViewController *root = NULL;
UIAlertController *alertController = NULL;
UIAlertController *ncController = NULL;
UIAlertController *errorController = NULL;
// The dylib constructor sets decryptedIPAPath, spawns a thread to do the app decryption, then exits.
__attribute__ ((constructor)) static void bfinject_rocknroll() {
NSLog(@"[bfdecrypt] Spawning thread to do decryption in the background...");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"[bfdecrypt] Inside decryption thread");
const char *fullPathStr = _dyld_get_image_name(0);
DumpDecrypted *dd = [[DumpDecrypted alloc] initWithPathToBinary:[NSString stringWithUTF8String:fullPathStr]];
if(!dd) {
NSLog(@"[bfdecrypt] ERROR: failed to get DumpDecrypted instance");
return;
}
NSLog(@"[bfdecrypt] Full path to app: %s /// IPA File: %@", fullPathStr, [dd IPAPath]);
dispatch_async(dispatch_get_main_queue(), ^{
alertWindow = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
alertWindow.rootViewController = [UIViewController new];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
// Show a "Decrypting!" alert on the device and block the UI
alertController = [UIAlertController
alertControllerWithTitle:@"Decrypting"
message:@"Please wait, this will take a few seconds..."
preferredStyle:UIAlertControllerStyleAlert];
kw = alertWindow;
if([kw respondsToSelector:@selector(topmostPresentedViewController)])
root = [kw performSelector:@selector(topmostPresentedViewController)];
else
root = [kw rootViewController];
root.modalPresentationStyle = UIModalPresentationFullScreen;
[root presentViewController:alertController animated:YES completion:nil];
});
// Do the decryption
[dd createIPAFile];
// Dismiss the alert box
dispatch_async(dispatch_get_main_queue(), ^{
[alertController dismissViewControllerAnimated:NO completion:nil];
// Would the user like to host the IPA on a port for easy retrieval with NetCat?
NSString *message = @"Would you like to serve the IPA on the following addresses/ports for retrieval with NetCat?\n\n";
DEBUG(@"Getting IPs");
NSDictionary *addresses = [dd getIPAddresses];
DEBUG(@"IP Addresses: %@", addresses);
id key;
NSString *ip;
for(key in addresses) {
ip = [addresses objectForKey:key];
message = [NSString stringWithFormat:@"%@%@:31336\n", message, ip];
}
message = [NSString stringWithFormat:@"\n\n%@For example:\nnc %@:31336 > /tmp/ecrypted.ipa.", message, ip];
ncController = [UIAlertController
alertControllerWithTitle:@"Decryption Complete!"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"No", @"Cancel action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(@"Cancel action");
[ncController dismissViewControllerAnimated:NO completion:nil];
[kw removeFromSuperview];
kw.hidden = YES;
[kw release];
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Yes", @"OK action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(@"OK action");
// Removing the "Decryption Complete!" alert
[ncController dismissViewControllerAnimated:NO completion:nil];
// Spawn server on port 31336 by default
// Connections to this port will be sent a raw copy of the IPA file.
NSLog(@"[bfdecrypt] Checking we can start the server...");
int s;
if( ! (s = [dd getSocketForPort:PORT])) {
// Port 31336 isn't available. Something listening?
NSLog(@"[bfdecrypt] Couldn't listen on port %d, is another decrypted app still running?", PORT);
errorController = [UIAlertController
alertControllerWithTitle:@"Error!"
message:@"Could not start server on port 31336, perhaps there's another decryption server already listening?"
preferredStyle:UIAlertControllerStyleAlert
];
[errorController addAction:[UIAlertAction
actionWithTitle:NSLocalizedString(@"Ok", @"Ok")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(@"Cancel action");
[errorController dismissViewControllerAnimated:NO completion:nil];
[kw removeFromSuperview];
kw.hidden = YES;
[kw release];
}]
];
[root presentViewController:errorController animated:YES completion:nil];
} else {
close(s);
NSLog(@"[bfdecrypt] Yes we can, starting now.");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[kw removeFromSuperview];
kw.hidden = YES;
[kw release];
[dd IPAServer:PORT];
});
NSLog(@"[bfdecrypt] IPAServer finished.");
}
}];
[ncController addAction:cancelAction];
[ncController addAction:okAction];
[root presentViewController:ncController animated:YES completion:nil];
}); // dispatch on main
NSLog(@"[bfdecrypt] Over and out.");
while(1)
sleep(9999999);
}); // dispatch in background
NSLog(@"[bfdecrypt] All done, exiting constructor.");
}
void showAlert(NSString *title, NSString *message) {
dispatch_async(dispatch_get_main_queue(), ^{
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
alertWindow.rootViewController = [UIViewController new];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIWindow *kw = alertWindow;
UIViewController *root;
if([kw respondsToSelector:@selector(topmostPresentedViewController)])
root = [kw performSelector:@selector(topmostPresentedViewController)];
else
root = [kw rootViewController];
root.modalPresentationStyle = UIModalPresentationFullScreen;
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"Ok", @"Ok")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
[alertController dismissViewControllerAnimated:NO completion:nil];
[kw removeFromSuperview];
kw.hidden = YES;
[kw release];
}];
[alertController addAction:okAction];
[root presentViewController:alertController animated:YES completion:nil];
});
}