Skip to content

Commit

Permalink
switching to manual hooks for some C functions, remove dependency on …
Browse files Browse the repository at this point in the history
…Cephei, optimize caching
  • Loading branch information
jjolano committed Nov 23, 2022
1 parent 6ee4d47 commit 7c7d952
Show file tree
Hide file tree
Showing 24 changed files with 351 additions and 307 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ARCHS = armv7 arm64 arm64e
TARGET = iphone:clang:13.0:7.0
TARGET = iphone:clang:14.5:5.0

include $(THEOS)/makefiles/common.mk
SUBPROJECTS += dylib
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ A jailbreak detection bypass for modern iOS jailbreaks.
## Issues
Please note that Shadow is **not** designed as an app-specific bypass. Issues mainly in consideration are non-detection related app crashes, regressions from previous versions, and compatibility issues.

## Compatibility
Shadow should work on at least iOS 7 with any Cydia Substrate-compatible jailbreak.

## Installation
Add my repo (`https://ios.jjolano.me`) to your package manager and install the Shadow (`me.jjolano.shadow`) package. Alternatively, download the [latest release](https://github.com/jjolano/shadow/releases) directly from GitHub and open the file with your package manager.

Expand Down
15 changes: 3 additions & 12 deletions api/Shadow.m
Original file line number Diff line number Diff line change
Expand Up @@ -204,21 +204,12 @@ - (BOOL)isPathRestricted:(NSString *)path resolve:(BOOL)resolve {

if([path hasPrefix:@"/var/containers"]
|| [path hasPrefix:@"/var/mobile/Containers"]
|| [path hasPrefix:@"/System"]) {
|| [path hasPrefix:@"/System"]
|| [path hasPrefix:bundlePath]
|| [path hasPrefix:homePath]) {
return NO;
}

// Recurse call into parent directories.
NSString* pathParent = [path stringByDeletingLastPathComponent];

if(![pathParent isEqualToString:@"/"]) {
BOOL isParentPathRestricted = [self isPathRestricted:pathParent resolve:NO];

if(isParentPathRestricted) {
return YES;
}
}

// Check if path is restricted from ShadowService.
if(service && [service isPathRestricted:path]) {
HBLogDebug(@"%@: %@: %@", @"isPathRestricted", @"restricted", path);
Expand Down
7 changes: 5 additions & 2 deletions api/ShadowService.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#import <Foundation/Foundation.h>

#define BYPASS_VERSION "4.1"
#define API_VERSION "3.1"
#define BYPASS_VERSION "4.2"
#define API_VERSION "3.2"

#define SHADOW_PREFS_PLIST "/var/mobile/Library/Preferences/me.jjolano.shadow.plist"
#define CPDMC_SERVICE_NAME "me.jjolano.shadow.service"
#define LOCAL_SERVICE_DB "/Library/Shadow/db.plist"

Expand All @@ -18,4 +19,6 @@
- (BOOL)isPathRestricted:(NSString *)path;
- (NSArray*)getURLSchemes;
- (NSDictionary *)getVersions;

+ (NSUserDefaults *)getPreferences;
@end
66 changes: 55 additions & 11 deletions api/ShadowService.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ - (BOOL)isPathRestricted_internal:(NSString *)path {
return [responseCachePath boolValue];
}

// Recurse call into parent directories.
NSString* pathParent = [path stringByDeletingLastPathComponent];

if(![pathParent isEqualToString:@"/"]) {
BOOL isParentPathRestricted = [self isPathRestricted_internal:pathParent];

if(isParentPathRestricted) {
return YES;
}
}

BOOL restricted = NO;

NSArray* base_extra = @[
Expand Down Expand Up @@ -107,6 +96,19 @@ - (BOOL)isPathRestricted_internal:(NSString *)path {
}
}

if(!restricted) {
// Recurse call into parent directories.
NSString* pathParent = [path stringByDeletingLastPathComponent];

if(![pathParent isEqualToString:@"/"]) {
BOOL isParentPathRestricted = [self isPathRestricted_internal:pathParent];

if(isParentPathRestricted) {
return YES;
}
}
}

[responseCache setObject:@(restricted) forKey:path];
return restricted;
}
Expand Down Expand Up @@ -440,6 +442,14 @@ - (BOOL)isPathRestricted:(NSString *)path {
}];

if(response) {
if(![response[@"restricted"] boolValue]) {
BOOL responseParent = [self isPathRestricted:[path stringByDeletingLastPathComponent]];

if(responseParent) {
return YES;
}
}

[responseCache setObject:response[@"restricted"] forKey:path];
return [response[@"restricted"] boolValue];
}
Expand All @@ -465,6 +475,40 @@ - (NSDictionary *)getVersions {
};
}

