-
Notifications
You must be signed in to change notification settings - Fork 365
/
SSJailbreakCheck.m
executable file
·405 lines (356 loc) · 11.2 KB
/
SSJailbreakCheck.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
//
// SSJailbreakCheck.m
// SystemServicesDemo
//
// Created by Shmoopi LLC on 9/17/12.
// Copyright (c) 2012 Shmoopi LLC. All rights reserved.
//
/* Check out "Hacking and Securing iOS Applications" Book to determine all available methods */
#import "SSJailbreakCheck.h"
// UIKit
#import <UIKit/UIKit.h>
// stat
#import <sys/stat.h>
// sysctl
#import <sys/sysctl.h>
// System Version Less Than
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
// Failed jailbroken checks
enum {
// Failed the Jailbreak Check
KFJailbroken = 3429542,
// Failed the OpenURL Check
KFOpenURL = 321,
// Failed the Cydia Check
KFCydia = 432,
// Failed the Inaccessible Files Check
KFIFC = 47293,
// Failed the plist check
KFPlist = 9412,
// Failed the Processes Check with Cydia
KFProcessesCydia = 10012,
// Failed the Processes Check with other Cydia
KFProcessesOtherCydia = 42932,
// Failed the Processes Check with other other Cydia
KFProcessesOtherOCydia = 10013,
// Failed the FSTab Check
KFFSTab = 9620,
// Failed the System() Check
KFSystem = 47475,
// Failed the Symbolic Link Check
KFSymbolic = 34859,
// Failed the File Exists Check
KFFileExists = 6625,
} JailbrokenChecks;
@implementation SSJailbreakCheck
// Is the application running on a jailbroken device?
+ (int)jailbroken {
// Is the device jailbroken?
// Make an int to monitor how many checks are failed
int motzart = 0;
// Check if iOS 8 or lower
if (SYSTEM_VERSION_LESS_THAN(@"9.0")) {
// URL Check
if ([self urlCheck] != NOTJAIL) {
// Jailbroken
motzart += 3;
}
}
// Cydia Check
if ([self cydiaCheck] != NOTJAIL) {
// Jailbroken
motzart += 3;
}
// Inaccessible Files Check
if ([self inaccessibleFilesCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
// Plist Check
if ([self plistCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
// Check if iOS 8 or lower
if (SYSTEM_VERSION_LESS_THAN(@"9.0")) {
// Processes Check
if ([self processesCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
// FSTab Check
if ([self fstabCheck] != NOTJAIL) {
// Jailbroken
motzart += 1;
}
// Shell Check
if ([self systemCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
}
// Symbolic Link Check
if ([self symbolicLinkCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
// FilesExist Integrity Check
if ([self filesExistCheck] != NOTJAIL) {
// Jailbroken
motzart += 2;
}
// Check if the Jailbreak Integer is 3 or more
if (motzart >= 3) {
// Jailbroken
return KFJailbroken;
}
// Not Jailbroken
return NOTJAIL;
}
#pragma mark - Static Jailbreak Checks
// UIApplication CanOpenURL Check
+ (int)urlCheck {
@try {
#if !(defined(__has_feature) && __has_feature(attribute_availability_app_extension))
// Create a fake url for cydia
NSURL *FakeURL = [NSURL URLWithString:CYDIAPACKAGE];
// Return whether or not cydia's openurl item exists
if ([[UIApplication sharedApplication] canOpenURL:FakeURL])
return KFOpenURL;
#end
}
@catch (NSException *exception) {
// Error, return false
}
return NOTJAIL;
}
// Cydia Check
+ (int)cydiaCheck {
@try {
// Create a file path string
NSString *filePath = CYDIALOC;
// Check if it exists
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
// It exists
return KFCydia;
} else {
// It doesn't exist
return NOTJAIL;
}
}
@catch (NSException *exception) {
// Error, return false
return NOTJAIL;
}
}
// Inaccessible Files Check
+ (int)inaccessibleFilesCheck {
@try {
// Run through the array of files
for (NSString *key in HIDDENFILES) {
// Check if any of the files exist (should return no)
if ([[NSFileManager defaultManager] fileExistsAtPath:key]) {
// Jailbroken
return KFIFC;
}
}
// Shouldn't get this far, return jailbroken
return NOTJAIL;
}
@catch (NSException *exception) {
// Error, return false
return NOTJAIL;
}
}
// Plist Check
+ (int)plistCheck {
@try {
// Define the Executable name
NSString *ExeName = EXEPATH;
NSDictionary *ipl = PLISTPATH;
// Check if the plist exists
if ([FILECHECK ExeName] == FALSE || ipl == nil || ipl.count <= 0) {
// Executable file can't be found and the plist can't be found...hmmm
return KFPlist;
} else {
// Everything is good
return NOTJAIL;
}
}
@catch (NSException *exception) {
// Error, return false
return NOTJAIL;
}
}
// Running Processes Check
+ (int)processesCheck {
@try {
// Make a processes array
NSArray *processes = [self runningProcesses];
// Check for Cydia in the running processes
for (NSDictionary * dict in processes) {
// Define the process name
NSString *process = [dict objectForKey:@"ProcessName"];
// If the process is this executable
if ([process isEqualToString:CYDIA]) {
// Return Jailbroken
return KFProcessesCydia;
} else if ([process isEqualToString:OTHERCYDIA]) {
// Return Jailbroken
return KFProcessesOtherCydia;
} else if ([process isEqualToString:OOCYDIA]) {
// Return Jailbroken
return KFProcessesOtherOCydia;
}
}
// Not Jailbroken
return NOTJAIL;
}
@catch (NSException *exception) {
// Error
return NOTJAIL;
}
}
// FSTab Size
+ (int)fstabCheck {
@try {
struct stat sb;
stat("/etc/fstab", &sb);
long long size = sb.st_size;
if (size == 80) {
// Not jailbroken
return NOTJAIL;
} else
// Jailbroken
return KFFSTab;
}
@catch (NSException *exception) {
// Not jailbroken
return NOTJAIL;
}
}
// System() available
+ (int)systemCheck {
@try {
// See if the system call can be used
if (system(0)) {
// Jailbroken
return KFSystem;
} else
// Not Jailbroken
return NOTJAIL;
}
@catch (NSException *exception) {
// Not Jailbroken
return NOTJAIL;
}
}
// Symbolic Link available
+ (int)symbolicLinkCheck {
@try {
// See if the Applications folder is a symbolic link
struct stat s;
if (lstat("/Applications", &s) != 0) {
if (s.st_mode & S_IFLNK) {
// Device is jailbroken
return KFSymbolic;
} else
// Not jailbroken
return NOTJAIL;
} else {
// Not jailbroken
return NOTJAIL;
}
}
@catch (NSException *exception) {
// Not Jailbroken
return NOTJAIL;
}
}
// FileSystem working correctly?
+ (int)filesExistCheck {
@try {
// Check if filemanager is working
if (![FILECHECK [[NSBundle mainBundle] executablePath]]) {
// Jailbroken and trying to hide it
return KFFileExists;
} else
// Not Jailbroken
return NOTJAIL;
}
@catch (NSException *exception) {
// Not Jailbroken
return NOTJAIL;
}
}
// Get the running processes
+ (NSArray *)runningProcesses {
// Define the int array of the kernel's processes
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;
// Make a new size and int of the sysctl calls
size_t size = 0;
int st;
// Make new structs for the processes
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
// Do get all the processes while there are no errors
do {
// Add to the size
size += (size / 10);
// Get the new process
newprocess = realloc(process, size);
// If the process selected doesn't exist
if (!newprocess){
// But the process exists
if (process){
// Free the process
free(process);
}
// Return that nothing happened
return nil;
}
// Make the process equal
process = newprocess;
// Set the st to the next process
st = sysctl(mib, (int)miblen, process, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
// As long as the process list is empty
if (st == 0){
// And the size of the processes is 0
if (size % sizeof(struct kinfo_proc) == 0){
// Define the new process
int nprocess = (int)(size / sizeof(struct kinfo_proc));
// If the process exists
if (nprocess){
// Create a new array
NSMutableArray * array = [[NSMutableArray alloc] init];
// Run through a for loop of the processes
for (int i = nprocess - 1; i >= 0; i--){
// Get the process ID
NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
// Get the process Name
NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];
// Get the process Priority
NSString *processPriority = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_priority];
// Get the process running time
NSDate *processStartDate = [NSDate dateWithTimeIntervalSince1970:process[i].kp_proc.p_un.__p_starttime.tv_sec];
// Create a new dictionary containing all the process ID's and Name's
NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processPriority, processName, processStartDate, nil]
forKeys:[NSArray arrayWithObjects:@"ProcessID", @"ProcessPriority", @"ProcessName", @"ProcessStartDate", nil]];
// Add the dictionary to the array
[array addObject:dict];
}
// Free the process array
free(process);
// Return the process array
return array;
}
}
}
// Free the process array
free(process);
// If no processes are found, return nothing
return nil;
}
@end