diff --git a/.gitignore b/.gitignore index 9bcaccc..6dbf15c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,7 @@ _ obj .theos .DS_Store +layout +packages +compile_commands.json +.cache diff --git a/.gitmodules b/.gitmodules index be62880..8e3a63a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "framework"] - path = framework - url = git://github.com/rpetrich/theos.git [submodule "LightMessaging"] path = LightMessaging - url = git://github.com/rpetrich/LightMessaging.git + url = https://github.com/rpetrich/LightMessaging.git diff --git a/LightMessaging b/LightMessaging index fb5cc4c..b33c340 160000 --- a/LightMessaging +++ b/LightMessaging @@ -1 +1 @@ -Subproject commit fb5cc4c1c32cff35956274f3d07943837b7424d9 +Subproject commit b33c340753d7175cc6b4c8e541028153a325e22f diff --git a/Makefile b/Makefile index 073de67..3c41951 100644 --- a/Makefile +++ b/Makefile @@ -1,65 +1,48 @@ -LIBRARY_NAME = librocketbootstrap -librocketbootstrap_FILES = Tweak.x Shims.x -librocketbootstrap_LIBRARIES = substrate -librocketbootstrap_FRAMEWORKS = Foundation -librocketbootstrap_USE_MODULES = 0 +TARGET := iphone:clang:latest:13.0 +ARCHS := arm64 arm64e +INSTALL_TARGET_PROCESSES = SpringBoard MobileGestaltHelper rocketd _rocketd_reenable +GO_EASY_ON_ME = 1 -TOOL_NAME = rocketd _rocketd_reenable -rocketd_FILES = rocketd.c -rocketd_CFLAGS = -fblocks -rocketd_FRAMEWORKS = CoreFoundation -rocketd_INSTALL_PATH = /usr/libexec -rocketd_USE_MODULES = 0 -rocketd_CODESIGN_FLAGS = -Sentitlements.xml +LIBRARY_NAME := librocketbootstrap +librocketbootstrap_FILES += Tweak.x Shims.x +ifeq ($(THEOS_PACKAGE_SCHEME),rootless) +librocketbootstrap_LDFLAGS += -install_name @rpath/librocketbootstrap.dylib +librocketbootstrap_WEAK_LIBRARIES += libs/rootless/TweakInject.tbd +else +librocketbootstrap_WEAK_LIBRARIES += libs/TweakInject.tbd +endif +librocketbootstrap_LIBRARIES += substrate +librocketbootstrap_FRAMEWORKS += Foundation +librocketbootstrap_USE_MODULES += 0 -_rocketd_reenable_FILES = rocketd_reenable.c -_rocketd_reenable_INSTALL_PATH = /usr/libexec -_rocketd_reenable_USE_MODULES = 0 -_rocketd_reenable_CODESIGN_FLAGS = -Sentitlements.xml +TOOL_NAME := rocketd _rocketd_reenable +rocketd_FILES += rocketd.c +rocketd_CFLAGS += -fblocks +rocketd_FRAMEWORKS += CoreFoundation +rocketd_INSTALL_PATH += /usr/libexec +rocketd_USE_MODULES += 0 +rocketd_CODESIGN_FLAGS += -Sentitlements.xml -ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders +_rocketd_reenable_FILES += rocketd_reenable.c +_rocketd_reenable_INSTALL_PATH += /usr/libexec +_rocketd_reenable_USE_MODULES += 0 +_rocketd_reenable_CODESIGN_FLAGS += -Sentitlements.xml -# Support targeting 3.0 in packaged builds, but allow testing packages/builds to be missing support for old iOS versions -XCODE4_PATH ?= /Applications/Xcode_Legacy.app -XCODE6_PATH ?= /Volumes/Xcode/Xcode.app -XCODE9_PATH ?= /Volumes/Xcode_9.4.1/Xcode.app +ADDITIONAL_CFLAGS += -std=c99 -Idefaultheaders -include prefix.pch +ADDITIONAL_LDFLAGS += -Wl,-no_warn_inits -ifeq ($(wildcard $(XCODE4_PATH)/.*),) -ADDITIONAL_CFLAGS += -Idefaultheaders -IPHONE_ARCHS = armv7 armv7s arm64 arm64e -TARGET_IPHONEOS_DEPLOYMENT_VERSION = 8.4 -ifeq ($(FINALPACKAGE),1) -$(error Building final package requires a legacy Xcode install!) -endif -else -armv6_CFLAGS += -Ifullheaders -armv7_CFLAGS += -Ifullheaders -armv7s_CFLAGS += -Ifullheaders -arm64_CFLAGS += -Idefaultheaders -arm64e_CFLAGS += -Idefaultheaders -rocketd_IPHONE_ARCHS = armv6 arm64 -_rocketd_reenable_IPHONE_ARCHS = armv6 arm64 -IPHONE_ARCHS = armv6 armv7 armv7s arm64 arm64e -SDKVERSION_armv6 = 5.1 -INCLUDE_SDKVERSION_armv6 = 8.4 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv7 = 4.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv7s = 6.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_arm64 = 7.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_arm64e = 12.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION = 9.0 -THEOS_PLATFORM_SDK_ROOT_armv6 = $(XCODE4_PATH)/Contents/Developer -THEOS_PLATFORM_SDK_ROOT_armv7 = $(XCODE6_PATH)/Contents/Developer -THEOS_PLATFORM_SDK_ROOT_armv7s = $(XCODE6_PATH)/Contents/Developer -THEOS_PLATFORM_SDK_ROOT_arm64 = $(XCODE9_PATH)/Contents/Developer -endif +include $(THEOS)/makefiles/common.mk +include $(THEOS_MAKE_PATH)/library.mk +include $(THEOS_MAKE_PATH)/tool.mk -include framework/makefiles/common.mk -include framework/makefiles/library.mk -include framework/makefiles/tool.mk +before-all:: + @rm -rf layout + @mkdir -p layout + @[ "$$THEOS_PACKAGE_SCHEME" = "rootless" ] && cp -rP defaultlayout/DEBIAN defaultlayout/var/jb/Library layout/ || true + @[ "$$THEOS_PACKAGE_SCHEME" = "" ] && cp -rP defaultlayout/DEBIAN defaultlayout/Library layout/ || true stage:: - mkdir -p "$(THEOS_STAGING_DIR)/usr/include" - cp -a rocketbootstrap.h rocketbootstrap_dynamic.h "$(THEOS_STAGING_DIR)/usr/include" - plutil -convert binary1 "$(THEOS_STAGING_DIR)/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist" - plutil -convert binary1 "$(THEOS_STAGING_DIR)/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist" + @mkdir -p "$(THEOS_STAGING_DIR)/usr/include" + @cp -a rocketbootstrap.h rocketbootstrap_dynamic.h "$(THEOS_STAGING_DIR)/usr/include" + @plutil -convert binary1 "$(THEOS_STAGING_DIR)/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist" || true + @plutil -convert binary1 "$(THEOS_STAGING_DIR)/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist" || true diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6bd2e6 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# RocketBootstrap +API to securely expose global services on jailbroken iOS. +Fully tested & worked on iOS 13 - iOS 15.4.1 (Dopamine, a rootless jailbreak). + +Special thanks to [@rpetrich](https://github.com/rpetrich), [@coolstar](https://github.com/coolstar) and [@DHowett](https://github.com/DHowett). diff --git a/Tweak.x b/Tweak.x index 5fb5942..4ce7cc4 100644 --- a/Tweak.x +++ b/Tweak.x @@ -1,8 +1,8 @@ -#include +#import #undef __IOS_PROHIBITED #define __IOS_PROHIBITED -#include +#import #define LIGHTMESSAGING_USE_ROCKETBOOTSTRAP 0 #define LIGHTMESSAGING_TIMEOUT 300 @@ -14,16 +14,16 @@ #ifndef __APPLE_API_PRIVATE #define __APPLE_API_PRIVATE -#include "sandbox.h" +#import "sandbox.h" #undef __APPLE_API_PRIVATE #else -#include "sandbox.h" +#import "sandbox.h" #endif #import +#import #import #import -//#import #import #import #import @@ -32,13 +32,50 @@ #define DISPATCH_MACH_SPI 1 #import -extern int *_NSGetArgc(void); -extern const char ***_NSGetArgv(void); +#define ROOTLESS_PREFIX "/var/jb" + +static const char *RBSExecutablePath(void) +{ + static char *executablePath = NULL; + if (!executablePath) + { + uint32_t executablePathSize = 0; + _NSGetExecutablePath(NULL, &executablePathSize); + executablePath = (char *)calloc(1, executablePathSize); + if (0 == _NSGetExecutablePath(executablePath, &executablePathSize)) + { + /* Resolve Symbolic Links */ + char realExecutablePath[PATH_MAX] = {0}; + if (realpath(executablePath, realExecutablePath) != NULL) + { + free(executablePath); + executablePath = strdup(realExecutablePath); + } + + /* Supports Procursus */ + if (strncmp("/private/preboot" "/", executablePath, sizeof("/private/preboot")) == 0) + { + const char *littlePtr = strstr(executablePath, "/procursus" "/"); + if (littlePtr != NULL) + { + char *suffixPtr = strdup(littlePtr + sizeof("/procursus") - 1); + free(executablePath); + char *markPtr = (char *)calloc(1, strlen(suffixPtr) + sizeof(ROOTLESS_PREFIX)); + markPtr = strcat(strcat(markPtr, ROOTLESS_PREFIX), suffixPtr); + free(suffixPtr); + executablePath = markPtr; + } + } + } + } + + return executablePath; +} #define kUserAppsPath "/var/mobile/Applications/" #define kSystemAppsPath "/Applications/" -static BOOL isDaemon; +static BOOL isDaemon = NO; static BOOL fill_redirected_name(char new_name[BOOTSTRAP_MAX_NAME_LEN], const name_t old_name) { size_t length = strlen(old_name); @@ -76,22 +113,22 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const } // Compatibility mode for Flex, limits it to only the processes in rbs 1.0.1 and earlier if (strcmp(service_name, "FLMessagingCenterSpringboard") == 0) { - const char **argv = *_NSGetArgv(); - size_t arg0len = strlen(argv[0]); + const char *executablePath = RBSExecutablePath(); + size_t arg0len = strlen(executablePath); bool allowed = false; - if ((arg0len > sizeof(kUserAppsPath)) && (memcmp(argv[0], kUserAppsPath, sizeof(kUserAppsPath) - 1) == 0)) + if ((arg0len > sizeof(kUserAppsPath)) && (memcmp(executablePath, kUserAppsPath, sizeof(kUserAppsPath) - 1) == 0)) allowed = true; - if ((arg0len > sizeof(kSystemAppsPath)) && (memcmp(argv[0], kSystemAppsPath, sizeof(kSystemAppsPath) - 1) == 0)) + if ((arg0len > sizeof(kSystemAppsPath)) && (memcmp(executablePath, kSystemAppsPath, sizeof(kSystemAppsPath) - 1) == 0)) allowed = true; if (!allowed) return 1; } - // Ask our service running inside of the com.apple.ReportCrash.SimulateCrash job + // Ask our service running inside of the com.apple.mobilegestalt.xpc job mach_port_t servicesPort = MACH_PORT_NULL; - kern_return_t err = bootstrap_look_up(bp, "com.apple.ReportCrash.SimulateCrash", &servicesPort); + kern_return_t err = bootstrap_look_up(bp, "com.apple.mobilegestalt.xpc", &servicesPort); if (err) { #ifdef DEBUG - NSLog(@"RocketBootstrap: = %lld (failed to lookup com.apple.ReportCrash.SimulateCrash)", (unsigned long long)err); + NSLog(@"RocketBootstrap: = %lld (failed to lookup com.apple.mobilegestalt.xpc)", (unsigned long long)err); #endif return err; } @@ -103,7 +140,7 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const #ifdef DEBUG NSLog(@"RocketBootstrap: = %lld (failed to allocate port)", (unsigned long long)err); #endif - mach_port_deallocate(selfTask, servicesPort); + mach_port_mod_refs(selfTask, servicesPort, MACH_PORT_RIGHT_SEND, -1); return err; } // Send message @@ -146,8 +183,8 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const } } // Cleanup - mach_port_deallocate(selfTask, servicesPort); - mach_port_deallocate(selfTask, replyPort); + mach_port_mod_refs(selfTask, servicesPort, MACH_PORT_RIGHT_SEND, -1); + mach_port_mod_refs(selfTask, replyPort, MACH_PORT_RIGHT_RECEIVE, -1); return err; } @@ -185,10 +222,11 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) if (!fill_redirected_name(redirected_name, service_name)) { return 1; } + mach_port_t selfPort = mach_task_self(); mach_port_t bootstrap = MACH_PORT_NULL; - task_get_bootstrap_port(mach_task_self(), &bootstrap); - mach_port_t service; - kern_return_t err = bootstrap_look_up(bootstrap, service_name, &service); + task_get_bootstrap_port(selfPort, &bootstrap); + mach_port_t servicePort; + kern_return_t err = bootstrap_look_up(bootstrap, service_name, &servicePort); if (err != 0) { // If the current process is permitted to register for this port, assume it's about to int sandbox_result = sandbox_check(getpid(), "mach-register", SANDBOX_FILTER_LOCAL_NAME | SANDBOX_CHECK_NO_REPORT, service_name); @@ -198,26 +236,26 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) char *copied_service_name = strdup(service_name); CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFRunLoopPerformBlock(runLoop, kCFRunLoopCommonModes, ^{ + mach_port_t selfPort1 = mach_task_self(); mach_port_t bootstrap = MACH_PORT_NULL; - task_get_bootstrap_port(mach_task_self(), &bootstrap); - mach_port_t service; - kern_return_t err = bootstrap_look_up(bootstrap, copied_service_name, &service); + task_get_bootstrap_port(selfPort1, &bootstrap); + mach_port_t servicePort1; + kern_return_t err = bootstrap_look_up(bootstrap, copied_service_name, &servicePort1); if (err == 0) { char redirected_name[BOOTSTRAP_MAX_NAME_LEN]; fill_redirected_name(redirected_name, copied_service_name); - err = bootstrap_register(bootstrap, redirected_name, service); - if (err != 0) { - mach_port_deallocate(mach_task_self(), service); - } + err = bootstrap_register(bootstrap, redirected_name, servicePort1); + if (err != 0) + mach_port_mod_refs(selfPort1, servicePort1, MACH_PORT_RIGHT_SEND, -1); } free(copied_service_name); }); CFRunLoopWakeUp(runLoop); return 0; } else { - err = bootstrap_register(bootstrap, redirected_name, service); + err = bootstrap_register(bootstrap, redirected_name, servicePort); if (err != 0) { - mach_port_deallocate(mach_task_self(), service); + mach_port_mod_refs(selfPort, servicePort, MACH_PORT_RIGHT_SEND, -1); return err; } } @@ -251,7 +289,7 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) } #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -kern_return_t rocketbootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp) +kern_return_t rocketbootstrap_register(mach_port_t bp, const name_t service_name, mach_port_t sp) { if (rocketbootstrap_uses_name_redirection()) { char redirected_name[BOOTSTRAP_MAX_NAME_LEN]; @@ -340,7 +378,7 @@ static boolean_t new_demux(mach_msg_header_t *request, mach_msg_header_t *reply) #ifdef DEBUG NSLog(@"RocketBootstrap: new_demux(%lld)", (long long)request->msgh_id); #endif - // Highjack ROCKETBOOTSTRAP_LOOKUP_ID from the com.apple.ReportCrash.SimulateCrash demuxer + // Highjack ROCKETBOOTSTRAP_LOOKUP_ID from the com.apple.mobilegestalt.xpc demuxer if (request->msgh_id == ROCKETBOOTSTRAP_LOOKUP_ID) { continue_server_once = true; kern_return_t err = handle_bootstrap_lookup_msg(request); @@ -352,12 +390,13 @@ static boolean_t new_demux(mach_msg_header_t *request, mach_msg_header_t *reply) return server_once_demux_orig(request, reply); } +__used static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_header_t *, mach_msg_header_t *), mach_msg_size_t max_size, mach_port_t rcv_name, mach_msg_options_t options) { #ifdef DEBUG NSLog(@"RocketBootstrap: mach_msg_server_once(%p, %llu, %llu, 0x%llx)", demux, (unsigned long long)max_size, (unsigned long long)rcv_name, (long long)options); #endif - // Highjack com.apple.ReportCrash.SimulateCrash's use of mach_msg_server_once + // Highjack com.apple.mobilegestalt.xpc's use of mach_msg_server_once unfair_lock_lock(&server_once_lock); if (!server_once_demux_orig) { server_once_demux_orig = demux; @@ -380,15 +419,19 @@ static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_heade #ifdef __clang__ +__used static void *interceptedConnection; +__used static void *(*_xpc_connection_create_mach_service)(const char *name, dispatch_queue_t targetq, uint64_t flags); + +__used static void *$xpc_connection_create_mach_service(const char *name, dispatch_queue_t targetq, uint64_t flags) { #ifdef DEBUG NSLog(@"RocketBootstrap: xpc_connection_create_mach_service(%s, %p, %lld)", name, targetq, (unsigned long long)flags); #endif - if (name && strcmp(name, "com.apple.ReportCrash.SimulateCrash") == 0) { + if (name && strcmp(name, "com.apple.mobilegestalt.xpc") == 0) { void *result = _xpc_connection_create_mach_service(name, targetq, flags); interceptedConnection = result; return result; @@ -396,13 +439,16 @@ static void *$xpc_connection_create_mach_service(const char *name, dispatch_queu return _xpc_connection_create_mach_service(name, targetq, flags); } +__used static void (*__xpc_connection_mach_event)(void *context, dispatch_mach_reason_t reason, dispatch_mach_msg_t message, mach_error_t error); + +__used static void $_xpc_connection_mach_event(void *context, dispatch_mach_reason_t reason, dispatch_mach_msg_t message, mach_error_t error) { #ifdef DEBUG NSLog(@"RocketBootstrap: _xpc_connection_mach_event(%p, %lu, %p, 0x%x)", context, reason, message, error); #endif - // Highjack ROCKETBOOTSTRAP_LOOKUP_ID from the com.apple.ReportCrash.SimulateCrash XPC service + // Highjack ROCKETBOOTSTRAP_LOOKUP_ID from the com.apple.mobilegestalt.xpc XPC service if ((reason == DISPATCH_MACH_MESSAGE_RECEIVED) && (context == interceptedConnection)) { size_t size; mach_msg_header_t *header = dispatch_mach_msg_get_msg(message, &size); @@ -428,7 +474,7 @@ static pid_t pid_of_process(const char *process_name) struct kinfo_proc * newprocess = NULL; do { - if (size == 0){ + if (size == 0) { st = sysctl(mib, miblen, NULL, &size, NULL, 0); } @@ -515,8 +561,7 @@ static void observe_rocketd(void) buffer.message.body.msgh_descriptor_count = 0; buffer.message.data.in_line.length = 0; err = mach_msg(&buffer.message.head, MACH_SEND_MSG | MACH_RCV_MSG | _LIGHTMESSAGING_TIMEOUT_FLAGS, size, sizeof(LMResponseBuffer), replyPort, LIGHTMESSAGING_TIMEOUT, MACH_PORT_NULL); - if (err) { - } + if (err) { } // Cleanup mach_port_mod_refs(self, replyPort, MACH_PORT_RIGHT_RECEIVE, -1); } @@ -558,72 +603,55 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati { } +#import "pac_helper.h" + %ctor { %init(); - // Attach rockets when in the com.apple.ReportCrash.SimulateCrash job + // Attach rockets when in the com.apple.mobilegestalt.xpc job // (can't check in using the launchd APIs because it hates more than one checkin; this will do) - const char **_argv = *_NSGetArgv(); - if (strcmp(_argv[0], "/System/Library/CoreServices/ReportCrash") == 0 && _argv[1]) { - if (strcmp(_argv[1], "-f") == 0) { - isDaemon = YES; -#ifdef DEBUG - NSLog(@"RocketBootstrap: Initializing ReportCrash using mach_msg_server"); -#endif - MSHookFunction(mach_msg_server_once, $mach_msg_server_once, (void **)&_mach_msg_server_once); -#ifdef __clang__ - } else if (strcmp(_argv[1], "com.apple.ReportCrash.SimulateCrash") == 0) { - isDaemon = YES; -#ifdef DEBUG - NSLog(@"RocketBootstrap: Initializing ReportCrash using XPC"); -#endif - MSImageRef libxpc = MSGetImageByName("/usr/lib/system/libxpc.dylib"); - if (libxpc) { - void *xpc_connection_create_mach_service = MSFindSymbol(libxpc, "_xpc_connection_create_mach_service"); - if (xpc_connection_create_mach_service) { - MSHookFunction(xpc_connection_create_mach_service, $xpc_connection_create_mach_service, (void **)&_xpc_connection_create_mach_service); - } else { + const char *executablePath = RBSExecutablePath(); + if (strcmp(executablePath, "/usr/libexec/MobileGestaltHelper") == 0) { + isDaemon = YES; +// #ifdef DEBUG +// NSLog(@"RocketBootstrap: Initializing %s using mach_msg_server", executablePath); +// #endif +// MSHookFunction(mach_msg_server_once, $mach_msg_server_once, (void **)&_mach_msg_server_once); #ifdef DEBUG - NSLog(@"RocketBootstrap: Could not find xpc_connection_create_mach_service symbol!"); + NSLog(@"RocketBootstrap: Initializing %s using XPC", executablePath); #endif - } - void *_xpc_connection_mach_event = MSFindSymbol(libxpc, "__xpc_connection_mach_event"); - if (_xpc_connection_mach_event) { - MSHookFunction(_xpc_connection_mach_event, $_xpc_connection_mach_event, (void **)&__xpc_connection_mach_event); - } else { + MSImageRef libxpc = MSGetImageByName("/usr/lib/system/libxpc.dylib"); + if (libxpc) { + void *xpc_connection_create_mach_service = MSFindSymbol(libxpc, "_xpc_connection_create_mach_service"); + if (xpc_connection_create_mach_service) { + MSHookFunction(xpc_connection_create_mach_service, $xpc_connection_create_mach_service, (void **)&_xpc_connection_create_mach_service); + } else { #ifdef DEBUG - NSLog(@"RocketBootstrap: Could not find _xpc_connection_mach_event symbol!"); + NSLog(@"RocketBootstrap: Could not find xpc_connection_create_mach_service symbol!"); #endif - } + } + void *_xpc_connection_mach_event = MSFindSymbol(libxpc, "__xpc_connection_mach_event"); + if (!_xpc_connection_mach_event) + _xpc_connection_mach_event = make_sym_callable(*((void **)make_sym_readable((void *)libxpc)) + 0x10530); + if (_xpc_connection_mach_event) { + MSHookFunction(_xpc_connection_mach_event, $_xpc_connection_mach_event, (void **)&__xpc_connection_mach_event); } else { #ifdef DEBUG - NSLog(@"RocketBootstrap: Could not find libxpc.dylib image!"); + NSLog(@"RocketBootstrap: Could not find _xpc_connection_mach_event symbol!"); #endif } -#endif } - } else if (strcmp(argv[0], "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { + } else if (strcmp(executablePath, "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { #ifdef DEBUG - NSLog(@"RocketBootstrap: Initializing SpringBoard"); + NSLog(@"RocketBootstrap: Initializing %s", executablePath); #endif - if (kCFCoreFoundationVersionNumber < 847.20) { - return; - } - // Sanity check on the SimulateCrash service + if (kCFCoreFoundationVersionNumber < 847.20) return; + // Sanity check on the MobileGestaltHelper service mach_port_t bootstrap = MACH_PORT_NULL; mach_port_t self = mach_task_self(); task_get_bootstrap_port(self, &bootstrap); mach_port_t servicesPort = MACH_PORT_NULL; - kern_return_t err = bootstrap_look_up(bootstrap, "com.apple.ReportCrash.SimulateCrash", &servicesPort); - //bool has_simulate_crash; - if (err) { - //has_simulate_crash = false; - } else { - mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); - //has_simulate_crash = true; - //servicesPort = MACH_PORT_NULL; - //err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); - } + kern_return_t err = bootstrap_look_up(bootstrap, "com.apple.mobilegestalt.xpc", &servicesPort); if (err == 0) { mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); observe_rocketd(); @@ -633,17 +661,12 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati kCFUserNotificationAlertMessageKey, kCFUserNotificationDefaultButtonTitleKey, }; - const CFTypeRef valuesCrash[] = { + const CFTypeRef valuesList[] = { CFSTR("System files missing!"), - CFSTR("RocketBootstrap has detected that your SimulateCrash crash reporting daemon is missing or disabled.\nThis daemon is required for proper operation of packages that depend on RocketBootstrap."), + CFSTR("RocketBootstrap has detected that your MobileGestaltHelper daemon is missing or disabled.\nThis daemon is required for proper operation of packages that depend on RocketBootstrap."), CFSTR("OK"), }; - /*const CFTypeRef valuesRocket[] = { - CFSTR("System files missing!"), - CFSTR("RocketBootstrap has detected that your rocketbootstrap daemon is missing or disabled.\nThis daemon is required for proper operation of packages that depend on RocketBootstrap."), - CFSTR("OK"), - };*/ - CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, /*has_simulate_crash ? (const void **)valuesRocket :*/ (const void **)valuesCrash, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)valuesList, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SInt32 err = 0; CFUserNotificationRef notification = CFUserNotificationCreate(kCFAllocatorDefault, 0.0, kCFUserNotificationPlainAlertLevel, &err, dict); CFRunLoopSourceRef runLoopSource = CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, notification, SanityCheckNotificationCallback, 0); diff --git a/layout/DEBIAN/control b/control similarity index 85% rename from layout/DEBIAN/control rename to control index 2bce6bd..f16ca9b 100644 --- a/layout/DEBIAN/control +++ b/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap -Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) +Depends: firmware (>= 13.0), firmware (<< 16.0), mobilesubstrate Name: RocketBootstrap -Version: 1.0.9 +Version: 1.0.10~beta5 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ diff --git a/defaultlayout/DEBIAN/postinst b/defaultlayout/DEBIAN/postinst new file mode 100755 index 0000000..f0dd84c --- /dev/null +++ b/defaultlayout/DEBIAN/postinst @@ -0,0 +1,16 @@ +#!/bin/sh + +JB_PREFIX="" +if [ -e /var/jb ]; then + JB_PREFIX="/var/jb" +fi + +chown root:wheel "$JB_PREFIX/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist" > /dev/null 2>&1 || true +launchctl load -w "$JB_PREFIX/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist" > /dev/null 2>&1 || true +launchctl kill 9 system/com.apple.mobilegestalt.xpc > /dev/null 2>&1 || true +mv /System/Library/LaunchDaemons{BAK,}/com.apple.mobilegestalt.xpc.plist > /dev/null 2>&1 || true +launchctl load -w /System/Library/LaunchDaemons/com.apple.mobilegestalt.xpc.plist > /dev/null 2>&1 || true +chown root:wheel "$JB_PREFIX/usr/libexec/_rocketd_reenable" > /dev/null 2>&1 || true +chmod +s "$JB_PREFIX/usr/libexec/_rocketd_reenable" > /dev/null 2>&1 || true + +exit 0 \ No newline at end of file diff --git a/defaultlayout/DEBIAN/prerm b/defaultlayout/DEBIAN/prerm new file mode 100755 index 0000000..c5e0c70 --- /dev/null +++ b/defaultlayout/DEBIAN/prerm @@ -0,0 +1,11 @@ +#!/bin/sh + +JB_PREFIX="" +if [ -e /var/jb ]; then + JB_PREFIX="/var/jb" +fi + +launchctl unload -w "$JB_PREFIX/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist" > /dev/null 2>&1 || true +launchctl kill 9 system/com.apple.mobilegestalt.xpc > /dev/null 2>&1 || true + +exit 0 \ No newline at end of file diff --git a/layout/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist b/defaultlayout/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist similarity index 100% rename from layout/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist rename to defaultlayout/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist diff --git a/layout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib b/defaultlayout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib similarity index 100% rename from layout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib rename to defaultlayout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib diff --git a/layout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist b/defaultlayout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist similarity index 73% rename from layout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist rename to defaultlayout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist index 13a5b4a..690ed45 100644 --- a/layout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist +++ b/defaultlayout/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist @@ -4,9 +4,13 @@ Filter + Bundles + + com.apple.springboard + Executables - ReportCrash + MobileGestaltHelper CoreFoundationVersion diff --git a/defaultlayout/var/jb/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist b/defaultlayout/var/jb/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist new file mode 100644 index 0000000..3e92122 --- /dev/null +++ b/defaultlayout/var/jb/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist @@ -0,0 +1,26 @@ + + + + + ProgramArguments + + /var/jb/usr/libexec/rocketd + + OnDemand + + UserName + mobile + MachServices + + com.rpetrich.rocketbootstrapd + + + Label + com.rpetrich.rocketbootstrapd + JetsamProperties + + JetsamPriority + 18 + + + diff --git a/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib b/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib new file mode 120000 index 0000000..6985df7 --- /dev/null +++ b/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.dylib @@ -0,0 +1 @@ +/var/jb/usr/lib/librocketbootstrap.dylib \ No newline at end of file diff --git a/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist b/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist new file mode 100644 index 0000000..690ed45 --- /dev/null +++ b/defaultlayout/var/jb/Library/MobileSubstrate/DynamicLibraries/RocketBootstrap.plist @@ -0,0 +1,21 @@ + + + + + Filter + + Bundles + + com.apple.springboard + + Executables + + MobileGestaltHelper + + CoreFoundationVersion + + 800 + + + + diff --git a/framework b/framework deleted file mode 120000 index 11eaf40..0000000 --- a/framework +++ /dev/null @@ -1 +0,0 @@ -../theos \ No newline at end of file diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst deleted file mode 100755 index 3b51ee5..0000000 --- a/layout/DEBIAN/postinst +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -chown root:wheel /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist -launchctl load /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist || true -launchctl stop com.apple.ReportCrash.SimulateCrash || true -mv /System/Library/LaunchDaemons{BAK,}/com.apple.ReportCrash.SimulateCrash.plist 2> /dev/null || true -launchctl load /System/Library/LaunchDaemons/com.apple.ReportCrash.SimulateCrash.plist 2> /dev/null || true -chown root:wheel /usr/libexec/_rocketd_reenable -chmod +s /usr/libexec/_rocketd_reenable diff --git a/layout/DEBIAN/prerm b/layout/DEBIAN/prerm deleted file mode 100755 index e0396bf..0000000 --- a/layout/DEBIAN/prerm +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -launchctl unload /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist || true -launchctl stop com.apple.ReportCrash.SimulateCrash || true diff --git a/libs/TweakInject.tbd b/libs/TweakInject.tbd new file mode 100644 index 0000000..2054166 --- /dev/null +++ b/libs/TweakInject.tbd @@ -0,0 +1,20 @@ +--- +archs: [ arm64, arm64e ] +platform: ios +install-name: /usr/lib/TweakInject.dylib +current-version: 0.0 +compatibility-version: 0.0 +exports: + - archs: [ arm64, arm64e ] + symbols: [ _LHPatchMemory, _SpringBoardSigHandler, _calljailbreakd, + _calljailbreakdforexec, _callpaccrypto_fixup_hook, + _close_xpc_client, _closejailbreakfd, _connection, + _file_exist, _fixfont, _hook, _hookPacket, _hook_loader, + _jailbreakd_sock, _launch_root, _log_file, _new_getLoader, + _old_getLoader, _open_xpc_client, _opensocket, _paccrypto_sock, + _parseMacho, _pathFromProcessID, _processName, _rpath_to_var, + _safeMode, _sbinjectGenerateDylibList, _usr_to_var, + _xpc_attchme, _xpc_fixProc, _xpc_fixProcAndRoot, + _xpc_fix_dylib, _xpc_ldrestart, _xpc_platform, _xpc_sbrelaod, + _xpc_sig, _xpcrelease ] +... diff --git a/libs/rootless/TweakInject.tbd b/libs/rootless/TweakInject.tbd new file mode 100644 index 0000000..9042faa --- /dev/null +++ b/libs/rootless/TweakInject.tbd @@ -0,0 +1,20 @@ +--- +archs: [ arm64, arm64e ] +platform: ios +install-name: '@rpath/TweakInject.dylib' +current-version: 0.0 +compatibility-version: 0.0 +exports: + - archs: [ arm64, arm64e ] + symbols: [ _LHPatchMemory, _SpringBoardSigHandler, _calljailbreakd, + _calljailbreakdforexec, _callpaccrypto_fixup_hook, + _close_xpc_client, _closejailbreakfd, _connection, + _file_exist, _fixfont, _hook, _hookPacket, _hook_loader, + _jailbreakd_sock, _launch_root, _log_file, _new_getLoader, + _old_getLoader, _open_xpc_client, _opensocket, _paccrypto_sock, + _parseMacho, _pathFromProcessID, _processName, _rpath_to_var, + _safeMode, _sbinjectGenerateDylibList, _usr_to_var, + _xpc_attchme, _xpc_fixProc, _xpc_fixProcAndRoot, + _xpc_fix_dylib, _xpc_ldrestart, _xpc_platform, _xpc_sbrelaod, + _xpc_sig, _xpcrelease ] +... diff --git a/overlayheaders b/overlayheaders deleted file mode 120000 index 80cf74d..0000000 --- a/overlayheaders +++ /dev/null @@ -1 +0,0 @@ -../overlayheaders/ \ No newline at end of file diff --git a/pac_helper.h b/pac_helper.h new file mode 100644 index 0000000..953b826 --- /dev/null +++ b/pac_helper.h @@ -0,0 +1,34 @@ +#ifndef PTRAUTH_HELPERS_H +#define PTRAUTH_HELPERS_H + +// Helpers for PAC archs. + +// If the compiler understands __arm64e__, assume it's paired with an SDK that has +// ptrauth.h. Otherwise, it'll probably error if we try to include it so don't. +#if __arm64e__ +#include +#endif + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" + +// Given a pointer to instructions, sign it so you can call it like a normal fptr. +static void *make_sym_callable(void *ptr) { +#if __arm64e__ + if (!ptr) return ptr; + ptr = ptrauth_sign_unauthenticated(ptrauth_strip(ptr, ptrauth_key_function_pointer), ptrauth_key_function_pointer, 0); +#endif + return ptr; +} + +// Given a function pointer, strip the PAC so you can read the instructions. +static void *make_sym_readable(void *ptr) { +#if __arm64e__ + if (!ptr) return ptr; + ptr = ptrauth_strip(ptr, ptrauth_key_function_pointer); +#endif + return ptr; +} + +#pragma clang diagnostic pop +#endif // PTRAUTH_HELPERS_H diff --git a/prefix.pch b/prefix.pch new file mode 100644 index 0000000..f93058f --- /dev/null +++ b/prefix.pch @@ -0,0 +1,3 @@ +#if __OBJC__ +#import +#endif \ No newline at end of file diff --git a/rocketbootstrap.h b/rocketbootstrap.h index cb7ee03..46bb3fc 100644 --- a/rocketbootstrap.h +++ b/rocketbootstrap.h @@ -16,7 +16,7 @@ kern_return_t rocketbootstrap_look_up(mach_port_t bootstrap_port, const name_t s kern_return_t rocketbootstrap_unlock(const name_t service_name); // Register a port with and grant system-wide access to a particular service name // Note: Will return an error if called from within a sandboxed process -kern_return_t rocketbootstrap_register(mach_port_t bootstrap_port, name_t service_name, mach_port_t service_port); +kern_return_t rocketbootstrap_register(mach_port_t bootstrap_port, const name_t service_name, mach_port_t service_port); // CFMessagePort helpers