+ (NSDictionary *)getDefaultPreferences {
return @{
@"Global_Enabled" : @(NO),
@"Global_Service" : @(NO),
@"Use_LocalService" : @(NO),
@"Tweak_CompatEx" : @(NO),
@"Hook_Filesystem" : @(YES),
@"Hook_DynamicLibraries" : @(YES),
@"Hook_URLScheme" : @(YES),
@"Hook_EnvVars" : @(YES),
@"Hook_FilesystemExtra" : @(NO),
@"Hook_Foundation" : @(NO),
@"Hook_DeviceCheck" : @(YES),
@"Hook_MachBootstrap" : @(NO),
@"Hook_SymLookup" : @(NO),
@"Hook_LowLevelC" : @(NO),
@"Hook_AntiDebugging" : @(NO),
@"Hook_DynamicLibrariesExtra" : @(NO),
@"Hook_ObjCRuntime" : @(NO),
@"Hook_FakeMac" : @(NO),
@"Hook_Syscall" : @(NO),
@"Hook_Sandbox" : @(NO)
};
}

+ (NSUserDefaults *)getPreferences {
NSUserDefaults* result = [[NSUserDefaults alloc] initWithSuiteName:@SHADOW_PREFS_PLIST];

// Register default preferences.
[result registerDefaults:[self getDefaultPreferences]];

return result;
}

