Skip to content

Commit

Permalink
Ios jailbreak bybass detect (#3838)
Browse files Browse the repository at this point in the history
* feat: add ios jailbreak detection via build hint

new build hint ios.detectJailbreak=true|false

* fixup

* fix compile errors
  • Loading branch information
shannah authored Sep 8, 2024
1 parent 97f9b18 commit ea6553d
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 3 deletions.
26 changes: 26 additions & 0 deletions Ports/iOSPort/nativeSources/CN1JailbreakDetector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
//#define CN1_DETECT_JAILBREAK 1
#ifdef CN1_DETECT_JAILBREAK
void cn1DetectJailbreakBypassesAndExit();
#endif
108 changes: 108 additions & 0 deletions Ports/iOSPort/nativeSources/CN1JailbreakDetector.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/

#import "CN1JailbreakDetector.h"
#ifdef CN1_DETECT_JAILBREAK
#import <UIKit/UIKit.h>
#import <dlfcn.h>
#import <sys/sysctl.h>
#import <mach-o/dyld.h>

void cn1DetectJailbreakBypassesAndExit() {
#if (TARGET_IPHONE_SIMULATOR)
return;
#endif
// List of known libraries used by bypass tools like Liberty Lite and Substrate
NSArray *bypassLibraries = @[
@"LibertyLite.dylib",
@"Substrate.dylib",
@"MobileSubstrate.dylib",
@"SubstrateInserter.dylib",
@"tsProtector.dylib",
@"FridaGadget"
];

// Check all loaded dynamic libraries
for (int i = 0; i < _dyld_image_count(); i++) {
const char *imageName = _dyld_get_image_name(i);
NSString *libraryName = [NSString stringWithUTF8String:imageName];

// Check if the library name matches any known bypass tool libraries
for (NSString *bypassLibrary in bypassLibraries) {
if ([libraryName containsString:bypassLibrary]) {
// Jailbreak bypass detected, exit the app
NSLog(@"Bypass library detected: %@", bypassLibrary);
exit(0); // Exit the app if a bypass tool is detected
}
}
}

// Additional check for file access to system areas (indicates potential bypass)
NSArray *restrictedPaths = @[
@"/Applications/Cydia.app",
@"/usr/sbin/sshd",
@"/bin/bash",
@"/etc/apt",
@"/Library/MobileSubstrate/MobileSubstrate.dylib"
];

NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSString *path in restrictedPaths) {
if ([fileManager fileExistsAtPath:path]) {
// Jailbreak files detected, exit the app
NSLog(@"Jailbreak-related file detected: %@", path);
exit(0); // Exit the app if a jailbreak-related file is found
}
}

// Check if we can write to a restricted area (bypasses may allow this)
NSString *testPath = @"/private/jailbreakTest.txt";
NSError *error;
[@"Test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!error) {
// Able to write to restricted area, exit the app
NSLog(@"Write access to restricted area detected.");
exit(0); // Exit the app if write access to restricted areas is detected
}

// Check for abnormal system behavior like successful fork()
if (fork() == 0) {
// fork() should not succeed on non-jailbroken devices, exit if it does
NSLog(@"Fork succeeded, indicating jailbreak bypass.");
exit(0); // Exit the app if fork() succeeds
}

// Check for process tracing (which could indicate Liberty Lite tampering)
struct kinfo_proc info;
size_t size = sizeof(info);
int name[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
if (sysctl(name, 4, &info, &size, NULL, 0) == 0 && (info.kp_proc.p_flag & P_TRACED) != 0) {
// Process is being traced, likely due to a jailbreak bypass
NSLog(@"Process tracing detected, indicating jailbreak bypass.");
exit(0); // Exit the app if process tracing is detected
}

// If no jailbreak bypass was detected, the app continues as normal
NSLog(@"No jailbreak bypass detected.");
}
#endif
4 changes: 4 additions & 0 deletions Ports/iOSPort/nativeSources/CodenameOne_GLAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* need additional information or have any questions.
*/
#import "CodenameOne_GLAppDelegate.h"
#import "CN1JailbreakDetector.h"
#include "xmlvm.h"
#import "EAGLView.h"
#import "CodenameOne_GLViewController.h"
Expand Down Expand Up @@ -115,6 +116,9 @@ @implementation CodenameOne_GLAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef CN1_DETECT_JAILBREAK
cn1DetectJailbreakBypassesAndExit();
#endif
//beforeDidFinishLaunchingWithOptionsMarkerEntry

// Override point for customization after application launch.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class IPhoneBuilder extends Executor {
// which adds localized strings files to the project.
private StringBuilder installLocalizedStringsScript = new StringBuilder();

private boolean detectJailbreak;

private boolean runPods=false;
private boolean photoLibraryUsage;
private String buildVersion;
Expand Down Expand Up @@ -212,6 +214,7 @@ private int getDeploymentTargetInt(BuildRequest request) {
@Override
public boolean build(File sourceZip, BuildRequest request) throws BuildException {
addMinDeploymentTarget(DEFAULT_MIN_DEPLOYMENT_VERSION);
detectJailbreak = request.getArg("ios.detectJailbreak", "false").equals("true");
defaultEnvironment.put("LANG", "en_US.UTF-8");
tmpFile = tmpDir = getBuildDirectory();
useMetal = "true".equals(request.getArg("ios.metal", "false"));
Expand Down Expand Up @@ -939,9 +942,6 @@ public void usesClassMethod(String cls, String method) {
+ " }\n"
+ " });\n";




try (OutputStream stubSourceStream = new FileOutputStream(new File(stubSource, request.getMainClass() + "Stub.java"))) {
String stubSourceCode = "package " + request.getPackageName() + ";\n\n"
+ "import com.codename1.ui.*;\n"
Expand Down Expand Up @@ -1283,6 +1283,11 @@ public void usesClassMethod(String cls, String method) {
replaceInFile(glAppDelegate, "//GL_APP_DELEGATE_INCLUDE", glAppDelegeateHeader);
}

File jailbreakH = new File(buildinRes, "CN1JailbreakDetector.h");
if (jailbreakH.exists() && detectJailbreak) {
replaceInFile(jailbreakH, "//#define CN1_DETECT_JAILBREAK", "#define CN1_DETECT_JAILBREAK");
}

String glAppDelegeateBody = request.getArg("ios.glAppDelegateBody", null);
if (glAppDelegeateBody != null && glAppDelegeateBody.length() > 0) {
replaceInFile(glAppDelegate, "//GL_APP_DELEGATE_BODY", glAppDelegeateBody);
Expand Down

0 comments on commit ea6553d

Please sign in to comment.