diff --git a/RootHelperSample/launchdshim/generalhook/main.m b/RootHelperSample/launchdshim/generalhook/main.m index 368aec7..f25b21b 100644 --- a/RootHelperSample/launchdshim/generalhook/main.m +++ b/RootHelperSample/launchdshim/generalhook/main.m @@ -211,6 +211,12 @@ void applySandboxExtensions(void) break; } } - // NSLog(@"generalhook - loading tweaks for pid %d", getpid()); - dlopen(jbroot(@"/basebin/bootstrap.dylib").UTF8String, RTLD_GLOBAL | RTLD_NOW); + NSLog(@"generalhook - loading tweaks for pid %d", getpid()); + // dlopen([jbroot(@"/usr/lib/roothideinit.dylib") UTF8String], RTLD_NOW); + // dlopen([jbroot(@"/usr/lib/roothidepatch.dylib") UTF8String], RTLD_NOW); + const char* oldJBROOT = getenv("JBROOT"); + setenv("JBROOT", [jbroot(@"/") UTF8String], 1); + dlopen([jbroot(@"/usr/lib/TweakLoader.dylib") UTF8String], RTLD_NOW); + if(oldJBROOT) setenv("JBROOT", oldJBROOT, 1); else unsetenv("JBROOT"); + // dlopen(jbroot(@"/basebin/bootstrap.dylib").UTF8String, RTLD_GLOBAL | RTLD_NOW); } diff --git a/RootHelperSample/launchdshim/launchdhook/README.md b/RootHelperSample/launchdshim/launchdhook/README.md index 17d0ef2..9522bd4 100644 --- a/RootHelperSample/launchdshim/launchdhook/README.md +++ b/RootHelperSample/launchdshim/launchdhook/README.md @@ -1,3 +1,5 @@ -# FBWrite - -Write text to the framebuffer, with style. \ No newline at end of file +# launchdhook +## Consists of: +* launchdhook itself +* jbserver that does systemcheckin for generalhook +* jitterd -> daemon that systemcheckin calls to ptrace binaries \ No newline at end of file diff --git a/RootHelperSample/launchdshim/launchdhook/control b/RootHelperSample/launchdshim/launchdhook/control deleted file mode 100644 index 5315e07..0000000 --- a/RootHelperSample/launchdshim/launchdhook/control +++ /dev/null @@ -1,9 +0,0 @@ -Package: ca.bomberfish.fbwrite -Name: FBWrite -Version: 0.0.1 -Architecture: iphoneos-arm -Description: Write to the framebuffer with style. -Maintainer: BomberFish Industries -Author: BomberFish Industries -Section: System -Tag: role::hacker diff --git a/RootHelperSample/launchdshim/launchdhook/jitter/jitterd.plist b/RootHelperSample/launchdshim/launchdhook/jitter/jitterd.plist index 3825075..2d19fd8 100644 --- a/RootHelperSample/launchdshim/launchdhook/jitter/jitterd.plist +++ b/RootHelperSample/launchdshim/launchdhook/jitter/jitterd.plist @@ -18,7 +18,7 @@ ProgramArguments - jitterd + /jitterd UserName root diff --git a/RootHelperSample/launchdshim/launchdhook/main.m b/RootHelperSample/launchdshim/launchdhook/main.m index 3075805..2e81df4 100644 --- a/RootHelperSample/launchdshim/launchdhook/main.m +++ b/RootHelperSample/launchdshim/launchdhook/main.m @@ -19,22 +19,14 @@ #include "jbserver/log.h" #include "xpc_hook.h" -#define PT_DETACH 11 /* stop tracing a process */ -#define PT_ATTACHEXC 14 /* attach to running process with signal exception */ #define __probable(x) __builtin_expect(!!(x), 1) #define __improbable(x) __builtin_expect(!!(x), 0) - -int ptrace(int request, pid_t pid, caddr_t addr, int data); - #define INSTALLD_PATH "/usr/libexec/installd" #define NFCD_PATH "/usr/libexec/nfcd" +#define MEDIASERVERD_PATH "/usr/sbin/mediaserverd" #define SPRINGBOARD_PATH "/System/Library/CoreServices/SpringBoard.app/SpringBoard" #define MRUI_PATH "/Applications/MediaRemoteUI.app/MediaRemoteUI" #define XPCPROXY_PATH "/usr/libexec/xpcproxy" -#define MEDIASERVERD_PATH "/usr/sbin/mediaserverd" - -void abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char *reason_string, uint64_t reason_flags); - #define MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT 6 #define POSIX_SPAWNATTR_OFF_MEMLIMIT_ACTIVE 0x48 #define POSIX_SPAWNATTR_OFF_MEMLIMIT_INACTIVE 0x4C @@ -157,7 +149,6 @@ int hooked_posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_acti char HOOK_DYLIB_PATH[PATH_MAX] = {0}; bool shouldWeGamble = true; int hooked_posix_spawnp(pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *restrict file_actions, posix_spawnattr_t *attrp, char *argv[restrict], char *const envp[restrict]) { - change_launchtype(attrp, path); if (!strncmp(path, SPRINGBOARD_PATH, strlen(SPRINGBOARD_PATH))) { // log_path(path, jbroot(SPRINGBOARD_PATH)); path = jbroot(SPRINGBOARD_PATH); @@ -186,15 +177,16 @@ int hooked_posix_spawnp(pid_t *restrict pid, const char *restrict path, const po do_kclose(); shouldWeGamble = false; } - } else if (!strncmp(path, MEDIASERVERD_PATH, strlen(MEDIASERVERD_PATH))) { - path = jbroot(MEDIASERVERD_PATH); - argv[0] = (char *)path; - posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); - } else if (!strncmp(path, NFCD_PATH, strlen(NFCD_PATH))) { - path = jbroot(NFCD_PATH); - argv[0] = (char *)path; - posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); } + // } else if (!strncmp(path, MEDIASERVERD_PATH, strlen(MEDIASERVERD_PATH))) { + // path = jbroot(MEDIASERVERD_PATH); + // argv[0] = (char *)path; + // posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); + // } else if (!strncmp(path, NFCD_PATH, strlen(NFCD_PATH))) { + // path = jbroot(NFCD_PATH); + // argv[0] = (char *)path; + // posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); + // } return orig_posix_spawnp(pid, path, file_actions, (posix_spawnattr_t *)attrp, argv, envp); } @@ -204,6 +196,22 @@ bool hook_xpc_dictionary_get_bool(xpc_object_t dictionary, const char *key) { if (!strcmp(key, "LogPerformanceStatistics")) return true; else return xpc_dictionary_get_bool_orig(dictionary, key); } +bool jbrootUpdated = false; +void patchJbrootLaunchDaemonPlist(NSString *plistPath) +{ + NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath]; + if (plistDict) { + NSMutableArray *programArguments = ((NSArray *)plistDict[@"ProgramArguments"]).mutableCopy; + if (programArguments.count >= 1) { + NSString *pathBefore = programArguments[0]; + if (![pathBefore hasPrefix:@"/var/containers/Bundle"]) { + programArguments[0] = jbroot(pathBefore); + plistDict[@"ProgramArguments"] = [programArguments copy]; + [plistDict writeToFile:plistPath atomically:YES]; + } + } + } +} xpc_object_t hook_xpc_dictionary_get_value(xpc_object_t dict, const char *key) { xpc_object_t retval = xpc_dictionary_get_value_orig(dict, key); @@ -241,11 +249,13 @@ int memorystatus_control_hook(uint32_t command, int32_t pid, uint32_t flags, voi // crashreporter_start(); // customLog("launchdhook is running"); if(gSystemInfo.jailbreakInfo.rootPath) free(gSystemInfo.jailbreakInfo.rootPath); - NSString* jbroot_path = find_jbroot(); - if(jbroot_path) { - gSystemInfo.jailbreakInfo.rootPath = strdup(jbroot_path.fileSystemRepresentation); - gSystemInfo.jailbreakInfo.jbrand = jbrand(); + gSystemInfo.jailbreakInfo.rootPath = strdup(jbroot_path.fileSystemRepresentation); + gSystemInfo.jailbreakInfo.jbrand = jbrand(); + + if (__improbable(!jbrootUpdated)) { + patchJbrootLaunchDaemonPlist([NSString stringWithUTF8String:jbroot("/Library/LaunchDaemons/com.hrtowii.jitterd.plist")]); + jbrootUpdated = true; } initXPCHooks(); setenv("DYLD_INSERT_LIBRARIES", jbroot("/launchdhook.dylib"), 1); @@ -257,10 +267,10 @@ int memorystatus_control_hook(uint32_t command, int32_t pid, uint32_t flags, voi // We could try to change the boot time ourselves, but I'm worried of potential side effects // So we just wipe the offending preferences ourselves // In practice this fixes nano launch daemons not being loaded after the userspace reboot, resulting in certain apple watch features breaking - if (!access("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRRootCommander.volatile.plist", W_OK)) { + if (__probable(!access("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRRootCommander.volatile.plist", W_OK))) { remove("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRRootCommander.volatile.plist"); } - if (!access("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRLaunchNotificationController.volatile.plist", W_OK)) { + if (__probable(!access("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRLaunchNotificationController.volatile.plist", W_OK))) { remove("/var/mobile/Library/Preferences/com.apple.NanoRegistry.NRLaunchNotificationController.volatile.plist"); } struct rebinding rebindings[] = (struct rebinding[]){ diff --git a/RootHelperSample/launchdshim/xpcproxyhook/xpcproxyhook.m b/RootHelperSample/launchdshim/xpcproxyhook/xpcproxyhook.m index c245c6d..00a670e 100644 --- a/RootHelperSample/launchdshim/xpcproxyhook/xpcproxyhook.m +++ b/RootHelperSample/launchdshim/xpcproxyhook/xpcproxyhook.m @@ -39,28 +39,27 @@ int hooked_csops_audittoken(pid_t pid, unsigned int ops, void * useraddr, size_t } return result; } -const char *installd = "/usr/libexec/installd"; -const char *nfcd = "/usr/libexec/nfcd"; -const char *mediaserverd = "/usr/sbin/mediaserverd"; +#define INSTALLD_PATH "/usr/libexec/installd" +#define NFCD_PATH "/usr/libexec/nfcd" +#define MEDIASERVERD_PATH "/usr/sbin/mediaserverd" int hooked_posix_spawnp(pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *restrict file_actions, posix_spawnattr_t *attrp, char *argv[restrict], char * envp[restrict]) { if (strncmp(path, "/usr/sbin/cfprefsd", 18) == 0) { path = jbroot("/usr/sbin/cfprefsd"); argv[0] = (char *)path; posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); -// } else if (!strncmp(path, mediaserverd, strlen(mediaserverd))) { -// path = jbroot(mediaserverd); -// argv[0] = (char *)path; -// posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); - } else if (!strncmp(path, installd, strlen(installd))) { - path = jbroot(installd); + // } else if (!strncmp(path, MEDIASERVERD_PATH, strlen(MEDIASERVERD_PATH))) { + // path = jbroot(MEDIASERVERD_PATH); + // argv[0] = (char *)path; + // posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); + } else if (!strncmp(path, INSTALLD_PATH, strlen(INSTALLD_PATH))) { + path = jbroot(INSTALLD_PATH); argv[0] = (char *)path; posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); -// } else if (!strncmp(path, nfcd, strlen(nfcd))) { -// log_path(path, jbroot(path)); -// path = jbroot(nfcd); -// argv[0] = (char *)path; -// posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); + } else if (!strncmp(path, NFCD_PATH, strlen(NFCD_PATH))) { + path = jbroot(NFCD_PATH); + argv[0] = (char *)path; + posix_spawnattr_set_launch_type_np((posix_spawnattr_t *)attrp, 0); } return orig_posix_spawnp(pid, path, file_actions, attrp, argv, envp); } diff --git a/RootHelperSample/main.m b/RootHelperSample/main.m index 242d587..7bdf1e6 100644 --- a/RootHelperSample/main.m +++ b/RootHelperSample/main.m @@ -300,7 +300,7 @@ int main(int argc, char *argv[], char *envp[]) { install_cfprefsd(); [[NSFileManager defaultManager] copyItemAtPath:[usprebooterappPath() stringByAppendingPathComponent:@"generalhooksigned.dylib"] toPath:jbroot(@"/generalhooksigned.dylib") error:nil]; - [[NSFileManager defaultManager] copyItemAtPath:[usprebooterappPath() stringByAppendingPathComponent:@"jitter"] toPath:jbroot(@"/jitter") error:nil]; + [[NSFileManager defaultManager] copyItemAtPath:[usprebooterappPath() stringByAppendingPathComponent:@"jitterd"] toPath:jbroot(@"/jitterd") error:nil]; [[NSFileManager defaultManager] copyItemAtPath:[usprebooterappPath() stringByAppendingPathComponent:@"jitterd.plist"] toPath:jbroot(@"/Library/LaunchDaemons/com.hrtowii.jitterd.plist") error:nil]; // [[NSFileManager defaultManager] copyItemAtPath:[usprebooterappPath() stringByAppendingPathComponent:@"Serotonin.jp2"] toPath:@"/var/mobile/Serotonin.jp2" error:nil]; @@ -335,6 +335,9 @@ int main(int argc, char *argv[], char *envp[]) { [jbroot(@"/usr/sbin/") stringByAppendingPathComponent:@"mediaserverd"], jbroot(@"/generalhooksigned.dylib"), jbroot(@"/var/mobile/Serotonin.jp2"), + jbroot(@"/jitter"), + jbroot(@"/jitterd"), + jbroot(@"/Library/LaunchDaemons/com.hrtowii.jitterd.plist"), ]; for (NSString *path in pathsToRemove) { if ([fileManager fileExistsAtPath:path]) {