- (instancetype)init {
if((self = [super init])) {
responseCache = [NSCache new];
Expand Down
4 changes: 1 addition & 3 deletions dylib/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
ARCHS ?= armv7 arm64 arm64e
TARGET ?= iphone:clang:13.0:7.0
INSTALL_TARGET_PROCESSES = SpringBoard

include $(THEOS)/makefiles/common.mk
Expand All @@ -12,7 +10,7 @@ ShadowAPI = $(wildcard ../api/*.m)
Shadow_FILES = $(ShadowHooks) $(ShadowAPI) dylib.x
Shadow_LIBRARIES = rocketbootstrap
Shadow_FRAMEWORKS = Foundation UIKit CoreFoundation
Shadow_EXTRA_FRAMEWORKS = Cephei
Shadow_EXTRA_FRAMEWORKS =
Shadow_PRIVATE_FRAMEWORKS = AppSupport
Shadow_CFLAGS = -fobjc-arc -DROCKETBOOTSTRAP_LOAD_DYNAMIC -DTHEOS_LEAN_AND_MEAN

Expand Down
74 changes: 25 additions & 49 deletions dylib/dylib.x
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#import <HBLog.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <Cephei/HBPreferences.h>

#import "../api/Shadow.h"
#import "../api/ShadowService.h"
#import "hooks/hooks.h"

Shadow* _shadow = nil;
ShadowService* _srv = nil;
NSUserDefaults* prefs;

%group hook_springboard
%hook SpringBoard
Expand All @@ -31,31 +31,7 @@ ShadowService* _srv = nil;

%ctor {
// Load preferences.
HBPreferences* prefs = [HBPreferences preferencesForIdentifier:@"me.jjolano.shadow"];

// Register default preferences.
[prefs registerDefaults:@{
@"Global_Enabled" : @(NO),
@"Global_Service" : @(NO),
@"Use_LocalService" : @(NO),
@"Tweak_CompatEx" : @(NO),
@"Hook_Filesystem" : @(YES),
@"Hook_DynamicLibraries" : @(YES),
@"Hook_URLScheme" : @(YES),
@"Hook_EnvVars" : @(YES),
@"Hook_FilesystemExtra" : @(NO),
@"Hook_Foundation" : @(NO),
@"Hook_DeviceCheck" : @(YES),
@"Hook_MachBootstrap" : @(NO),
@"Hook_SymLookup" : @(NO),
@"Hook_LowLevelC" : @(NO),
@"Hook_AntiDebugging" : @(NO),
@"Hook_DynamicLibrariesExtra" : @(NO),
@"Hook_ObjCRuntime" : @(NO),
@"Hook_FakeMac" : @(NO),
@"Hook_Syscall" : @(NO),
@"Hook_Sandbox" : @(NO)
}];
prefs = [ShadowService getPreferences];

// Determine the application we're injected into.
NSString* bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
Expand All @@ -66,7 +42,7 @@ ShadowService* _srv = nil;
if([bundleIdentifier isEqualToString:@"com.apple.springboard"] || [[executablePath lastPathComponent] isEqualToString:@"SpringBoard"]) {
_srv = [ShadowService new];

if(prefs[@"Global_Service"] && [prefs[@"Global_Service"] boolValue]) {
if([prefs boolForKey:@"Global_Service"]) {
[_srv startService];
HBLogDebug(@"%@", @"started ShadowService");
}
Expand All @@ -90,34 +66,34 @@ ShadowService* _srv = nil;
// Determine whether to load the rest of the tweak.
// Load app-specific settings, if enabled.
NSDictionary* prefs_load = nil;
NSDictionary* prefs_app = prefs[bundleIdentifier];
NSDictionary* prefs_app = [prefs objectForKey:bundleIdentifier];

if(prefs_app && prefs_app[@"App_Override"] && [prefs_app[@"App_Override"] boolValue]) {
enabled = prefs_app[@"App_Enabled"] ? [prefs_app[@"App_Enabled"] boolValue] : NO;
enabled = prefs_app[@"App_Enabled"] && [prefs_app[@"App_Enabled"] boolValue];
prefs_load = prefs_app;
}

if(!prefs_load) {
enabled = [prefs[@"Global_Enabled"] boolValue];
enabled = [prefs boolForKey:@"Global_Enabled"];
prefs_load = @{
@"Use_LocalService" : prefs[@"Use_LocalService"],
@"Tweak_CompatEx" : prefs[@"Tweak_CompatEx"],
@"Hook_Filesystem" : prefs[@"Hook_Filesystem"],
@"Hook_DynamicLibraries" : prefs[@"Hook_DynamicLibraries"],
@"Hook_URLScheme" : prefs[@"Hook_URLScheme"],
@"Hook_EnvVars" : prefs[@"Hook_EnvVars"],
@"Hook_FilesystemExtra" : prefs[@"Hook_FilesystemExtra"],
@"Hook_Foundation" : prefs[@"Hook_Foundation"],
@"Hook_DeviceCheck" : prefs[@"Hook_DeviceCheck"],
@"Hook_MachBootstrap" : prefs[@"Hook_MachBootstrap"],
@"Hook_SymLookup" : prefs[@"Hook_SymLookup"],
@"Hook_LowLevelC" : prefs[@"Hook_LowLevelC"],
@"Hook_AntiDebugging" : prefs[@"Hook_AntiDebugging"],
@"Hook_DynamicLibrariesExtra" : prefs[@"Hook_DynamicLibrariesExtra"],
@"Hook_ObjCRuntime" : prefs[@"Hook_ObjCRuntime"],
@"Hook_FakeMac" : prefs[@"Hook_FakeMac"],
@"Hook_Syscall" : prefs[@"Hook_Syscall"],
@"Hook_Sandbox" : prefs[@"Hook_Sandbox"]
@"Use_LocalService" : @([prefs boolForKey:@"Use_LocalService"]),
@"Tweak_CompatEx" : @([prefs boolForKey:@"Tweak_CompatEx"]),
@"Hook_Filesystem" : @([prefs boolForKey:@"Hook_Filesystem"]),
@"Hook_DynamicLibraries" : @([prefs boolForKey:@"Hook_DynamicLibraries"]),
@"Hook_URLScheme" : @([prefs boolForKey:@"Hook_URLScheme"]),
@"Hook_EnvVars" : @([prefs boolForKey:@"Hook_EnvVars"]),
@"Hook_FilesystemExtra" : @([prefs boolForKey:@"Hook_FilesystemExtra"]),
@"Hook_Foundation" : @([prefs boolForKey:@"Hook_Foundation"]),
@"Hook_DeviceCheck" : @([prefs boolForKey:@"Hook_DeviceCheck"]),
@"Hook_MachBootstrap" : @([prefs boolForKey:@"Hook_MachBootstrap"]),
@"Hook_SymLookup" : @([prefs boolForKey:@"Hook_SymLookup"]),
@"Hook_LowLevelC" : @([prefs boolForKey:@"Hook_LowLevelC"]),
@"Hook_AntiDebugging" : @([prefs boolForKey:@"Hook_AntiDebugging"]),
@"Hook_DynamicLibrariesExtra" : @([prefs boolForKey:@"Hook_DynamicLibrariesExtra"]),
@"Hook_ObjCRuntime" : @([prefs boolForKey:@"Hook_ObjCRuntime"]),
@"Hook_FakeMac" : @([prefs boolForKey:@"Hook_FakeMac"]),
@"Hook_Syscall" : @([prefs boolForKey:@"Hook_Syscall"]),
@"Hook_Sandbox" : @([prefs boolForKey:@"Hook_Sandbox"])
};
}

Expand All @@ -132,7 +108,7 @@ ShadowService* _srv = nil;

BOOL LocalShadowService = prefs_load[@"Use_LocalService"] && [prefs_load[@"Use_LocalService"] boolValue];

if(LocalShadowService || !prefs[@"Global_Service"] || ![prefs[@"Global_Service"] boolValue]) {
if(LocalShadowService || ![prefs boolForKey:@"Global_Service"]) {
[_srv startLocalService];
} else {
[_srv connectService];
Expand Down
Loading

0 comments on commit 7c7d952

Please sign in to comment.