|
@@ -8,22 +8,21 @@
|
|
#import <sys/types.h>
|
|
#import <sys/types.h>
|
|
#import <CommonCrypto/CommonDigest.h>
|
|
#import <CommonCrypto/CommonDigest.h>
|
|
#include <syslog.h>
|
|
#include <syslog.h>
|
|
|
|
+#import <Foundation/Foundation.h>
|
|
|
|
+#import <UIKit/UIKit.h>
|
|
|
|
|
|
#define PROC_PIDPATHINFO_MAXSIZE (1024)
|
|
#define PROC_PIDPATHINFO_MAXSIZE (1024)
|
|
int proc_pidpath(pid_t pid, void *buffer, uint32_t buffersize);
|
|
int proc_pidpath(pid_t pid, void *buffer, uint32_t buffersize);
|
|
|
|
|
|
-#define dylibDir @"/usr/lib/TweakInject"
|
|
|
|
|
|
+#define dylibDir @"/Library/TweakInject"
|
|
|
|
|
|
NSArray *sbinjectGenerateDylibList() {
|
|
NSArray *sbinjectGenerateDylibList() {
|
|
-
|
|
|
|
NSString *processName = [[NSProcessInfo processInfo] processName];
|
|
NSString *processName = [[NSProcessInfo processInfo] processName];
|
|
// launchctl, amfid you are special cases
|
|
// launchctl, amfid you are special cases
|
|
if ([processName isEqualToString:@"launchctl"]) {
|
|
if ([processName isEqualToString:@"launchctl"]) {
|
|
- HBLogInfo(@"launchctl exit");
|
|
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
if ([processName isEqualToString:@"amfid"]) {
|
|
if ([processName isEqualToString:@"amfid"]) {
|
|
- HBLogInfo(@"amfid exit");
|
|
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
// Create an array containing all the filenames in dylibDir (/opt/simject)
|
|
// Create an array containing all the filenames in dylibDir (/opt/simject)
|
|
@@ -33,8 +32,7 @@ NSArray *sbinjectGenerateDylibList() {
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
// Read current bundle identifier
|
|
// Read current bundle identifier
|
|
- NSString *bundleIdentifier = NSBundle.mainBundle.bundleIdentifier;
|
|
|
|
- //NSLog(@"bundleID: %@", bundleIdentifier);
|
|
|
|
|
|
+ //NSString *bundleIdentifier = NSBundle.mainBundle.bundleIdentifier;
|
|
// We're only interested in the plist files
|
|
// We're only interested in the plist files
|
|
NSArray *plists = [dylibDirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", @"plist"]];
|
|
NSArray *plists = [dylibDirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", @"plist"]];
|
|
// Create an empty mutable array that will contain a list of dylib paths to be injected into the target process
|
|
// Create an empty mutable array that will contain a list of dylib paths to be injected into the target process
|
|
@@ -42,8 +40,6 @@ NSArray *sbinjectGenerateDylibList() {
|
|
// Loop through the list of plists
|
|
// Loop through the list of plists
|
|
for (NSString *plist in plists) {
|
|
for (NSString *plist in plists) {
|
|
// We'll want to deal with absolute paths, so append the filename to dylibDir
|
|
// We'll want to deal with absolute paths, so append the filename to dylibDir
|
|
-
|
|
|
|
- //NSLog(@"plist: %@", plist);
|
|
|
|
NSString *plistPath = [dylibDir stringByAppendingPathComponent:plist];
|
|
NSString *plistPath = [dylibDir stringByAppendingPathComponent:plist];
|
|
NSDictionary *filter = [NSDictionary dictionaryWithContentsOfFile:plistPath];
|
|
NSDictionary *filter = [NSDictionary dictionaryWithContentsOfFile:plistPath];
|
|
// This boolean indicates whether or not the dylib has already been injected
|
|
// This boolean indicates whether or not the dylib has already been injected
|
|
@@ -62,41 +58,23 @@ NSArray *sbinjectGenerateDylibList() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Decide whether or not to load the dylib based on the Bundles values
|
|
// Decide whether or not to load the dylib based on the Bundles values
|
|
-
|
|
|
|
- NSArray *injectBundles = filter[@"Filter"][@"Bundles"];
|
|
|
|
- //NSLog(@"injectBundles: %@ vs %@", injectBundles, bundleIdentifier);
|
|
|
|
-
|
|
|
|
- if ([injectBundles containsObject:bundleIdentifier]){
|
|
|
|
-
|
|
|
|
- NSLog(@"inject bundles contains object: %@", bundleIdentifier);
|
|
|
|
-
|
|
|
|
- [dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
|
|
- isInjected = YES;
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //this code never worked for me on tvOS
|
|
|
|
for (NSString *entry in filter[@"Filter"][@"Bundles"]) {
|
|
for (NSString *entry in filter[@"Filter"][@"Bundles"]) {
|
|
// Check to see whether or not this bundle is actually loaded in this application or not
|
|
// Check to see whether or not this bundle is actually loaded in this application or not
|
|
if (!CFBundleGetBundleWithIdentifier((CFStringRef)entry)) {
|
|
if (!CFBundleGetBundleWithIdentifier((CFStringRef)entry)) {
|
|
// If not, skip it
|
|
// If not, skip it
|
|
- //NSLog(@"we not in here?: %@", entry);
|
|
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
isInjected = YES;
|
|
isInjected = YES;
|
|
- //NSLog(@"here?: %@", entry);
|
|
|
|
- continue;
|
|
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
-
|
|
|
|
if (!isInjected) {
|
|
if (!isInjected) {
|
|
// Decide whether or not to load the dylib based on the Executables values
|
|
// Decide whether or not to load the dylib based on the Executables values
|
|
for (NSString *process in filter[@"Filter"][@"Executables"]) {
|
|
for (NSString *process in filter[@"Filter"][@"Executables"]) {
|
|
if ([process isEqualToString:processName]) {
|
|
if ([process isEqualToString:processName]) {
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
isInjected = YES;
|
|
isInjected = YES;
|
|
- continue;
|
|
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -111,11 +89,10 @@ NSArray *sbinjectGenerateDylibList() {
|
|
// It's fine to add this dylib at this point
|
|
// It's fine to add this dylib at this point
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
[dylibsToInject addObject:[[plistPath stringByDeletingPathExtension] stringByAppendingString:@".dylib"]];
|
|
isInjected = YES;
|
|
isInjected = YES;
|
|
- continue;
|
|
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
[dylibsToInject sortUsingSelector:@selector(caseInsensitiveCompare:)];
|
|
[dylibsToInject sortUsingSelector:@selector(caseInsensitiveCompare:)];
|
|
return dylibsToInject;
|
|
return dylibsToInject;
|
|
}
|
|
}
|
|
@@ -126,11 +103,8 @@ int file_exist(char *filename) {
|
|
return (r == 0);
|
|
return (r == 0);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-@interface SpringBoard : NSObject
|
|
|
|
|
|
+@interface SpringBoard : UIApplication
|
|
- (BOOL)launchApplicationWithIdentifier:(NSString *)identifier suspended:(BOOL)suspended;
|
|
- (BOOL)launchApplicationWithIdentifier:(NSString *)identifier suspended:(BOOL)suspended;
|
|
-- (id)sharedApplication;
|
|
|
|
@end
|
|
@end
|
|
|
|
|
|
%group SafeMode
|
|
%group SafeMode
|
|
@@ -142,7 +116,7 @@ int file_exist(char *filename) {
|
|
return [newVariables autorelease];
|
|
return [newVariables autorelease];
|
|
}
|
|
}
|
|
%end
|
|
%end
|
|
-/*
|
|
|
|
|
|
+
|
|
%hook SBLockScreenManager
|
|
%hook SBLockScreenManager
|
|
-(BOOL)_finishUIUnlockFromSource:(int)arg1 withOptions:(id)arg2 {
|
|
-(BOOL)_finishUIUnlockFromSource:(int)arg1 withOptions:(id)arg2 {
|
|
BOOL ret = %orig;
|
|
BOOL ret = %orig;
|
|
@@ -156,7 +130,6 @@ int file_exist(char *filename) {
|
|
[(SpringBoard *)[%c(UIApplication) sharedApplication] launchApplicationWithIdentifier:@"org.coolstar.SafeMode" suspended:NO];
|
|
[(SpringBoard *)[%c(UIApplication) sharedApplication] launchApplicationWithIdentifier:@"org.coolstar.SafeMode" suspended:NO];
|
|
}
|
|
}
|
|
%end
|
|
%end
|
|
-*/
|
|
|
|
%end
|
|
%end
|
|
|
|
|
|
static BOOL isSpringBoardOrBackboard = NO;
|
|
static BOOL isSpringBoardOrBackboard = NO;
|
|
@@ -169,9 +142,11 @@ void SpringBoardSigHandler(int signo, siginfo_t *info, void *uap){
|
|
fprintf(f, "Hello World\n");
|
|
fprintf(f, "Hello World\n");
|
|
fclose(f);
|
|
fclose(f);
|
|
}
|
|
}
|
|
- FILE *f = fopen([[NSString stringWithFormat:@"%@/.safeMode-%@", NSTemporaryDirectory(), processHash] UTF8String], "w");
|
|
|
|
- fprintf(f, "Hello World!\n");
|
|
|
|
- fclose(f);
|
|
|
|
|
|
+ if (processHash){
|
|
|
|
+ FILE *f = fopen([[NSString stringWithFormat:@"%@/.safeMode-%@", NSTemporaryDirectory(), processHash] UTF8String], "w");
|
|
|
|
+ fprintf(f, "Hello World!\n");
|
|
|
|
+ fclose(f);
|
|
|
|
+ }
|
|
|
|
|
|
raise(signo);
|
|
raise(signo);
|
|
}
|
|
}
|
|
@@ -179,21 +154,30 @@ void SpringBoardSigHandler(int signo, siginfo_t *info, void *uap){
|
|
__attribute__ ((constructor))
|
|
__attribute__ ((constructor))
|
|
static void ctor(void) {
|
|
static void ctor(void) {
|
|
@autoreleasepool {
|
|
@autoreleasepool {
|
|
|
|
+ unsetenv("DYLD_INSERT_LIBRARIES");
|
|
|
|
+
|
|
if (NSBundle.mainBundle.bundleIdentifier == nil || ![NSBundle.mainBundle.bundleIdentifier isEqualToString:@"org.coolstar.SafeMode"]){
|
|
if (NSBundle.mainBundle.bundleIdentifier == nil || ![NSBundle.mainBundle.bundleIdentifier isEqualToString:@"org.coolstar.SafeMode"]){
|
|
char pathbuf[PROC_PIDPATHINFO_MAXSIZE] = {0};
|
|
char pathbuf[PROC_PIDPATHINFO_MAXSIZE] = {0};
|
|
int ret = proc_pidpath(getpid(), pathbuf, sizeof(pathbuf));
|
|
int ret = proc_pidpath(getpid(), pathbuf, sizeof(pathbuf));
|
|
if (ret > 0){
|
|
if (ret > 0){
|
|
- uint8_t digest[CC_SHA1_DIGEST_LENGTH];
|
|
|
|
|
|
+ NSString *pathStr = [[NSString stringWithUTF8String:pathbuf] stringByResolvingSymlinksInPath];
|
|
|
|
+ NSLog(@"TweakInject: Loading for binary %@", pathStr.lastPathComponent);
|
|
|
|
+
|
|
|
|
+ if ([pathStr hasPrefix:@"/Applications"] || [pathStr hasPrefix:@"/var/containers/Bundle/Application"]){
|
|
|
|
+ processHash = nil;
|
|
|
|
+ } else {
|
|
|
|
+ uint8_t digest[CC_SHA1_DIGEST_LENGTH];
|
|
|
|
|
|
- CC_SHA1(pathbuf, ret, digest);
|
|
|
|
|
|
+ CC_SHA1(pathbuf, ret, digest);
|
|
|
|
|
|
- NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
|
|
|
|
|
|
+ NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
|
|
|
|
|
|
- for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
|
|
|
|
- {
|
|
|
|
- [output appendFormat:@"%02x", digest[i]];
|
|
|
|
|
|
+ for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
|
|
|
|
+ {
|
|
|
|
+ [output appendFormat:@"%02x", digest[i]];
|
|
|
|
+ }
|
|
|
|
+ processHash = [[NSString alloc] initWithString:output];
|
|
}
|
|
}
|
|
- processHash = [[NSString alloc] initWithString:output];
|
|
|
|
}
|
|
}
|
|
|
|
|
|
safeMode = false;
|
|
safeMode = false;
|
|
@@ -231,10 +215,12 @@ static void ctor(void) {
|
|
dlopen("/usr/lib/TweakInjectMapsCheck.dylib", RTLD_LAZY | RTLD_GLOBAL);
|
|
dlopen("/usr/lib/TweakInjectMapsCheck.dylib", RTLD_LAZY | RTLD_GLOBAL);
|
|
}
|
|
}
|
|
|
|
|
|
- const char *safeModeByProcPath = [[NSString stringWithFormat:@"%@/.safeMode-%@", NSTemporaryDirectory(), processHash] UTF8String];
|
|
|
|
- if (file_exist((char *)safeModeByProcPath)){
|
|
|
|
- safeMode = true;
|
|
|
|
- unlink(safeModeByProcPath);
|
|
|
|
|
|
+ if (processHash){
|
|
|
|
+ const char *safeModeByProcPath = [[NSString stringWithFormat:@"%@/.safeMode-%@", NSTemporaryDirectory(), processHash] UTF8String];
|
|
|
|
+ if (file_exist((char *)safeModeByProcPath)){
|
|
|
|
+ safeMode = true;
|
|
|
|
+ unlink(safeModeByProcPath);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (getenv("_MSSafeMode")){
|
|
if (getenv("_MSSafeMode")){
|
|
@@ -254,12 +240,7 @@ static void ctor(void) {
|
|
}
|
|
}
|
|
|
|
|
|
if (!safeMode){
|
|
if (!safeMode){
|
|
-
|
|
|
|
- //HBLogInfo(@"In bundle: %@", NSBundle.mainBundle.bundleIdentifier);
|
|
|
|
-
|
|
|
|
- NSArray *theList = sbinjectGenerateDylibList();
|
|
|
|
- //HBLogInfo(@"theList: %@", theList);
|
|
|
|
- for (NSString *dylib in theList) {
|
|
|
|
|
|
+ for (NSString *dylib in sbinjectGenerateDylibList()) {
|
|
NSLog(@"Injecting %@", dylib);
|
|
NSLog(@"Injecting %@", dylib);
|
|
void *dl = dlopen([dylib UTF8String], RTLD_LAZY | RTLD_GLOBAL);
|
|
void *dl = dlopen([dylib UTF8String], RTLD_LAZY | RTLD_GLOBAL);
|
|
|
|
|
|
@@ -272,4 +253,4 @@ static void ctor(void) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+}
|