From 844a502d2cd621421ef5d1eb404c5d442e815387 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 15:27:35 -0400 Subject: [PATCH 01/65] Make buildable against SDK 9.0 --- LightMessaging | 2 +- Makefile | 6 ++++-- overlayheaders | 1 + tests/Makefile | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) create mode 120000 overlayheaders diff --git a/LightMessaging b/LightMessaging index e6edada..c341570 160000 --- a/LightMessaging +++ b/LightMessaging @@ -1 +1 @@ -Subproject commit e6edada93c2ac45936785dc80535908455890889 +Subproject commit c341570a91e3600ac2e569bc418b185b24305f32 diff --git a/Makefile b/Makefile index 45f7da7..886da4d 100644 --- a/Makefile +++ b/Makefile @@ -5,16 +5,17 @@ librocketbootstrap_FRAMEWORKS = Foundation TOOL_NAME = rocketd rocketd_FILES = rocketd.c +rocketd_CFLAGS = -fblocks rocketd_FRAMEWORKS = CoreFoundation rocketd_INSTALL_PATH = /usr/libexec rocketd_IPHONE_ARCHS = armv6 arm64 -ADDITIONAL_CFLAGS = -std=c99 +ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders IPHONE_ARCHS = armv6 armv7 armv7s arm64 SDKVERSION_armv6 = 5.1 -INCLUDE_SDKVERSION_armv6 = 7.0 +INCLUDE_SDKVERSION_armv6 = 8.4 TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 @@ -28,3 +29,4 @@ 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" diff --git a/overlayheaders b/overlayheaders new file mode 120000 index 0000000..80cf74d --- /dev/null +++ b/overlayheaders @@ -0,0 +1 @@ +../overlayheaders/ \ No newline at end of file diff --git a/tests/Makefile b/tests/Makefile index 2443219..21a8f60 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -8,7 +8,7 @@ ADDITIONAL_CFLAGS = -std=c99 -I../ IPHONE_ARCHS = armv6 arm64 SDKVERSION_armv6 = 5.1 -INCLUDE_SDKVERSION_armv6 = 7.0 +INCLUDE_SDKVERSION_armv6 = 8.4 TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 From 35abaeceb1d56636040f906b048f60dc6404c077 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 15:27:47 -0400 Subject: [PATCH 02/65] Change description --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 5b34585..b953512 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -3,7 +3,7 @@ Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap Version: 1.0.2 Architecture: iphoneos-arm -Description: mach lookup support library for iOS 7 +Description: mach lookup support library for iOS Depiction: http://rpetri.ch/cydia/rocketbootstrap/ Homepage: http://rpetri.ch/cydia/rocketbootstrap/ Maintainer: BigBoss From 1657aadf76557623ec513a815d89c5e1c817c14a Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 16:29:51 -0400 Subject: [PATCH 03/65] Always re-register when rocketd is restarted --- Tweak.x | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Tweak.x b/Tweak.x index a0816d9..68bb330 100644 --- a/Tweak.x +++ b/Tweak.x @@ -117,10 +117,18 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *serviceNameString = [NSString stringWithUTF8String:service_name]; OSSpinLockLock(&namesLock); - BOOL containedName = [allowedNames containsObject:serviceNameString]; + BOOL containedName; + if (!allowedNames) { + allowedNames = [[NSMutableSet alloc] init]; + [allowedNames addObject:serviceNameString]; + CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), &daemon_restarted_callback, daemon_restarted_callback, CFSTR("com.rpetrich.rocketd.started"), NULL, CFNotificationSuspensionBehaviorCoalesce); + containedName = NO; + } else { + containedName = [allowedNames containsObject:serviceNameString]; + } OSSpinLockUnlock(&namesLock); + [pool drain]; if (containedName) { - [pool drain]; return 0; } // Ask rocketd to unlock it for us @@ -129,18 +137,7 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) [pool drain]; return sandbox_result; } - kern_return_t result = LMConnectionSendOneWay(&connection, 0, service_name, strlen(service_name)); - if (!result) { - OSSpinLockLock(&namesLock); - if (!allowedNames) { - allowedNames = [[NSMutableSet alloc] init]; - CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), &daemon_restarted_callback, daemon_restarted_callback, CFSTR("com.rpetrich.rocketd.started"), NULL, CFNotificationSuspensionBehaviorCoalesce); - } - [allowedNames addObject:serviceNameString]; - OSSpinLockUnlock(&namesLock); - } - [pool drain]; - return result; + return LMConnectionSendOneWay(&connection, 0, service_name, strlen(service_name)); } #pragma GCC diagnostic ignored "-Wdeprecated-declarations" From 2f09b1bdbd5a36f2fd71892012b097bcfb054879 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 16:31:13 -0400 Subject: [PATCH 04/65] Send a response from the ReportCrash daemon if name isn't allowed (so that client doesn't hang indefinitely on iOS 9) --- Tweak.x | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Tweak.x b/Tweak.x index 68bb330..f1ab125 100644 --- a/Tweak.x +++ b/Tweak.x @@ -173,12 +173,10 @@ static boolean_t new_demux(mach_msg_header_t *request, mach_msg_header_t *reply) LMResponseBuffer buffer; if (LMConnectionSendTwoWay(&connection, 1, &lookup_message->name[0], length, &buffer)) return false; - if (!LMResponseConsumeInteger(&buffer)) - return false; + BOOL nameIsAllowed = LMResponseConsumeInteger(&buffer) != 0; // Lookup service port mach_port_t servicePort = MACH_PORT_NULL; mach_port_t selfTask = mach_task_self(); - BOOL nameIsAllowed = YES; kern_return_t err; if (nameIsAllowed) { mach_port_t bootstrap = MACH_PORT_NULL; From b56bbdabc96725c173d88ae6eda2f133fff0a94d Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 16:31:43 -0400 Subject: [PATCH 05/65] Optimize call to bootstrap_look_up by avoiding creation of an NSString --- Tweak.x | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Tweak.x b/Tweak.x index f1ab125..6025eea 100644 --- a/Tweak.x +++ b/Tweak.x @@ -182,9 +182,13 @@ static boolean_t new_demux(mach_msg_header_t *request, mach_msg_header_t *reply) mach_port_t bootstrap = MACH_PORT_NULL; err = task_get_bootstrap_port(selfTask, &bootstrap); if (!err) { - NSString *name = [[NSString alloc] initWithBytes:&lookup_message->name[0] length:length encoding:NSUTF8StringEncoding]; - bootstrap_look_up(bootstrap, [name UTF8String], &servicePort); - [name release]; + char *buffer = malloc(length + 1); + if (buffer) { + memcpy(buffer, lookup_message->name, length); + buffer[length] = '\0'; + err = bootstrap_look_up(bootstrap, buffer, &servicePort); + free(buffer); + } } } // Generate response From f580515a8fa7be526f9209a74a1d112094f3cb99 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 16:35:00 -0400 Subject: [PATCH 06/65] Use beta depiction --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index b953512..252648a 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.2 Architecture: iphoneos-arm Description: mach lookup support library for iOS -Depiction: http://rpetri.ch/cydia/rocketbootstrap/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 8ecfcef2bbfdac6d925c6d29ced4453e9d381780 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Oct 2015 17:03:39 -0400 Subject: [PATCH 07/65] Public Release 1.0.3 beta 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 252648a..eb572e8 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.2 +Version: 1.0.3~beta1 Architecture: iphoneos-arm Description: mach lookup support library for iOS Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ From 81fbafea32175e1be3baf000cc0b86f410639050 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 19 Oct 2015 01:20:41 -0400 Subject: [PATCH 08/65] Remove beta depiction URL --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index eb572e8..db2b6eb 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.3~beta1 Architecture: iphoneos-arm Description: mach lookup support library for iOS -Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 1ae235b46c6ebbc3c9a0caa931f7d0f1a5a506a6 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 19 Oct 2015 01:20:51 -0400 Subject: [PATCH 09/65] Public Release 1.0.3 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index db2b6eb..7f2006c 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.3~beta1 +Version: 1.0.3 Architecture: iphoneos-arm Description: mach lookup support library for iOS Depiction: http://rpetri.ch/cydia/rocketbootstrap/ From ed094ae16d5998b2fc4f0fb1fb2bbedad58ef707 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Tue, 20 Oct 2015 23:18:59 -0400 Subject: [PATCH 10/65] Use a 300 ms timeout when communicating over bootstrap ports --- LightMessaging | 2 +- Tweak.x | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/LightMessaging b/LightMessaging index c341570..496257b 160000 --- a/LightMessaging +++ b/LightMessaging @@ -1 +1 @@ -Subproject commit c341570a91e3600ac2e569bc418b185b24305f32 +Subproject commit 496257b11c3e906333797639355db9a43015eb50 diff --git a/Tweak.x b/Tweak.x index 6025eea..d7042de 100644 --- a/Tweak.x +++ b/Tweak.x @@ -1,4 +1,5 @@ #define LIGHTMESSAGING_USE_ROCKETBOOTSTRAP 0 +#define LIGHTMESSAGING_TIMEOUT 300 #import "LightMessaging/LightMessaging.h" #import "rocketbootstrap_internal.h" @@ -25,7 +26,7 @@ extern const char ***_NSGetArgv(void); static BOOL isDaemon; -kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp) +static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const name_t service_name, mach_port_t *sp, mach_msg_timeout_t timeout) { if (rocketbootstrap_is_passthrough() || isDaemon) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_5_0) { @@ -78,7 +79,13 @@ kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, message->head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); message->name_length = service_name_size; memcpy(&message->name[0], service_name, service_name_size); - err = mach_msg(&message->head, MACH_SEND_MSG | MACH_RCV_MSG, size, size, replyPort, 0, MACH_PORT_NULL); + mach_msg_option_t options = MACH_SEND_MSG | MACH_RCV_MSG; + if (timeout == 0) { + timeout = MACH_MSG_TIMEOUT_NONE; + } else { + options |= MACH_SEND_TIMEOUT | MACH_RCV_TIMEOUT; + } + err = mach_msg(&message->head, options, size, size, replyPort, timeout, MACH_PORT_NULL); // Parse response if (!err) { _rocketbootstrap_lookup_response_t *response = (_rocketbootstrap_lookup_response_t *)message; @@ -93,6 +100,11 @@ kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, return err; } +kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp) +{ + return rocketbootstrap_look_up_with_timeout(bp, service_name, sp, LIGHTMESSAGING_TIMEOUT); +} + static NSMutableSet *allowedNames; static volatile OSSpinLock namesLock; From dc89f387f2d046e397976e5d13058029076cae64 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 25 Oct 2015 22:38:08 -0400 Subject: [PATCH 11/65] More rigorous sanity check on startup --- Tweak.x | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Tweak.x b/Tweak.x index d7042de..10dea31 100644 --- a/Tweak.x +++ b/Tweak.x @@ -271,21 +271,38 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati } else if (strcmp(argv[0], "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { // Sanity check on the SimulateCrash service mach_port_t bootstrap = MACH_PORT_NULL; - task_get_bootstrap_port(mach_task_self(), &bootstrap); + 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); + } + if (err == 0) { + mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); + } else { const CFTypeRef keys[] = { kCFUserNotificationAlertHeaderKey, kCFUserNotificationAlertMessageKey, kCFUserNotificationDefaultButtonTitleKey, }; - const CFTypeRef values[] = { + const CFTypeRef valuesCrash[] = { 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("OK"), }; - CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + 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); SInt32 err = 0; CFUserNotificationRef notification = CFUserNotificationCreate(kCFAllocatorDefault, 0.0, kCFUserNotificationPlainAlertLevel, &err, dict); CFRunLoopSourceRef runLoopSource = CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, notification, SanityCheckNotificationCallback, 0); From 34b63d32a96dee29e8aeb47518862787a24fbec4 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 00:20:48 -0400 Subject: [PATCH 12/65] Fix re-registration --- Tweak.x | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tweak.x b/Tweak.x index 10dea31..cc35d11 100644 --- a/Tweak.x +++ b/Tweak.x @@ -137,6 +137,9 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) containedName = NO; } else { containedName = [allowedNames containsObject:serviceNameString]; + if (!containedName) { + [allowedNames addObject:serviceNameString]; + } } OSSpinLockUnlock(&namesLock); [pool drain]; From 9cf59248fccb9147b6321eca2f82ee1d440a385e Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 00:32:36 -0400 Subject: [PATCH 13/65] Monitor and relaunch rocketd --- Tweak.x | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ rocketd.c | 5 +++ 2 files changed, 123 insertions(+) diff --git a/Tweak.x b/Tweak.x index cc35d11..66e2b48 100644 --- a/Tweak.x +++ b/Tweak.x @@ -17,6 +17,8 @@ #import //#import #import +#import +#import extern int *_NSGetArgc(void); extern const char ***_NSGetArgv(void); @@ -258,6 +260,121 @@ static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_heade return result; } +static pid_t pid_of_process(const char *process_name) +{ + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; + size_t miblen = 4; + + size_t size; + int st = sysctl(mib, miblen, NULL, &size, NULL, 0); + + struct kinfo_proc * process = NULL; + struct kinfo_proc * newprocess = NULL; + + do { + size += size / 10; + newprocess = (struct kinfo_proc *)realloc(process, size); + + if (!newprocess) { + if (process) { + free(process); + } + return 0; + } + + process = newprocess; + st = sysctl(mib, miblen, process, &size, NULL, 0); + + } while (st == -1 && errno == ENOMEM); + + if (st == 0) { + if (size % sizeof(struct kinfo_proc) == 0) { + int nprocess = size / sizeof(struct kinfo_proc); + if (nprocess) { + for (int i = nprocess - 1; i >= 0; i--) { + if (strcmp(process[i].kp_proc.p_comm, process_name) == 0) { + pid_t result = process[i].kp_proc.p_pid; + free(process); + return result; + } + } + } + } + } + + free(process); + return 0; +} + +static int daemon_die_queue; +static CFFileDescriptorRef daemon_die_fd; +static CFRunLoopSourceRef daemon_die_source; + +static void process_terminate_callback(CFFileDescriptorRef fd, CFOptionFlags callBackTypes, void *info); + +static void observe_rocketd(void) +{ + // Force the daemon to load + 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.rpetrich.rocketbootstrapd", &servicesPort); + if (err) { + //NSLog(@"RocketBootstrap: failed to launch rocketd!"); + } else { + mach_port_name_t replyPort = MACH_PORT_NULL; + err = mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &replyPort); + if (err == 0) { + LMResponseBuffer buffer; + uint32_t size = LMBufferSizeForLength(0); + memset(&buffer.message, 0, sizeof(LMMessage)); + buffer.message.head.msgh_id = 2; + buffer.message.head.msgh_size = size; + buffer.message.head.msgh_local_port = replyPort; + buffer.message.head.msgh_reserved = 0; + buffer.message.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); + buffer.message.head.msgh_remote_port = servicesPort; + 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) { + } + // Cleanup + mach_port_mod_refs(self, replyPort, MACH_PORT_RIGHT_RECEIVE, -1); + } + mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); + } + // Find it + pid_t pid = pid_of_process("rocketd"); + if (pid) { + //NSLog(@"RocketBootstrap: rocketd found: %d", pid); + daemon_die_queue = kqueue(); + struct kevent changes; + EV_SET(&changes, pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL); + (void)kevent(daemon_die_queue, &changes, 1, &changes, 1, NULL); + daemon_die_fd = CFFileDescriptorCreate(NULL, daemon_die_queue, true, process_terminate_callback, NULL); + daemon_die_source = CFFileDescriptorCreateRunLoopSource(NULL, daemon_die_fd, 0); + CFRunLoopAddSource(CFRunLoopGetCurrent(), daemon_die_source, kCFRunLoopDefaultMode); + CFFileDescriptorEnableCallBacks(daemon_die_fd, kCFFileDescriptorReadCallBack); + } else { + NSLog(@"RocketBootstrap: unable to find rocketd!"); + } +} + +static void process_terminate_callback(CFFileDescriptorRef fd, CFOptionFlags callBackTypes, void *info) +{ + struct kevent event; + (void)kevent(daemon_die_queue, NULL, 0, &event, 1, NULL); + NSLog(@"RocketBootstrap: rocketd terminated: %d, relaunching", (int)(pid_t)event.ident); + // Cleanup + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), daemon_die_source, kCFRunLoopDefaultMode); + CFRelease(daemon_die_source); + CFRelease(daemon_die_fd); + close(daemon_die_queue); + observe_rocketd(); +} + static void SanityCheckNotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) { } @@ -289,6 +406,7 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati } if (err == 0) { mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); + observe_rocketd(); } else { const CFTypeRef keys[] = { kCFUserNotificationAlertHeaderKey, diff --git a/rocketd.c b/rocketd.c index c97a0d5..067fab6 100644 --- a/rocketd.c +++ b/rocketd.c @@ -44,6 +44,11 @@ static void machPortCallback(CFMachPortRef port, void *bytes, CFIndex size, void #endif } break; + case 2: + // Good morning, still awake + reply_data = &one; + reply_length = sizeof one; + break; } CFRelease(name); } From 9d8295c933cf5ba71f6c25681bb22433a9c0e4a9 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 00:38:00 -0400 Subject: [PATCH 14/65] Early exit on old iOS versions --- Tweak.x | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tweak.x b/Tweak.x index 66e2b48..cb7c032 100644 --- a/Tweak.x +++ b/Tweak.x @@ -389,6 +389,9 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati isDaemon = YES; MSHookFunction(mach_msg_server_once, $mach_msg_server_once, (void **)&_mach_msg_server_once); } else if (strcmp(argv[0], "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { + if (kCFCoreFoundationVersionNumber < 847.20) { + return; + } // Sanity check on the SimulateCrash service mach_port_t bootstrap = MACH_PORT_NULL; mach_port_t self = mach_task_self(); From 100fbb30eec7af20fb7721260697a26b2c189a58 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 00:38:45 -0400 Subject: [PATCH 15/65] Add beta depiction --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 7f2006c..b9d110c 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.3 Architecture: iphoneos-arm Description: mach lookup support library for iOS -Depiction: http://rpetri.ch/cydia/rocketbootstrap/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From cb4c72dddf13cf205c1e3038964d9ac4d78e9986 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 00:40:13 -0400 Subject: [PATCH 16/65] Public Release 1.0.4 beta 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index b9d110c..f848fed 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.3 +Version: 1.0.4~beta1 Architecture: iphoneos-arm Description: mach lookup support library for iOS Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ From 0949410aee48f631f61e076eb8c84dafc05ceb4f Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 08:47:24 -0400 Subject: [PATCH 17/65] Disable non-working rocketd test --- Tweak.x | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Tweak.x b/Tweak.x index cb7c032..880ed76 100644 --- a/Tweak.x +++ b/Tweak.x @@ -398,14 +398,14 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati 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; + //bool has_simulate_crash; if (err) { - has_simulate_crash = false; + //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); + //has_simulate_crash = true; + //servicesPort = MACH_PORT_NULL; + //err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); } if (err == 0) { mach_port_mod_refs(self, servicesPort, MACH_PORT_RIGHT_SEND, -1); @@ -421,12 +421,12 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati 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("OK"), }; - const CFTypeRef valuesRocket[] = { + /*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, /*has_simulate_crash ? (const void **)valuesRocket :*/ (const void **)valuesCrash, 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); From 28768ab39367b1c5a0d3a514da1a4a089edc7122 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 26 Oct 2015 08:47:53 -0400 Subject: [PATCH 18/65] Public Release 1.0.4 beta 2 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index f848fed..6685643 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.4~beta1 +Version: 1.0.4~beta2 Architecture: iphoneos-arm Description: mach lookup support library for iOS Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ From 6dae69c969ffff728231754a33ed0e18c9e7a1d4 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 1 Nov 2015 20:24:26 -0500 Subject: [PATCH 19/65] Restore non-beta depiction URL --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 6685643..1781be8 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.4~beta2 Architecture: iphoneos-arm Description: mach lookup support library for iOS -Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From bd54f4ac8452ce2dc2978459afc262440ce94f19 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 1 Nov 2015 20:34:05 -0500 Subject: [PATCH 20/65] Public Release 1.0.4 --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 1781be8..94faa23 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,9 +1,9 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.4~beta2 +Version: 1.0.4 Architecture: iphoneos-arm -Description: mach lookup support library for iOS +Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: http://rpetri.ch/cydia/rocketbootstrap/ Homepage: http://rpetri.ch/cydia/rocketbootstrap/ Maintainer: BigBoss From 06e2eba2c7c998c89d88623c77dfdca71fe59357 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 2 Jan 2017 20:14:19 -0500 Subject: [PATCH 21/65] Support iOS 10; Log in more places when DEBUG=1 --- Tweak.x | 233 ++++++++++++----- dispatch/mach_private.h | 546 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 721 insertions(+), 58 deletions(-) create mode 100644 dispatch/mach_private.h diff --git a/Tweak.x b/Tweak.x index 880ed76..735c8c4 100644 --- a/Tweak.x +++ b/Tweak.x @@ -19,6 +19,10 @@ #import #import #import +#import +#define __DISPATCH_INDIRECT__ +#define DISPATCH_MACH_SPI 1 +#import extern int *_NSGetArgc(void); extern const char ***_NSGetArgv(void); @@ -30,6 +34,9 @@ static BOOL isDaemon; static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const name_t service_name, mach_port_t *sp, mach_msg_timeout_t timeout) { +#ifdef DEBUG + NSLog(@"RocketBootstrap: rocketbootstrap_look_up(%llu, %s, %p)", (unsigned long long)bp, service_name, sp); +#endif if (rocketbootstrap_is_passthrough() || isDaemon) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_5_0) { int sandbox_result = sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_LOCAL_NAME | SANDBOX_CHECK_NO_REPORT, service_name); @@ -54,13 +61,20 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const // Ask our service running inside of the com.apple.ReportCrash.SimulateCrash job mach_port_t servicesPort = MACH_PORT_NULL; kern_return_t err = bootstrap_look_up(bp, "com.apple.ReportCrash.SimulateCrash", &servicesPort); - if (err) + if (err) { +#ifdef DEBUG + NSLog(@"RocketBootstrap: = %lld (failed to lookup com.apple.ReportCrash.SimulateCrash)", (unsigned long long)err); +#endif return err; + } mach_port_t selfTask = mach_task_self(); // Create a reply port mach_port_name_t replyPort = MACH_PORT_NULL; err = mach_port_allocate(selfTask, MACH_PORT_RIGHT_RECEIVE, &replyPort); if (err) { +#ifdef DEBUG + NSLog(@"RocketBootstrap: = %lld (failed to allocate port)", (unsigned long long)err); +#endif mach_port_deallocate(selfTask, servicesPort); return err; } @@ -91,10 +105,17 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const // Parse response if (!err) { _rocketbootstrap_lookup_response_t *response = (_rocketbootstrap_lookup_response_t *)message; - if (response->body.msgh_descriptor_count) + if (response->body.msgh_descriptor_count) { *sp = response->response_port.name; - else +#ifdef DEBUG + NSLog(@"RocketBootstrap: = 0 (success)"); +#endif + } else { err = 1; +#ifdef DEBUG + NSLog(@"RocketBootstrap: = 1 (disallowed)"); +#endif + } } // Cleanup mach_port_deallocate(selfTask, servicesPort); @@ -126,6 +147,9 @@ static void daemon_restarted_callback(CFNotificationCenterRef center, void *obse kern_return_t rocketbootstrap_unlock(const name_t service_name) { +#ifdef DEBUG + NSLog(@"RocketBootstrap: rocketbootstrap_unlock(%s)", service_name); +#endif if (rocketbootstrap_is_passthrough()) return 0; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -167,6 +191,66 @@ kern_return_t rocketbootstrap_register(mach_port_t bp, name_t service_name, mach } #pragma GCC diagnostic warning "-Wdeprecated-declarations" +static kern_return_t handle_bootstrap_lookup_msg(mach_msg_header_t *request) +{ + _rocketbootstrap_lookup_query_t *lookup_message = (_rocketbootstrap_lookup_query_t *)request; + // Extract service name + size_t length = request->msgh_size - offsetof(_rocketbootstrap_lookup_query_t, name); + if (lookup_message->name_length <= length) { + length = lookup_message->name_length; + } +#ifdef DEBUG + NSLog(@"RocketBootstrap: handle_bootstrap_lookup_msg(%.*s)", (int)length, &lookup_message->name[0]); +#endif + // Ask rocketd if it's unlocked + LMResponseBuffer buffer; + if (LMConnectionSendTwoWay(&connection, 1, &lookup_message->name[0], length, &buffer)) + return 1; + BOOL nameIsAllowed = LMResponseConsumeInteger(&buffer) != 0; + // Lookup service port + mach_port_t servicePort = MACH_PORT_NULL; + mach_port_t selfTask = mach_task_self(); + kern_return_t err; + if (nameIsAllowed) { + mach_port_t bootstrap = MACH_PORT_NULL; + err = task_get_bootstrap_port(selfTask, &bootstrap); + if (!err) { + char *buffer = malloc(length + 1); + if (buffer) { + memcpy(buffer, lookup_message->name, length); + buffer[length] = '\0'; + err = bootstrap_look_up(bootstrap, buffer, &servicePort); + free(buffer); + } + } + } + // Generate response + _rocketbootstrap_lookup_response_t response; + response.head.msgh_id = 0; + response.head.msgh_size = (sizeof(_rocketbootstrap_lookup_response_t) + 3) & ~3; + response.head.msgh_remote_port = request->msgh_remote_port; + response.head.msgh_local_port = MACH_PORT_NULL; + response.head.msgh_reserved = 0; + response.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); + if (servicePort != MACH_PORT_NULL) { + response.head.msgh_bits |= MACH_MSGH_BITS_COMPLEX; + response.body.msgh_descriptor_count = 1; + response.response_port.name = servicePort; + response.response_port.disposition = MACH_MSG_TYPE_COPY_SEND; + response.response_port.type = MACH_MSG_PORT_DESCRIPTOR; + } else { + response.body.msgh_descriptor_count = 0; + } + // Send response + err = mach_msg(&response.head, MACH_SEND_MSG, response.head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (err) { + if (servicePort != MACH_PORT_NULL) { + mach_port_mod_refs(selfTask, servicePort, MACH_PORT_RIGHT_SEND, -1); + } + } + return err; +} + 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); 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); @@ -177,60 +261,15 @@ static bool continue_server_once; 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 if (request->msgh_id == ROCKETBOOTSTRAP_LOOKUP_ID) { continue_server_once = true; - _rocketbootstrap_lookup_query_t *lookup_message = (_rocketbootstrap_lookup_query_t *)request; - // Extract service name - size_t length = request->msgh_size - offsetof(_rocketbootstrap_lookup_query_t, name); - if (lookup_message->name_length <= length) { - length = lookup_message->name_length; - } - // Ask rocketd if it's unlocked - LMResponseBuffer buffer; - if (LMConnectionSendTwoWay(&connection, 1, &lookup_message->name[0], length, &buffer)) - return false; - BOOL nameIsAllowed = LMResponseConsumeInteger(&buffer) != 0; - // Lookup service port - mach_port_t servicePort = MACH_PORT_NULL; - mach_port_t selfTask = mach_task_self(); - kern_return_t err; - if (nameIsAllowed) { - mach_port_t bootstrap = MACH_PORT_NULL; - err = task_get_bootstrap_port(selfTask, &bootstrap); - if (!err) { - char *buffer = malloc(length + 1); - if (buffer) { - memcpy(buffer, lookup_message->name, length); - buffer[length] = '\0'; - err = bootstrap_look_up(bootstrap, buffer, &servicePort); - free(buffer); - } - } - } - // Generate response - _rocketbootstrap_lookup_response_t response; - response.head.msgh_id = 0; - response.head.msgh_size = (sizeof(_rocketbootstrap_lookup_response_t) + 3) & ~3; - response.head.msgh_remote_port = request->msgh_remote_port; - response.head.msgh_local_port = MACH_PORT_NULL; - response.head.msgh_reserved = 0; - response.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); - if (servicePort != MACH_PORT_NULL) { - response.head.msgh_bits |= MACH_MSGH_BITS_COMPLEX; - response.body.msgh_descriptor_count = 1; - response.response_port.name = servicePort; - response.response_port.disposition = MACH_MSG_TYPE_COPY_SEND; - response.response_port.type = MACH_MSG_PORT_DESCRIPTOR; - } else { - response.body.msgh_descriptor_count = 0; - } - // Send response - err = mach_msg(&response.head, MACH_SEND_MSG, response.head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + kern_return_t err = handle_bootstrap_lookup_msg(request); if (err) { - if (servicePort != MACH_PORT_NULL) - mach_port_mod_refs(selfTask, servicePort, MACH_PORT_RIGHT_SEND, -1); - mach_port_mod_refs(selfTask, reply->msgh_remote_port, MACH_PORT_RIGHT_SEND_ONCE, -1); + mach_port_mod_refs(mach_task_self(), reply->msgh_remote_port, MACH_PORT_RIGHT_SEND_ONCE, -1); } return true; } @@ -239,6 +278,9 @@ static boolean_t new_demux(mach_msg_header_t *request, mach_msg_header_t *reply) 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 OSSpinLockLock(&server_once_lock); if (!server_once_demux_orig) { @@ -260,6 +302,41 @@ static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_heade return result; } +static void *interceptedConnection; + +static void *(*_xpc_connection_create_mach_service)(const char *name, dispatch_queue_t targetq, uint64_t flags); +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) { + void *result = _xpc_connection_create_mach_service(name, targetq, flags); + interceptedConnection = result; + return result; + } + return _xpc_connection_create_mach_service(name, targetq, flags); +} + +static void (*__xpc_connection_mach_event)(void *context, dispatch_mach_reason_t reason, dispatch_mach_msg_t message, mach_error_t error); +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 + if ((reason == DISPATCH_MACH_MESSAGE_RECEIVED) && (context == interceptedConnection)) { + size_t size; + mach_msg_header_t *header = dispatch_mach_msg_get_msg(message, &size); + if (header->msgh_id == ROCKETBOOTSTRAP_LOOKUP_ID) { + handle_bootstrap_lookup_msg(header); + return; + } + } + return __xpc_connection_mach_event(context, reason, message, error); +} + + static pid_t pid_of_process(const char *process_name) { int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; @@ -321,7 +398,9 @@ static void observe_rocketd(void) mach_port_t servicesPort = MACH_PORT_NULL; kern_return_t err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); if (err) { - //NSLog(@"RocketBootstrap: failed to launch rocketd!"); +#ifdef DEBUG + NSLog(@"RocketBootstrap: failed to launch rocketd!"); +#endif } else { mach_port_name_t replyPort = MACH_PORT_NULL; err = mach_port_allocate(self, MACH_PORT_RIGHT_RECEIVE, &replyPort); @@ -348,7 +427,9 @@ static void observe_rocketd(void) // Find it pid_t pid = pid_of_process("rocketd"); if (pid) { - //NSLog(@"RocketBootstrap: rocketd found: %d", pid); +#ifdef DEBUG + NSLog(@"RocketBootstrap: rocketd found: %d", pid); +#endif daemon_die_queue = kqueue(); struct kevent changes; EV_SET(&changes, pid, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL); @@ -385,10 +466,46 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati // Attach rockets when in the com.apple.ReportCrash.SimulateCrash 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] && strcmp(argv[1], "-f") == 0) { - isDaemon = YES; - MSHookFunction(mach_msg_server_once, $mach_msg_server_once, (void **)&_mach_msg_server_once); + 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); + } 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 { +#ifdef DEBUG + 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) { + MSHookFunction(_xpc_connection_mach_event, $_xpc_connection_mach_event, (void **)&__xpc_connection_mach_event); + } else { +#ifdef DEBUG + NSLog(@"RocketBootstrap: Could not find _xpc_connection_mach_event symbol!"); +#endif + } + } else { +#ifdef DEBUG + NSLog(@"RocketBootstrap: Could not find libxpc.dylib image!"); +#endif + } + } } else if (strcmp(argv[0], "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { +#ifdef DEBUG + NSLog(@"RocketBootstrap: Initializing SpringBoard"); +#endif if (kCFCoreFoundationVersionNumber < 847.20) { return; } diff --git a/dispatch/mach_private.h b/dispatch/mach_private.h new file mode 100644 index 0000000..2146fea --- /dev/null +++ b/dispatch/mach_private.h @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2012-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +/* + * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch + * which are subject to change in future releases of Mac OS X. Any applications + * relying on these interfaces WILL break. + */ + +#ifndef __DISPATCH_MACH_PRIVATE__ +#define __DISPATCH_MACH_PRIVATE__ + +#ifndef __DISPATCH_INDIRECT__ +#error "Please #include instead of this file directly." +#include // for HeaderDoc +#endif + +__BEGIN_DECLS + +#if DISPATCH_MACH_SPI + +#include + +/*! + * @functiongroup Dispatch Mach Channel SPI + * + * IMPORTANT: This is Libsystem-internal SPI not intended for general use and + * is subject to change at any time without warning. + */ + +/*! + * @typedef dispatch_mach_t + * A dispatch mach channel asynchronously recevives and sends mach messages. + */ +DISPATCH_DECL(dispatch_mach); + +/*! + * @typedef dispatch_mach_reason_t + * Reasons for a mach channel handler to be invoked. + * + * @const DISPATCH_MACH_CONNECTED + * The channel has been connected. The first handler invocation on a channel + * after calling dispatch_mach_connect() will have this reason. + * + * @const DISPATCH_MACH_MESSAGE_RECEIVED + * A message was received, it is passed in the message parameter. + * + * @const DISPATCH_MACH_MESSAGE_SENT + * A message was sent, it is passed in the message parameter (so that associated + * resources can be disposed of). + * + * @const DISPATCH_MACH_MESSAGE_SEND_FAILED + * A message failed to be sent, it is passed in the message parameter (so that + * associated resources can be disposed of), along with the error code from + * mach_msg(). + * + * @const DISPATCH_MACH_MESSAGE_NOT_SENT + * A message was not sent due to the channel being canceled or reconnected, it + * is passed in the message parameter (so that associated resources can be + * disposed of). + * + * @const DISPATCH_MACH_BARRIER_COMPLETED + * A barrier block has finished executing. + * + * @const DISPATCH_MACH_DISCONNECTED + * The channel has been disconnected by a call to dispatch_mach_reconnect() or + * dispatch_mach_cancel(), an empty message is passed in the message parameter + * (so that associated port rights can be disposed of). + * The message header will contain either a remote port with a previously + * connected send right, or a local port with a previously connected receive + * right (if the channel was canceled), or a local port with a receive right + * that was being monitored for a direct reply to a message previously sent to + * the channel (if no reply was received). + * + * @const DISPATCH_MACH_CANCELED + * The channel has been canceled. + */ +DISPATCH_ENUM(dispatch_mach_reason, unsigned long, + DISPATCH_MACH_CONNECTED = 1, + DISPATCH_MACH_MESSAGE_RECEIVED, + DISPATCH_MACH_MESSAGE_SENT, + DISPATCH_MACH_MESSAGE_SEND_FAILED, + DISPATCH_MACH_MESSAGE_NOT_SENT, + DISPATCH_MACH_BARRIER_COMPLETED, + DISPATCH_MACH_DISCONNECTED, + DISPATCH_MACH_CANCELED, + DISPATCH_MACH_REASON_LAST, /* unused */ +); + +/*! + * @typedef dispatch_mach_trailer_t + * Trailer type of mach message received by dispatch mach channels + */ + +typedef mach_msg_context_trailer_t dispatch_mach_trailer_t; + +/*! + * @constant DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE + * Maximum size of a message that can be received inline by a dispatch mach + * channel, reception of larger messages requires an extra roundtrip through + * the kernel. + */ + +#define DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE \ + (0x4000 - sizeof(dispatch_mach_trailer_t)) + +/*! + * @typedef dispatch_mach_msg_t + * A dispatch mach message encapsulates messages received or sent with dispatch + * mach channels. + */ +DISPATCH_DECL(dispatch_mach_msg); + +/*! + * @typedef dispatch_mach_msg_destructor_t + * Dispatch mach message object destructors. + * + * @const DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT + * Message buffer storage is internal to the object, if a buffer is supplied + * during object creation, its contents are copied. + * + * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE + * Message buffer will be deallocated with free(3). + * + * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE + * Message buffer will be deallocated with vm_deallocate. + */ +DISPATCH_ENUM(dispatch_mach_msg_destructor, unsigned int, + DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT = 0, + DISPATCH_MACH_MSG_DESTRUCTOR_FREE, + DISPATCH_MACH_MSG_DESTRUCTOR_VM_DEALLOCATE, +); + +/*! + * @function dispatch_mach_msg_create + * Creates a dispatch mach message object, either with a newly allocated message + * buffer of given size, or from an existing message buffer that will be + * deallocated with the specified destructor when the object is released. + * + * If a non-NULL reference to a pointer is provided in 'msg_ptr', it is filled + * with the location of the (possibly newly allocated) message buffer. + * + * It is the responsibility of the application to ensure that it does not modify + * the underlying message buffer once the dispatch mach message object is passed + * to other dispatch mach API. + * + * @param msg The message buffer to create the message object from. + * If 'destructor' is DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT, + * this argument may be NULL to leave the newly allocated + * message buffer zero-initialized. + * @param size The size of the message buffer. + * Must be >= sizeof(mach_msg_header_t) + * @param destructor The destructor to use to deallocate the message buffer + * when the object is released. + * @param msg_ptr A pointer to a pointer variable to be filled with the + * location of the (possibly newly allocated) message + * buffer, or NULL. + * @result A newly created dispatch mach message object. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT +DISPATCH_NOTHROW +dispatch_mach_msg_t +dispatch_mach_msg_create(mach_msg_header_t *msg, size_t size, + dispatch_mach_msg_destructor_t destructor, mach_msg_header_t **msg_ptr); + +/*! + * @function dispatch_mach_msg_get_msg + * Returns the message buffer underlying a dispatch mach message object. + * + * @param message The dispatch mach message object to query. + * @param size_ptr A pointer to a size_t variable to be filled with the + * size of the message buffer, or NULL. + * @result Pointer to message buffer underlying the object. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW +mach_msg_header_t* +dispatch_mach_msg_get_msg(dispatch_mach_msg_t message, size_t *size_ptr); + +#ifdef __BLOCKS__ +/*! + * @typedef dispatch_mach_handler_t + * Prototype of dispatch mach channel handler blocks. + * + * @param reason Reason the handler was invoked. + * @param message Message object that was sent or received. + * @param error Mach error code for the send operation. + */ +typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason_t reason, + dispatch_mach_msg_t message, mach_error_t error); + +/*! + * @function dispatch_mach_create + * Create a dispatch mach channel to asynchronously receive and send mach + * messages. + * + * The specified handler will be called with the corresponding reason parameter + * for each message received and for each message that was successfully sent, + * that failed to be sent, or was not sent; as well as when a barrier block + * has completed, or when channel connection, reconnection or cancellation has + * taken effect. + * + * Dispatch mach channels are created in a disconnected state, they must be + * connected via dispatch_mach_connect() to begin receiving and sending + * messages. + * + * @param label + * An optional string label to attach to the channel. The string is not copied, + * if it is non-NULL it must point to storage that remains valid for the + * lifetime of the channel object. May be NULL. + * + * @param queue + * The target queue of the channel, where the handler and barrier blocks will + * be submitted. + * + * @param handler + * The handler block to submit when a message has been sent or received. + * + * @result + * The newly created dispatch mach channel. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT +DISPATCH_NONNULL3 DISPATCH_NOTHROW +dispatch_mach_t +dispatch_mach_create(const char *label, dispatch_queue_t queue, + dispatch_mach_handler_t handler); +#endif + +/*! + * @typedef dispatch_mach_handler_function_t + * Prototype of dispatch mach channel handler functions. + * + * @param context Application-defined context parameter. + * @param reason Reason the handler was invoked. + * @param message Message object that was sent or received. + * @param error Mach error code for the send operation. + */ +typedef void (*dispatch_mach_handler_function_t)(void *context, + dispatch_mach_reason_t reason, dispatch_mach_msg_t message, + mach_error_t error); + +/*! + * @function dispatch_mach_create_f + * Create a dispatch mach channel to asynchronously receive and send mach + * messages. + * + * The specified handler will be called with the corresponding reason parameter + * for each message received and for each message that was successfully sent, + * that failed to be sent, or was not sent; as well as when a barrier block + * has completed, or when channel connection, reconnection or cancellation has + * taken effect. + * + * Dispatch mach channels are created in a disconnected state, they must be + * connected via dispatch_mach_connect() to begin receiving and sending + * messages. + * + * @param label + * An optional string label to attach to the channel. The string is not copied, + * if it is non-NULL it must point to storage that remains valid for the + * lifetime of the channel object. May be NULL. + * + * @param queue + * The target queue of the channel, where the handler and barrier blocks will + * be submitted. + * + * @param context + * The application-defined context to pass to the handler. + * + * @param handler + * The handler function to submit when a message has been sent or received. + * + * @result + * The newly created dispatch mach channel. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT +DISPATCH_NONNULL4 DISPATCH_NOTHROW +dispatch_mach_t +dispatch_mach_create_f(const char *label, dispatch_queue_t queue, void *context, + dispatch_mach_handler_function_t handler); + +/*! + * @function dispatch_mach_connect + * Connect a mach channel to the specified receive and send rights. + * + * This function must only be called once during the lifetime of a channel, it + * will initiate message reception and perform any already submitted message + * sends or barrier operations. + * + * @param channel + * The mach channel to connect. + * + * @param receive + * The receive right to associate with the channel. May be MACH_PORT_NULL. + * + * @param send + * The send right to associate with the channel. May be MACH_PORT_NULL. + * + * @param checkin + * An optional message object encapsulating the initial check-in message to send + * upon channel connection. The check-in message is sent immediately before the + * first message submitted via dispatch_mach_send(). The message object will be + * retained until the initial send operation is complete (or not peformed due + * to channel cancellation or reconnection) and the channel handler has + * returned. May be NULL. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW +void +dispatch_mach_connect(dispatch_mach_t channel, mach_port_t receive, + mach_port_t send, dispatch_mach_msg_t checkin); + +/*! + * @function dispatch_mach_reconnect + * Reconnect a mach channel to the specified send right. + * + * Disconnects the channel from the current send right, interrupts any pending + * message sends (and returns the messages as unsent), and reconnects the + * channel to a new send right. + * + * The application must wait for the channel handler to be invoked with + * DISPATCH_MACH_DISCONNECTED before releasing the previous send right. + * + * @param channel + * The mach channel to reconnect. + * + * @param send + * The new send right to associate with the channel. May be MACH_PORT_NULL. + * + * @param checkin + * An optional message object encapsulating the initial check-in message to send + * upon channel reconnection. The check-in message is sent immediately before + * the first message submitted via dispatch_mach_send() after this function + * returns. The message object will be retained until the initial send operation + * is complete (or not peformed due to channel cancellation or reconnection) + * and the channel handler has returned. May be NULL. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW +void +dispatch_mach_reconnect(dispatch_mach_t channel, mach_port_t send, + dispatch_mach_msg_t checkin); + +/*! + * @function dispatch_mach_cancel + * Cancel a mach channel, preventing any further messages from being sent or + * received. + * + * The application must wait for the channel handler to be invoked with + * DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive + * rights. + * + * Note: explicit cancellation of mach channels is required, no implicit + * cancellation takes place on release of the last application reference + * to the channel object. Failure to cancel will cause the channel and + * its associated resources to be leaked. + * + * @param channel + * The mach channel to cancel. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW +void +dispatch_mach_cancel(dispatch_mach_t channel); + +/*! + * @function dispatch_mach_send + * Asynchronously send a message encapsulated in a dispatch mach message object + * to the specified mach channel. + * + * Unless the message is being sent to a send-once right (as determined by the + * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits), + * the message header remote port is set to the channel send right before the + * send operation is performed. + * + * If the message expects a direct reply (as determined by the presence of + * MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive + * right specified in the message header local port will be monitored until a + * reply message (or a send-once notification) is received, or the channel is + * canceled. Hence the application must wait for the channel handler to be + * invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that + * receive right. + * + * If the message send operation is attempted but the channel is canceled + * before the send operation succesfully completes, the message returned to the + * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a + * pseudo-receive operation. If the message expected a direct reply, the + * receive right originally specified in the message header local port will + * returned in a DISPATCH_MACH_DISCONNECTED message. + * + * @param channel + * The mach channel to which to send the message. + * + * @param message + * The message object encapsulating the message to send. The object will be + * retained until the send operation is complete and the channel handler has + * returned. The storage underlying the message object may be modified by the + * send operation. + * + * @param options + * Additional send options to pass to mach_msg() when performing the send + * operation. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW +void +dispatch_mach_send(dispatch_mach_t channel, dispatch_mach_msg_t message, + mach_msg_option_t options); + +#ifdef __BLOCKS__ +/*! + * @function dispatch_mach_send_barrier + * Submit a send barrier to the specified mach channel. Messages submitted to + * the channel before the barrier will be sent before the barrier block is + * executed, and messages submitted to the channel after the barrier will only + * be sent once the barrier block has completed and the channel handler + * invocation for the barrier has returned. + * + * @param channel + * The mach channel to which to submit the barrier. + * + * @param barrier + * The barrier block to submit to the channel target queue. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW +void +dispatch_mach_send_barrier(dispatch_mach_t channel, dispatch_block_t barrier); +#endif + +/*! + * @function dispatch_mach_send_barrier_f + * Submit a send barrier to the specified mach channel. Messages submitted to + * the channel before the barrier will be sent before the barrier block is + * executed, and messages submitted to the channel after the barrier will only + * be sent once the barrier block has completed and the channel handler + * invocation for the barrier has returned. + * + * @param channel + * The mach channel to which to submit the barrier. + * + * @param context + * The application-defined context parameter to pass to the function. + * + * @param barrier + * The barrier function to submit to the channel target queue. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW +void +dispatch_mach_send_barrier_f(dispatch_mach_t channel, void *context, + dispatch_function_t barrier); + +#ifdef __BLOCKS__ +/*! + * @function dispatch_mach_receive_barrier + * Submit a receive barrier to the specified mach channel. Channel handlers for + * messages received by the channel after the receive barrier has been + * submitted will only be invoked once the barrier block has completed and the + * channel handler invocation for the barrier has returned. + * + * @param channel + * The mach channel to which to submit the receive barrier. + * + * @param barrier + * The barrier block to submit to the channel target queue. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW +void +dispatch_mach_receive_barrier(dispatch_mach_t channel, + dispatch_block_t barrier); +#endif + +/*! + * @function dispatch_mach_receive_barrier_f + * Submit a receive barrier to the specified mach channel. Channel handlers for + * messages received by the channel after the receive barrier has been + * submitted will only be invoked once the barrier block has completed and the + * channel handler invocation for the barrier has returned. + * + * @param channel + * The mach channel to which to submit the receive barrier. + * + * @param context + * The application-defined context parameter to pass to the function. + * + * @param barrier + * The barrier function to submit to the channel target queue. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW +void +dispatch_mach_receive_barrier_f(dispatch_mach_t channel, void *context, + dispatch_function_t barrier); + +/*! + * @function dispatch_mach_get_checkin_port + * Returns the port specified in the message header remote port of the check-in + * message passed to the most recent invocation of dispatch_mach_connect() or + * dispatch_mach_reconnect() for the provided mach channel (irrespective of the + * completion of the (re)connect or check-in operations in question). + * + * Returns MACH_PORT_NULL if dispatch_mach_connect() has not yet been called or + * if the most recently specified check-in message was NULL, and MACH_PORT_DEAD + * if the channel has been canceled. + * + * It is the responsibility of the application to ensure that the port + * specified in a check-in message remains valid at the time this function is + * called. + * + * @param channel + * The mach channel to query. + * + * @result + * The most recently specified check-in port for the channel. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW +mach_port_t +dispatch_mach_get_checkin_port(dispatch_mach_t channel); + +#endif // DISPATCH_MACH_SPI + +__END_DECLS + +#endif \ No newline at end of file From b071fe7cdce8b9f955a2a723c31fd8fe6d538595 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 2 Jan 2017 20:15:09 -0500 Subject: [PATCH 22/65] Make log statements show up on iOS 10 --- Shims.x | 1 + Tweak.x | 1 + log.h | 15 +++++++++++++++ tests/tests.m | 1 + 4 files changed, 18 insertions(+) create mode 100644 log.h diff --git a/Shims.x b/Shims.x index 7aeaf39..5c21538 100644 --- a/Shims.x +++ b/Shims.x @@ -1,3 +1,4 @@ +#import "log.h" #import "rocketbootstrap_internal.h" #import diff --git a/Tweak.x b/Tweak.x index 735c8c4..c08011a 100644 --- a/Tweak.x +++ b/Tweak.x @@ -1,6 +1,7 @@ #define LIGHTMESSAGING_USE_ROCKETBOOTSTRAP 0 #define LIGHTMESSAGING_TIMEOUT 300 #import "LightMessaging/LightMessaging.h" +#import "log.h" #import "rocketbootstrap_internal.h" diff --git a/log.h b/log.h new file mode 100644 index 0000000..416ea06 --- /dev/null +++ b/log.h @@ -0,0 +1,15 @@ +#import + +// Tiny shim to convert NSLog to public os_log statements on iOS 10 +#ifdef __clang__ +#include +#define NSLog(...) do { \ + if (kCFCoreFoundationVersionNumber > 1299.0) { \ + @autoreleasepool { \ + os_log(OS_LOG_DEFAULT, "%{public}@", [NSString stringWithFormat:__VA_ARGS__]); \ + } \ + } else { \ + NSLog(__VA_ARGS__); \ + } \ +} while(0) +#endif diff --git a/tests/tests.m b/tests/tests.m index f117a48..cd6c8da 100644 --- a/tests/tests.m +++ b/tests/tests.m @@ -1,4 +1,5 @@ #import +#include "log.h" #import "rocketbootstrap.h" From 015bb8435cfbcde3884820cb44e9b303492106fc Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 2 Jan 2017 23:38:11 -0500 Subject: [PATCH 23/65] Support building using only a modern version of Xcode by default, but force release builds to fail if armv6 and old iOS support isn't available --- Makefile | 18 ++++++++++++++---- Tweak.x | 5 +++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 886da4d..3bcae2d 100644 --- a/Makefile +++ b/Makefile @@ -8,18 +8,28 @@ rocketd_FILES = rocketd.c rocketd_CFLAGS = -fblocks rocketd_FRAMEWORKS = CoreFoundation rocketd_INSTALL_PATH = /usr/libexec -rocketd_IPHONE_ARCHS = armv6 arm64 ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders -IPHONE_ARCHS = armv6 armv7 armv7s arm64 +# Support targeting 3.0 in packaged builds, but allow testing packages/builds to be missing support for old iOS versions +LEGACY_XCODE_PATH ?= /Applications/Xcode_Legacy.app +ifeq ($(wildcard $(LEGACY_XCODE_PATH)/.*),) +IPHONE_ARCHS = armv7 armv7s arm64 +TARGET_IPHONEOS_DEPLOYMENT_VERSION = 7.0 +ifeq ($(FINALPACKAGE),1) +$(error Building final package requires a legacy Xcode install!) +endif +else +rocketd_IPHONE_ARCHS = armv6 arm64 +IPHONE_ARCHS = armv6 armv7 armv7s arm64 SDKVERSION_armv6 = 5.1 INCLUDE_SDKVERSION_armv6 = 8.4 TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0 - +TARGET_IPHONEOS_DEPLOYMENT_VERSION_arm64 = 7.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 -THEOS_PLATFORM_SDK_ROOT_armv6 = /Applications/Xcode_Legacy.app/Contents/Developer +THEOS_PLATFORM_SDK_ROOT_armv6 = $(LEGACY_XCODE_PATH)/Contents/Developer +endif include framework/makefiles/common.mk include framework/makefiles/library.mk diff --git a/Tweak.x b/Tweak.x index c08011a..3faefc4 100644 --- a/Tweak.x +++ b/Tweak.x @@ -303,6 +303,8 @@ static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_heade return result; } +#ifdef __clang__ + static void *interceptedConnection; static void *(*_xpc_connection_create_mach_service)(const char *name, dispatch_queue_t targetq, uint64_t flags); @@ -337,6 +339,7 @@ static void $_xpc_connection_mach_event(void *context, dispatch_mach_reason_t re return __xpc_connection_mach_event(context, reason, message, error); } +#endif static pid_t pid_of_process(const char *process_name) { @@ -474,6 +477,7 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati 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 @@ -502,6 +506,7 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati NSLog(@"RocketBootstrap: Could not find libxpc.dylib image!"); #endif } +#endif } } else if (strcmp(argv[0], "/System/Library/CoreServices/SpringBoard.app/SpringBoard") == 0) { #ifdef DEBUG From 5b8a73caedab2b0cc5134c0e09db9b20284c15d9 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Tue, 3 Jan 2017 01:34:28 -0500 Subject: [PATCH 24/65] Introduce helper tool that reinstates rocketd (because the iOS 10.1 jailbreak has a problem with launch daemons failing to stay registered) --- Makefile | 6 +++++- Tweak.x | 4 ++++ layout/DEBIAN/postinst | 2 ++ rocketd_reenable.c | 13 +++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 rocketd_reenable.c diff --git a/Makefile b/Makefile index 3bcae2d..e9b7094 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,15 @@ librocketbootstrap_FILES = Tweak.x Shims.x librocketbootstrap_LIBRARIES = substrate librocketbootstrap_FRAMEWORKS = Foundation -TOOL_NAME = rocketd +TOOL_NAME = rocketd _rocketd_reenable rocketd_FILES = rocketd.c rocketd_CFLAGS = -fblocks rocketd_FRAMEWORKS = CoreFoundation rocketd_INSTALL_PATH = /usr/libexec +_rocketd_reenable_FILES = rocketd_reenable.c +_rocketd_reenable_INSTALL_PATH = /usr/libexec + ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders # Support targeting 3.0 in packaged builds, but allow testing packages/builds to be missing support for old iOS versions @@ -22,6 +25,7 @@ $(error Building final package requires a legacy Xcode install!) endif else rocketd_IPHONE_ARCHS = armv6 arm64 +_rocketd_reenable_IPHONE_ARCHS = armv6 arm64 IPHONE_ARCHS = armv6 armv7 armv7s arm64 SDKVERSION_armv6 = 5.1 INCLUDE_SDKVERSION_armv6 = 8.4 diff --git a/Tweak.x b/Tweak.x index 3faefc4..bec2b57 100644 --- a/Tweak.x +++ b/Tweak.x @@ -401,6 +401,10 @@ static void observe_rocketd(void) task_get_bootstrap_port(self, &bootstrap); mach_port_t servicesPort = MACH_PORT_NULL; kern_return_t err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); + if (err) { + system("/usr/libexec/_rocketd_reenable"); + err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); + } if (err) { #ifdef DEBUG NSLog(@"RocketBootstrap: failed to launch rocketd!"); diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst index e707090..f9fa636 100755 --- a/layout/DEBIAN/postinst +++ b/layout/DEBIAN/postinst @@ -3,3 +3,5 @@ launchctl load /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist || tru 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 +chmod +s /usr/libexec/_rocketd_reenable +chown root:wheel /usr/libexec/_rocketd_reenable diff --git a/rocketd_reenable.c b/rocketd_reenable.c new file mode 100644 index 0000000..c2cfab1 --- /dev/null +++ b/rocketd_reenable.c @@ -0,0 +1,13 @@ +#import + +int main(int argc, char *argv[]) +{ + close(0); + close(1); + close(2); + setuid(0); + setgid(0); + seteuid(0); + setegid(0); + return execlp("launchctl", "launchctl", "load", "/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist", NULL); +} From c7a70f1dea65eb34fed0dba163d93be068e56ec1 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Wed, 4 Jan 2017 08:39:30 -0500 Subject: [PATCH 25/65] Don't expose some internal hook symbols --- Shims.x | 4 ++-- Tweak.x | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Shims.x b/Shims.x index 5c21538..e79f382 100644 --- a/Shims.x +++ b/Shims.x @@ -8,9 +8,9 @@ static OSSpinLock spin_lock; kern_return_t bootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags) __attribute__((weak_import)); -kern_return_t (*_bootstrap_look_up3)(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags); +static kern_return_t (*_bootstrap_look_up3)(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags); -kern_return_t $bootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags) +static kern_return_t $bootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary; diff --git a/Tweak.x b/Tweak.x index bec2b57..732daf1 100644 --- a/Tweak.x +++ b/Tweak.x @@ -254,7 +254,7 @@ static kern_return_t handle_bootstrap_lookup_msg(mach_msg_header_t *request) 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); -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); +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); static volatile OSSpinLock server_once_lock; static boolean_t (*server_once_demux_orig)(mach_msg_header_t *, mach_msg_header_t *); From df8a64ccf711c763ac529dead3736e7bdbaac257 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Wed, 4 Jan 2017 08:56:05 -0500 Subject: [PATCH 26/65] Use beta depiction --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 94faa23..8218b4a 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.4 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: http://rpetri.ch/cydia/rocketbootstrap/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 78cb14c02d9402e190ec7a46b4684274a4ced173 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Wed, 4 Jan 2017 08:56:16 -0500 Subject: [PATCH 27/65] Public Release 1.0.5 beta 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 8218b4a..60e49b8 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.4 +Version: 1.0.5~beta1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ From 536da62a00ceac395e811bba36042da67caed017 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:41:45 -0500 Subject: [PATCH 28/65] Use unfair locks to avoid deadlocking in spin locks on iOS 10 --- Shims.x | 7 ++++--- Tweak.x | 19 ++++++++++--------- unfair_lock.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 unfair_lock.h diff --git a/Shims.x b/Shims.x index e79f382..be6547d 100644 --- a/Shims.x +++ b/Shims.x @@ -1,11 +1,12 @@ #import "log.h" +#import "unfair_lock.h" #import "rocketbootstrap_internal.h" #import #import #import -static OSSpinLock spin_lock; +static unfair_lock shim_lock; kern_return_t bootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags) __attribute__((weak_import)); static kern_return_t (*_bootstrap_look_up3)(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags); @@ -27,12 +28,12 @@ static kern_return_t $bootstrap_look_up3(mach_port_t bp, const name_t service_na static void hook_bootstrap_lookup(void) { static bool hooked_bootstrap_look_up; - OSSpinLockLock(&spin_lock); + unfair_lock_lock(&shim_lock); if (!hooked_bootstrap_look_up) { MSHookFunction(bootstrap_look_up3, $bootstrap_look_up3, (void **)&_bootstrap_look_up3); hooked_bootstrap_look_up = true; } - OSSpinLockUnlock(&spin_lock); + unfair_lock_unlock(&shim_lock); } CFMessagePortRef rocketbootstrap_cfmessageportcreateremote(CFAllocatorRef allocator, CFStringRef name) diff --git a/Tweak.x b/Tweak.x index 732daf1..b3bb08a 100644 --- a/Tweak.x +++ b/Tweak.x @@ -2,6 +2,7 @@ #define LIGHTMESSAGING_TIMEOUT 300 #import "LightMessaging/LightMessaging.h" #import "log.h" +#import "unfair_lock.h" #import "rocketbootstrap_internal.h" @@ -130,14 +131,14 @@ kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, } static NSMutableSet *allowedNames; -static volatile OSSpinLock namesLock; +static unfair_lock namesLock; static void daemon_restarted_callback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - OSSpinLockLock(&namesLock); + unfair_lock_lock(&namesLock); NSSet *allNames = [allowedNames copy]; - OSSpinLockUnlock(&namesLock); + unfair_lock_unlock(&namesLock); for (NSString *name in allNames) { const char *service_name = [name UTF8String]; LMConnectionSendOneWay(&connection, 0, service_name, strlen(service_name)); @@ -155,7 +156,7 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) return 0; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *serviceNameString = [NSString stringWithUTF8String:service_name]; - OSSpinLockLock(&namesLock); + unfair_lock_lock(&namesLock); BOOL containedName; if (!allowedNames) { allowedNames = [[NSMutableSet alloc] init]; @@ -168,7 +169,7 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) [allowedNames addObject:serviceNameString]; } } - OSSpinLockUnlock(&namesLock); + unfair_lock_unlock(&namesLock); [pool drain]; if (containedName) { return 0; @@ -256,7 +257,7 @@ mach_msg_return_t mach_msg_server_once(boolean_t (*demux)(mach_msg_header_t *, m 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); -static volatile OSSpinLock server_once_lock; +static unfair_lock server_once_lock; static boolean_t (*server_once_demux_orig)(mach_msg_header_t *, mach_msg_header_t *); static bool continue_server_once; @@ -283,18 +284,18 @@ static mach_msg_return_t $mach_msg_server_once(boolean_t (*demux)(mach_msg_heade 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 - OSSpinLockLock(&server_once_lock); + unfair_lock_lock(&server_once_lock); if (!server_once_demux_orig) { server_once_demux_orig = demux; demux = new_demux; } else if (server_once_demux_orig == demux) { demux = new_demux; } else { - OSSpinLockUnlock(&server_once_lock); + unfair_lock_unlock(&server_once_lock); mach_msg_return_t result = _mach_msg_server_once(demux, max_size, rcv_name, options); return result; } - OSSpinLockUnlock(&server_once_lock); + unfair_lock_unlock(&server_once_lock); mach_msg_return_t result; do { continue_server_once = false; diff --git a/unfair_lock.h b/unfair_lock.h new file mode 100644 index 0000000..24e953f --- /dev/null +++ b/unfair_lock.h @@ -0,0 +1,45 @@ +#if __IPHONE_OS_VERSION_MAX_ALLOWED > 100000 +// New SDK +#include +#define unfair_lock os_unfair_lock +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000 +// Only targeting new iOS, always use unfair locks +#define unfair_lock_lock os_unfair_lock_lock +#define unfair_lock_trylock os_unfair_lock_trylock +#define unfair_lock_unlock os_unfair_lock_unlock +#else +// Support both at runtime +#import +static inline void unfair_lock_lock(unfair_lock *lock) +{ + if (&os_unfair_lock_lock != NULL) { + os_unfair_lock_lock(lock); + } else { + OSSpinLockLock((volatile OSSpinLock *)lock); + } +} +static inline bool unfair_lock_trylock(unfair_lock *lock) +{ + if (&os_unfair_lock_trylock != NULL) { + return os_unfair_lock_trylock(lock); + } else { + return OSSpinLockTry((volatile OSSpinLock *)lock); + } +} +static inline void unfair_lock_unlock(unfair_lock *lock) +{ + if (&os_unfair_lock_unlock != NULL) { + os_unfair_lock_unlock(lock); + } else { + OSSpinLockUnlock((volatile OSSpinLock *)lock); + } +} +#endif +#else +// Old SDK, fallback to using regular old spinlocks +#import +#define unfair_lock volatile OSSpinLock +#define unfair_lock_lock OSSpinLockLock +#define unfair_lock_trylock OSSpinLockTry +#define unfair_lock_unlock OSSpinLockUnlock +#endif \ No newline at end of file From 7a993281b515cda93984f0b3c0f33ef093b3db39 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:42:32 -0500 Subject: [PATCH 29/65] Add header guard to rocketbootstrap.h --- rocketbootstrap.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rocketbootstrap.h b/rocketbootstrap.h index ca5b890..885401e 100644 --- a/rocketbootstrap.h +++ b/rocketbootstrap.h @@ -1,3 +1,6 @@ +#ifndef ROCKETBOOTSTRAP_H +#define ROCKETBOOTSTRAP_H + #include #include #include "bootstrap.h" @@ -25,3 +28,5 @@ void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCent #include "rocketbootstrap_dynamic.h" #endif __END_DECLS + +#endif From fea77d6211e42c9095eb545c4f589060f59674b1 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:46:53 -0500 Subject: [PATCH 30/65] Adjust header documentation --- rocketbootstrap.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/rocketbootstrap.h b/rocketbootstrap.h index 885401e..8fb3055 100644 --- a/rocketbootstrap.h +++ b/rocketbootstrap.h @@ -8,18 +8,33 @@ __BEGIN_DECLS #ifndef ROCKETBOOTSTRAP_LOAD_DYNAMIC -kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp); +// Look up a port by service name +kern_return_t rocketbootstrap_look_up(mach_port_t bootstrap_port, const name_t service_name, mach_port_t *out_service_port); +// 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_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_unlock(const name_t service_name); // Errors if not in a privileged process such as SpringBoard or backboardd -kern_return_t rocketbootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp); // Errors if not in a privileged process such as SpringBoard or backboardd + +// CFMessagePort helpers #ifdef __COREFOUNDATION_CFMESSAGEPORT__ +// Acquire access to a system-wide CFMessagePort service CFMessagePortRef rocketbootstrap_cfmessageportcreateremote(CFAllocatorRef allocator, CFStringRef name); +// Expose access to a CFMessagePort service +// Note: Will return an error if called from within a sandboxed process kern_return_t rocketbootstrap_cfmessageportexposelocal(CFMessagePortRef messagePort); #endif + +// CPDistributedMessagingCenter helpers + #ifdef __OBJC__ +// Unlock access to a system-wide CPDistributedMessagingCenter service +// Note: Server processes may only run inside privileged processes @class CPDistributedMessagingCenter; void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCenter *messaging_center); #endif From 9b031613525b7a35366db33c35b7419cf6485d9a Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:47:24 -0500 Subject: [PATCH 31/65] Add XPC support (tested on iOS 9+) --- Shims.x | 107 +++++++++++++++++++++++++++++++++++++- rocketbootstrap.h | 14 +++++ rocketbootstrap_dynamic.h | 30 +++++++++++ 3 files changed, 149 insertions(+), 2 deletions(-) diff --git a/Shims.x b/Shims.x index be6547d..ad33015 100644 --- a/Shims.x +++ b/Shims.x @@ -117,11 +117,114 @@ void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCent { if (rocketbootstrap_is_passthrough()) return; - OSSpinLockLock(&spin_lock); + unfair_lock_lock(&shim_lock); if (!has_hooked_messaging_center) { has_hooked_messaging_center = true; %init(messaging_center); } - OSSpinLockUnlock(&spin_lock); + unfair_lock_unlock(&shim_lock); objc_setAssociatedObject(messaging_center, &has_hooked_messaging_center, (id)kCFBooleanTrue, OBJC_ASSOCIATION_ASSIGN); } + +#ifdef __clang__ + +#include + +static xpc_endpoint_t _xpc_endpoint_create(mach_port_t port) +{ + static xpc_endpoint_t(*__xpc_endpoint_create)(mach_port_t); + if (!__xpc_endpoint_create) { + MSImageRef libxpc = MSGetImageByName("/usr/lib/system/libxpc.dylib"); + if (!libxpc) { + return NULL; + } + __xpc_endpoint_create = MSFindSymbol(libxpc, "__xpc_endpoint_create"); + if (!__xpc_endpoint_create) { + return NULL; + } + } + return __xpc_endpoint_create(port); +} + +static mach_port_t _xpc_connection_copy_listener_port(xpc_connection_t connection) +{ + static mach_port_t(*__xpc_connection_copy_listener_port)(xpc_connection_t); + if (!__xpc_connection_copy_listener_port) { + MSImageRef libxpc = MSGetImageByName("/usr/lib/system/libxpc.dylib"); + if (!libxpc) { + return MACH_PORT_NULL; + } + __xpc_connection_copy_listener_port = MSFindSymbol(libxpc, "__xpc_connection_copy_listener_port"); + if (!__xpc_connection_copy_listener_port) { + return MACH_PORT_NULL; + } + } + return __xpc_connection_copy_listener_port(connection); +} + +xpc_object_t xpc_connection_copy_entitlement_value(xpc_connection_t, const char* entitlement); + +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatch_queue_t targetq, uint64_t flags) +{ + mach_port_t bootstrap = MACH_PORT_NULL; + if (task_get_bootstrap_port(mach_task_self(), &bootstrap) != 0) { + return NULL; + } + if (flags & XPC_CONNECTION_MACH_SERVICE_LISTENER) { + if (rocketbootstrap_unlock(name) != 0) { + return NULL; + } + xpc_connection_t result = xpc_connection_create(NULL, targetq); + mach_port_t port = _xpc_connection_copy_listener_port(result); + if (bootstrap_register(bootstrap, (char *)name, port) != 0) { + xpc_release(result); + return NULL; + } + return result; + } + mach_port_t send_port = MACH_PORT_NULL; + if (rocketbootstrap_look_up(bootstrap, name, &send_port) != 0) { + return NULL; + } + xpc_endpoint_t endpoint = _xpc_endpoint_create(send_port); + xpc_connection_t result = xpc_connection_create_from_endpoint(endpoint); + xpc_release(endpoint); + if (targetq != NULL) { + xpc_connection_set_target_queue(result, targetq); + } + return result; +} + +xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(xpc_connection_t connection) +{ + xpc_object_t application_id = xpc_connection_copy_entitlement_value(connection, "application-identifier"); + if (!application_id) { + return NULL; + } + if (xpc_get_type(application_id) != XPC_TYPE_STRING) { + xpc_release(application_id); + return NULL; + } + xpc_object_t team_id = xpc_connection_copy_entitlement_value(connection, "com.apple.developer.team-identifier"); + if (!team_id) { + return application_id; + } + if (xpc_get_type(team_id) != XPC_TYPE_STRING) { + xpc_release(team_id); + return application_id; + } + const char *application_id_str = xpc_string_get_string_ptr(application_id); + const char *team_id_str = xpc_string_get_string_ptr(team_id); + size_t team_id_length = xpc_string_get_length(team_id); + if (memcmp(application_id_str, team_id_str, team_id_length) != 0 || application_id_str[team_id_length] != '.') { + xpc_release(team_id); + return application_id; + } + xpc_object_t trimmed_id = xpc_string_create(application_id_str + team_id_length + 1); + xpc_release(team_id); + xpc_release(application_id); + return trimmed_id; +} + +#endif diff --git a/rocketbootstrap.h b/rocketbootstrap.h index 8fb3055..cb7ee03 100644 --- a/rocketbootstrap.h +++ b/rocketbootstrap.h @@ -39,6 +39,20 @@ kern_return_t rocketbootstrap_cfmessageportexposelocal(CFMessagePortRef messageP void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCenter *messaging_center); #endif + +// XPC helpers + +#ifdef __XPC_CONNECTION_H__ +// Create an XPC connection representing a system-wide service +// flags should be XPC_CONNECTION_MACH_SERVICE_LISTENER for a listener connection, and 0 for a client client connection +// XPC_CONNECTION_MACH_SERVICE_LISTENER will return an error if called from within a sandboxed process +// 0 will return an error if the service name hasn't been registered +xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatch_queue_t targetq, uint64_t flags); +// Copy the application bundle identifier of the peer connection +xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(xpc_connection_t connection); +#endif + + #else #include "rocketbootstrap_dynamic.h" #endif diff --git a/rocketbootstrap_dynamic.h b/rocketbootstrap_dynamic.h index 45585d1..0c4c07a 100644 --- a/rocketbootstrap_dynamic.h +++ b/rocketbootstrap_dynamic.h @@ -91,3 +91,33 @@ static void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessag impl(messaging_center); } #endif + +#ifdef __XPC_CONNECTION_H__ +__attribute__((unused)) +xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatch_queue_t targetq, uint64_t flags) +{ + static xpc_connection_t (*impl)(const char *name, dispatch_queue_t targetq, uint64_t flags); + if (!impl) { + void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); + if (handle) + impl = dlsym(handle, "rocketbootstrap_xpc_connection_create"); + if (!impl) + return NULL; + } + return impl(name, targetq, flags); +} + +__attribute__((unused)) +xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(xpc_connection_t connection) +{ + static xpc_object_t (*impl)(xpc_connection_t connection); + if (!impl) { + void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); + if (handle) + impl = dlsym(handle, "rocketbootstrap_xpc_connection_copy_application_identifier"); + if (!impl) + return NULL; + } + return impl(connection); +} +#endif From f2f1ca912cabc57c4c65b5cacd939fb9dccfe1a4 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:48:28 -0500 Subject: [PATCH 32/65] Add symlinks to system headers for XPC --- launch.h | 1 + xpc | 1 + 2 files changed, 2 insertions(+) create mode 120000 launch.h create mode 120000 xpc diff --git a/launch.h b/launch.h new file mode 120000 index 0000000..678b734 --- /dev/null +++ b/launch.h @@ -0,0 +1 @@ +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/launch.h \ No newline at end of file diff --git a/xpc b/xpc new file mode 120000 index 0000000..097dec4 --- /dev/null +++ b/xpc @@ -0,0 +1 @@ +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/xpc/ \ No newline at end of file From 9db9e34e6c008297a003e8ac9f6495311c2ebf79 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 02:56:34 -0500 Subject: [PATCH 33/65] Public Release 1.0.5 Release Candidate 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 60e49b8..6135c80 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.5~beta1 +Version: 1.0.5~rc1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ From 28e7d1d2113239046d52cb789dffc0ad86e7105d Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 18:59:38 -0500 Subject: [PATCH 34/65] Remove beta depiction --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 6135c80..3583386 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.5~rc1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: http://rpetri.ch/cydia/rocketbootstrap/beta/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/beta/ +Depiction: http://rpetri.ch/cydia/rocketbootstrap/ +Homepage: http://rpetri.ch/cydia/rocketbootstrap/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From bcecaec9998c4cdfd51f57ec89189ca607217988 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 5 Feb 2017 18:59:47 -0500 Subject: [PATCH 35/65] Public Release 1.0.5 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 3583386..e0c60a8 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.5~rc1 +Version: 1.0.5 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: http://rpetri.ch/cydia/rocketbootstrap/ From d861f95b11fe8cada3bc34e64077abdd0a686f16 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Feb 2018 15:48:05 -0500 Subject: [PATCH 36/65] Changes necessary to support Electra jailbreak for iOS 11 and builds on Xcode 9 --- LightMessaging | 2 +- Makefile | 5 +++++ Tweak.x | 19 +++++++++++++++---- entitlements.xml | 9 +++++++++ layout/DEBIAN/postinst | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 entitlements.xml diff --git a/LightMessaging b/LightMessaging index 496257b..fb5cc4c 160000 --- a/LightMessaging +++ b/LightMessaging @@ -1 +1 @@ -Subproject commit 496257b11c3e906333797639355db9a43015eb50 +Subproject commit fb5cc4c1c32cff35956274f3d07943837b7424d9 diff --git a/Makefile b/Makefile index e9b7094..7c0dbfc 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,20 @@ LIBRARY_NAME = librocketbootstrap librocketbootstrap_FILES = Tweak.x Shims.x librocketbootstrap_LIBRARIES = substrate librocketbootstrap_FRAMEWORKS = Foundation +librocketbootstrap_USE_MODULES = 0 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 _rocketd_reenable_FILES = rocketd_reenable.c _rocketd_reenable_INSTALL_PATH = /usr/libexec +_rocketd_reenable_USE_MODULES = 0 +_rocketd_reenable_CODESIGN_FLAGS = -Sentitlements.xml ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders diff --git a/Tweak.x b/Tweak.x index b3bb08a..7e8c393 100644 --- a/Tweak.x +++ b/Tweak.x @@ -1,3 +1,7 @@ +#include +#undef __IOS_PROHIBITED +#define __IOS_PROHIBITED + #define LIGHTMESSAGING_USE_ROCKETBOOTSTRAP 0 #define LIGHTMESSAGING_TIMEOUT 300 #import "LightMessaging/LightMessaging.h" @@ -403,7 +407,14 @@ static void observe_rocketd(void) mach_port_t servicesPort = MACH_PORT_NULL; kern_return_t err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); if (err) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wavailability" +#endif system("/usr/libexec/_rocketd_reenable"); +#if __clang__ +#pragma clang diagnostic pop +#endif err = bootstrap_look_up(bootstrap, "com.rpetrich.rocketbootstrapd", &servicesPort); } if (err) { @@ -474,16 +485,16 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati %init(); // Attach rockets when in the com.apple.ReportCrash.SimulateCrash 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) { + 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) { + } else if (strcmp(_argv[1], "com.apple.ReportCrash.SimulateCrash") == 0) { isDaemon = YES; #ifdef DEBUG NSLog(@"RocketBootstrap: Initializing ReportCrash using XPC"); diff --git a/entitlements.xml b/entitlements.xml new file mode 100644 index 0000000..1acd00b --- /dev/null +++ b/entitlements.xml @@ -0,0 +1,9 @@ + + + + platform-application + + com.apple.private.skip-library-validation + + + diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst index f9fa636..06d01b5 100755 --- a/layout/DEBIAN/postinst +++ b/layout/DEBIAN/postinst @@ -1,4 +1,5 @@ #!/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 From a8452421528ddbcaa658449e507e9e2eb751866f Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Feb 2018 15:48:35 -0500 Subject: [PATCH 37/65] Make dynamic versions of rocketbootstrap_xpc_connection_create and rocketbootstrap_xpc_connection_copy_application_identifier static --- rocketbootstrap_dynamic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rocketbootstrap_dynamic.h b/rocketbootstrap_dynamic.h index 0c4c07a..7a65403 100644 --- a/rocketbootstrap_dynamic.h +++ b/rocketbootstrap_dynamic.h @@ -94,7 +94,7 @@ static void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessag #ifdef __XPC_CONNECTION_H__ __attribute__((unused)) -xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatch_queue_t targetq, uint64_t flags) +static xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatch_queue_t targetq, uint64_t flags) { static xpc_connection_t (*impl)(const char *name, dispatch_queue_t targetq, uint64_t flags); if (!impl) { @@ -108,7 +108,7 @@ xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatc } __attribute__((unused)) -xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(xpc_connection_t connection) +static xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(xpc_connection_t connection) { static xpc_object_t (*impl)(xpc_connection_t connection); if (!impl) { From e690c193376aaabc3ac8906bd926c01b12484d1b Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Feb 2018 15:49:31 -0500 Subject: [PATCH 38/65] Use https depiction --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index e0c60a8..93d1af8 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.5 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: http://rpetri.ch/cydia/rocketbootstrap/ -Homepage: http://rpetri.ch/cydia/rocketbootstrap/ +Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ +Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From e52bd4b7075b160a6a143235159adaed8e9899e5 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 17 Feb 2018 15:49:46 -0500 Subject: [PATCH 39/65] Public Release 1.0.6 alpha 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 93d1af8..9fba86d 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.5 +Version: 1.0.6~alpha1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 5e365deb6958bb115642f7b5134e5accf4efe102 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Fri, 23 Feb 2018 13:56:12 -0500 Subject: [PATCH 40/65] Add support for Electra inside _rocketd_reenable --- layout/DEBIAN/postinst | 2 +- libjailbreak_xpc.h | 36 ++++++++++++++++++++++++++++++++++++ rocketd_reenable.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 libjailbreak_xpc.h diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst index 06d01b5..3b51ee5 100755 --- a/layout/DEBIAN/postinst +++ b/layout/DEBIAN/postinst @@ -4,5 +4,5 @@ launchctl load /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist || tru 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 -chmod +s /usr/libexec/_rocketd_reenable chown root:wheel /usr/libexec/_rocketd_reenable +chmod +s /usr/libexec/_rocketd_reenable diff --git a/libjailbreak_xpc.h b/libjailbreak_xpc.h new file mode 100644 index 0000000..9c9618e --- /dev/null +++ b/libjailbreak_xpc.h @@ -0,0 +1,36 @@ +#include +#include + +/* Flags for entp command. Any combination or none can be specified. */ +/* Wait for xpcproxy to exec before continuing */ +#define FLAG_WAIT_EXEC (1 << 5) +/* Wait for 0.5 sec after acting */ +#define FLAG_DELAY (1 << 4) +/* Send SIGCONT after acting */ +#define FLAG_SIGCONT (1 << 3) +/* Set sandbox exception */ +#define FLAG_SANDBOX (1 << 2) +/* Set platform binary flag */ +#define FLAG_PLATFORMIZE (1 << 1) +/* Set basic entitlements */ +#define FLAG_ENTITLE (1) + +typedef void *jb_connection_t; + +#if __BLOCKS__ +typedef void (^jb_callback_t)(int result); + +/* These ones run asynchronously. Callbacks take 1 on success, 0 on failure. + The queue which they run on is undefined. */ +extern void jb_entitle(jb_connection_t connection, pid_t pid, uint32_t what, jb_callback_t done); +extern void jb_fix_setuid(jb_connection_t connection, pid_t pid, jb_callback_t done); +#endif + +extern jb_connection_t jb_connect(void); +extern void jb_disconnect(jb_connection_t connection); + +extern int jb_entitle_now(jb_connection_t connection, pid_t pid, uint32_t what); +extern int jb_fix_setuid_now(jb_connection_t connection, pid_t pid); + +extern void jb_oneshot_entitle_now(pid_t pid, uint32_t what); +extern void jb_oneshot_fix_setuid_now(pid_t pid); diff --git a/rocketd_reenable.c b/rocketd_reenable.c index c2cfab1..a897a24 100644 --- a/rocketd_reenable.c +++ b/rocketd_reenable.c @@ -1,10 +1,41 @@ #import +#import +#import + +#ifdef __arm64__ +#import "libjailbreak_xpc.h" +static int fix_setuid(void) +{ + void *libjailbreak = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); + if (libjailbreak) { + jb_connection_t (*jb_connect)(void) = dlsym(libjailbreak, "jb_connect"); + int (*jb_fix_setuid_now)(jb_connection_t connection, pid_t pid) = dlsym(libjailbreak, "jb_fix_setuid_now"); + void (*jb_disconnect)(jb_connection_t connection) = dlsym(libjailbreak, "jb_disconnect"); + if (jb_connect && jb_fix_setuid_now && jb_disconnect) { + jb_connection_t connection = jb_connect(); + if (connection) { + int result = jb_fix_setuid_now(connection, getpid()); + jb_disconnect(connection); + return result; + } + } + } + return 1; +} +#else +static int fix_setuid(void) +{ + // Does not apply to older iOS versions + return 1; +} +#endif int main(int argc, char *argv[]) { close(0); close(1); close(2); + fix_setuid(); setuid(0); setgid(0); seteuid(0); From 89be0589429baece5aa8478a109be7acb37471e3 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Fri, 23 Feb 2018 14:02:39 -0500 Subject: [PATCH 41/65] Public Release 1.0.6 alpha 2 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 9fba86d..d30a75c 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.6~alpha1 +Version: 1.0.6~alpha2 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 7e9d6f1602d3d24bef30cb22763fbf6ac6792807 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 24 Feb 2018 11:01:56 -0500 Subject: [PATCH 42/65] Fix double-draining the autorelease pool --- Tweak.x | 1 - 1 file changed, 1 deletion(-) diff --git a/Tweak.x b/Tweak.x index 7e8c393..a13b56a 100644 --- a/Tweak.x +++ b/Tweak.x @@ -181,7 +181,6 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) // Ask rocketd to unlock it for us int sandbox_result = sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_LOCAL_NAME | SANDBOX_CHECK_NO_REPORT, kRocketBootstrapUnlockService); if (sandbox_result) { - [pool drain]; return sandbox_result; } return LMConnectionSendOneWay(&connection, 0, service_name, strlen(service_name)); From 4d02f6643558ede804b36026661ecea8b99f717b Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 24 Feb 2018 11:16:44 -0500 Subject: [PATCH 43/65] Public Release 1.0.6 beta 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index d30a75c..95735c6 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.6~alpha2 +Version: 1.0.6~beta1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 3793b264844116b83f1b86cd5ba7d2a1ba9cea17 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Wed, 7 Mar 2018 14:32:28 -0500 Subject: [PATCH 44/65] Public Release 1.0.6 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 95735c6..038dbd6 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.6~beta1 +Version: 1.0.6 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 5f65a9fea0c334d32c91420f413b805d99d089f3 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 3 Mar 2019 18:10:21 -0500 Subject: [PATCH 45/65] Fix build problems on latest Xcode toolchain on Mojave --- Makefile | 3 +++ Shims.x | 5 +++++ Tweak.x | 8 +++++++- log.h | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7c0dbfc..313f0c0 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders # Support targeting 3.0 in packaged builds, but allow testing packages/builds to be missing support for old iOS versions LEGACY_XCODE_PATH ?= /Applications/Xcode_Legacy.app +CLASSIC_XCODE_PATH ?= /Volumes/Xcode/Xcode.app ifeq ($(wildcard $(LEGACY_XCODE_PATH)/.*),) IPHONE_ARCHS = armv7 armv7s arm64 @@ -38,6 +39,8 @@ TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_arm64 = 7.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 THEOS_PLATFORM_SDK_ROOT_armv6 = $(LEGACY_XCODE_PATH)/Contents/Developer +THEOS_PLATFORM_SDK_ROOT_armv7 = $(CLASSIC_XCODE_PATH)/Contents/Developer +THEOS_PLATFORM_SDK_ROOT_armv7s = $(CLASSIC_XCODE_PATH)/Contents/Developer endif include framework/makefiles/common.mk diff --git a/Shims.x b/Shims.x index ad33015..e868408 100644 --- a/Shims.x +++ b/Shims.x @@ -128,6 +128,11 @@ void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCent #ifdef __clang__ +#ifndef __IPHONE_9_0 +#define __IPHONE_9_0 90000 +#define __AVAILABILITY_INTERNAL__IPHONE_9_0 +#endif + #include static xpc_endpoint_t _xpc_endpoint_create(mach_port_t port) diff --git a/Tweak.x b/Tweak.x index a13b56a..cee17cf 100644 --- a/Tweak.x +++ b/Tweak.x @@ -2,6 +2,8 @@ #undef __IOS_PROHIBITED #define __IOS_PROHIBITED +#include + #define LIGHTMESSAGING_USE_ROCKETBOOTSTRAP 0 #define LIGHTMESSAGING_TIMEOUT 300 #import "LightMessaging/LightMessaging.h" @@ -410,7 +412,11 @@ static void observe_rocketd(void) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wavailability" #endif - system("/usr/libexec/_rocketd_reenable"); + pid_t pid; + char *const argv[] = { "/usr/libexec/_rocketd_reenable", NULL }; + if (posix_spawn(&pid, "/usr/libexec/_rocketd_reenable", NULL, NULL, argv, NULL) == 0) { + waitpid(pid, NULL, 0); + } #if __clang__ #pragma clang diagnostic pop #endif diff --git a/log.h b/log.h index 416ea06..d6d87a4 100644 --- a/log.h +++ b/log.h @@ -2,6 +2,7 @@ // Tiny shim to convert NSLog to public os_log statements on iOS 10 #ifdef __clang__ +#if __has_include() #include #define NSLog(...) do { \ if (kCFCoreFoundationVersionNumber > 1299.0) { \ @@ -13,3 +14,4 @@ } \ } while(0) #endif +#endif From 8f0ee0ed749ff11e52b15c4db5528d5c69403eb6 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 3 Mar 2019 18:12:13 -0500 Subject: [PATCH 46/65] Redirect service names to have cy:rbs: prefix on iOS 12 and later, which is whitelisted for reads by substrate running in launched --- Shims.x | 7 ++-- Tweak.x | 69 ++++++++++++++++++++++++++++++++++++++ rocketbootstrap_internal.h | 6 ++++ rocketd.c | 3 ++ 4 files changed, 80 insertions(+), 5 deletions(-) diff --git a/Shims.x b/Shims.x index e868408..f153859 100644 --- a/Shims.x +++ b/Shims.x @@ -100,13 +100,13 @@ static bool has_hooked_messaging_center; - (void)runServerOnCurrentThreadProtectedByEntitlement:(id)entitlement { + %orig(); if (objc_getAssociatedObject(self, &has_hooked_messaging_center)) { NSString **_centerName = CHIvarRef(self, _centerName, NSString *); if (_centerName && *_centerName) { rocketbootstrap_unlock([*_centerName UTF8String]); } } - %orig(); } %end @@ -177,12 +177,9 @@ xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, dispatc return NULL; } if (flags & XPC_CONNECTION_MACH_SERVICE_LISTENER) { - if (rocketbootstrap_unlock(name) != 0) { - return NULL; - } xpc_connection_t result = xpc_connection_create(NULL, targetq); mach_port_t port = _xpc_connection_copy_listener_port(result); - if (bootstrap_register(bootstrap, (char *)name, port) != 0) { + if (rocketbootstrap_register(bootstrap, (char *)name, port) != 0) { xpc_release(result); return NULL; } diff --git a/Tweak.x b/Tweak.x index cee17cf..4b456d0 100644 --- a/Tweak.x +++ b/Tweak.x @@ -40,11 +40,28 @@ extern const char ***_NSGetArgv(void); static BOOL isDaemon; +static BOOL fill_redirected_name(char new_name[BOOTSTRAP_MAX_NAME_LEN], const name_t old_name) { + size_t length = strlen(old_name); + if (length > 128 - 8) { + return NO; + } + memcpy(new_name, "cy:rbs:", 7); + memcpy(new_name + 7, old_name, length + 1); + return YES; +} + static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const name_t service_name, mach_port_t *sp, mach_msg_timeout_t timeout) { #ifdef DEBUG NSLog(@"RocketBootstrap: rocketbootstrap_look_up(%llu, %s, %p)", (unsigned long long)bp, service_name, sp); #endif + if (rocketbootstrap_uses_name_redirection()) { + char redirected_name[BOOTSTRAP_MAX_NAME_LEN]; + if (!fill_redirected_name(redirected_name, service_name)) { + return 1; + } + return bootstrap_look_up(bp, redirected_name, sp); + } if (rocketbootstrap_is_passthrough() || isDaemon) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_5_0) { int sandbox_result = sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_LOCAL_NAME | SANDBOX_CHECK_NO_REPORT, service_name); @@ -160,6 +177,48 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) #endif if (rocketbootstrap_is_passthrough()) return 0; + if (rocketbootstrap_uses_name_redirection()) { + char redirected_name[BOOTSTRAP_MAX_NAME_LEN]; + if (!fill_redirected_name(redirected_name, service_name)) { + return 1; + } + 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); + 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); + if (sandbox_result) { + return sandbox_result; + } + char *copied_service_name = strdup(service_name); + CFRunLoopRef runLoop = CFRunLoopGetCurrent(); + CFRunLoopPerformBlock(runLoop, kCFRunLoopCommonModes, ^{ + 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); + 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); + } + } + free(copied_service_name); + }); + CFRunLoopWakeUp(runLoop); + return 0; + } + err = bootstrap_register(bootstrap, redirected_name, service); + if (err != 0) { + mach_port_deallocate(mach_task_self(), service); + return err; + } + return 0; + } NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *serviceNameString = [NSString stringWithUTF8String:service_name]; unfair_lock_lock(&namesLock); @@ -191,6 +250,13 @@ 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) { + if (rocketbootstrap_uses_name_redirection()) { + char redirected_name[BOOTSTRAP_MAX_NAME_LEN]; + if (!fill_redirected_name(redirected_name, service_name)) { + return 1; + } + return bootstrap_register(bp, redirected_name, sp); + } kern_return_t err = rocketbootstrap_unlock(service_name); if (err) return err; @@ -488,6 +554,9 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati %ctor { %init(); + if (rocketbootstrap_uses_name_redirection()) { + return; + } // Attach rockets when in the com.apple.ReportCrash.SimulateCrash job // (can't check in using the launchd APIs because it hates more than one checkin; this will do) const char **_argv = *_NSGetArgv(); diff --git a/rocketbootstrap_internal.h b/rocketbootstrap_internal.h index 6244b2b..565d1d7 100644 --- a/rocketbootstrap_internal.h +++ b/rocketbootstrap_internal.h @@ -33,4 +33,10 @@ static inline bool rocketbootstrap_is_passthrough(void) return kCFCoreFoundationVersionNumber < 800.0; } +__attribute__((unused)) +static inline bool rocketbootstrap_uses_name_redirection(void) +{ + return kCFCoreFoundationVersionNumber >= 1556.00; +} + kern_return_t _rocketbootstrap_is_unlocked(const name_t service_name); // Errors if not in a privileged process such as SpringBoard or backboardd diff --git a/rocketd.c b/rocketd.c index 067fab6..2ddc558 100644 --- a/rocketd.c +++ b/rocketd.c @@ -59,6 +59,9 @@ static void machPortCallback(CFMachPortRef port, void *bytes, CFIndex size, void int main(int argc, char *argv[]) { + if (rocketbootstrap_uses_name_redirection() || rocketbootstrap_is_passthrough()) { + return 0; + } allowedNames = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); LMCheckInService(connection.serverName, CFRunLoopGetCurrent(), machPortCallback, NULL); notify_post("com.rpetrich.rocketd.started"); From 968133f06c19b18bba0dc14143032a8ab5256a1f Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 3 Mar 2019 18:20:00 -0500 Subject: [PATCH 47/65] Internal Release 1.0.7 alpha 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 038dbd6..296e1af 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.6 +Version: 1.0.7~alpha1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 4f7912df3b3c4e9fa5be52a62d1c492c3f077d1e Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 3 Mar 2019 19:25:56 -0500 Subject: [PATCH 48/65] Fix inverted conditional in fallback path for "unlock then register" behaviour of many services --- Tweak.x | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweak.x b/Tweak.x index 4b456d0..9628d77 100644 --- a/Tweak.x +++ b/Tweak.x @@ -199,7 +199,7 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) task_get_bootstrap_port(mach_task_self(), &bootstrap); mach_port_t service; kern_return_t err = bootstrap_look_up(bootstrap, copied_service_name, &service); - if (err != 0) { + 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); From a88c3cfababb86f9b8d86df403dde206ae720e9d Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 3 Mar 2019 20:36:46 -0500 Subject: [PATCH 49/65] Public Release 1.0.7 beta 1 --- layout/DEBIAN/control | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 296e1af..b736a67 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,11 +1,11 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.7~alpha1 +Version: 1.0.7~beta1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ -Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/ +Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ +Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 888252fb430e059b6603b8851aa642c10ce20e83 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 16 Mar 2019 18:45:51 -0400 Subject: [PATCH 50/65] Fix build problems with Xcode 10 causing resulting binaries to be incompatible with iOS 8.x and earlier --- Makefile | 26 +++++++++++++++++--------- launch.h => defaultheaders/launch.h | 0 xpc => defaultheaders/xpc | 0 fullheaders/launch.h | 1 + fullheaders/xpc | 1 + 5 files changed, 19 insertions(+), 9 deletions(-) rename launch.h => defaultheaders/launch.h (100%) rename xpc => defaultheaders/xpc (100%) create mode 120000 fullheaders/launch.h create mode 120000 fullheaders/xpc diff --git a/Makefile b/Makefile index 313f0c0..6c349fb 100644 --- a/Makefile +++ b/Makefile @@ -20,27 +20,35 @@ _rocketd_reenable_CODESIGN_FLAGS = -Sentitlements.xml ADDITIONAL_CFLAGS = -std=c99 -Ioverlayheaders # Support targeting 3.0 in packaged builds, but allow testing packages/builds to be missing support for old iOS versions -LEGACY_XCODE_PATH ?= /Applications/Xcode_Legacy.app -CLASSIC_XCODE_PATH ?= /Volumes/Xcode/Xcode.app +XCODE4_PATH ?= /Applications/Xcode_Legacy.app +XCODE6_PATH ?= /Volumes/Xcode/Xcode.app +XCODE9_PATH ?= /Volumes/Xcode_9.4.1/Xcode.app -ifeq ($(wildcard $(LEGACY_XCODE_PATH)/.*),) +ifeq ($(wildcard $(XCODE4_PATH)/.*),) +ADDITIONAL_CFLAGS += -Idefaultheaders IPHONE_ARCHS = armv7 armv7s arm64 -TARGET_IPHONEOS_DEPLOYMENT_VERSION = 7.0 +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 rocketd_IPHONE_ARCHS = armv6 arm64 _rocketd_reenable_IPHONE_ARCHS = armv6 arm64 IPHONE_ARCHS = armv6 armv7 armv7s arm64 SDKVERSION_armv6 = 5.1 INCLUDE_SDKVERSION_armv6 = 8.4 -TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0 -TARGET_IPHONEOS_DEPLOYMENT_VERSION_arm64 = 7.0 TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0 -THEOS_PLATFORM_SDK_ROOT_armv6 = $(LEGACY_XCODE_PATH)/Contents/Developer -THEOS_PLATFORM_SDK_ROOT_armv7 = $(CLASSIC_XCODE_PATH)/Contents/Developer -THEOS_PLATFORM_SDK_ROOT_armv7s = $(CLASSIC_XCODE_PATH)/Contents/Developer +TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv7 = 4.0 +TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv7s = 6.0 +TARGET_IPHONEOS_DEPLOYMENT_VERSION = 7.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 = $(XCODE9_PATH)/Contents/Developer endif include framework/makefiles/common.mk diff --git a/launch.h b/defaultheaders/launch.h similarity index 100% rename from launch.h rename to defaultheaders/launch.h diff --git a/xpc b/defaultheaders/xpc similarity index 100% rename from xpc rename to defaultheaders/xpc diff --git a/fullheaders/launch.h b/fullheaders/launch.h new file mode 120000 index 0000000..845362d --- /dev/null +++ b/fullheaders/launch.h @@ -0,0 +1 @@ +/Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/launch.h \ No newline at end of file diff --git a/fullheaders/xpc b/fullheaders/xpc new file mode 120000 index 0000000..73e85a6 --- /dev/null +++ b/fullheaders/xpc @@ -0,0 +1 @@ +/Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/xpc/ \ No newline at end of file From 5705e63fb4218b3c63b37d34b33d1a5e34aef807 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 16 Mar 2019 21:27:15 -0400 Subject: [PATCH 51/65] Never use name redirection when substitute is available (by request of CoolStar) --- rocketbootstrap_internal.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rocketbootstrap_internal.h b/rocketbootstrap_internal.h index 565d1d7..4089209 100644 --- a/rocketbootstrap_internal.h +++ b/rocketbootstrap_internal.h @@ -1,4 +1,5 @@ #import +#import #import "rocketbootstrap.h" @@ -36,7 +37,15 @@ static inline bool rocketbootstrap_is_passthrough(void) __attribute__((unused)) static inline bool rocketbootstrap_uses_name_redirection(void) { - return kCFCoreFoundationVersionNumber >= 1556.00; + if (kCFCoreFoundationVersionNumber >= 1556.00) { + static int state; + int currentState = state; + if (currentState == 0) { + currentState = state = dlsym(RTLD_DEFAULT, "substitute_hook_functions") ? 1 : 2; + } + return currentState - 1; + } + return false; } kern_return_t _rocketbootstrap_is_unlocked(const name_t service_name); // Errors if not in a privileged process such as SpringBoard or backboardd From e484b365df25e0cd7efea8c0df6bd39427c5c0c1 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 16 Mar 2019 22:53:58 -0400 Subject: [PATCH 52/65] Public Release 1.0.7 beta 2 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index b736a67..31f67be 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.7~beta1 +Version: 1.0.7~beta2 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ From e93b1880a78d8f1bb9adc2cb113a1e8f45181574 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 30 Mar 2019 15:20:07 -0400 Subject: [PATCH 53/65] Add support for arm64e architecture --- Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 6c349fb..073de67 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ XCODE9_PATH ?= /Volumes/Xcode_9.4.1/Xcode.app ifeq ($(wildcard $(XCODE4_PATH)/.*),) ADDITIONAL_CFLAGS += -Idefaultheaders -IPHONE_ARCHS = armv7 armv7s arm64 +IPHONE_ARCHS = armv7 armv7s arm64 arm64e TARGET_IPHONEOS_DEPLOYMENT_VERSION = 8.4 ifeq ($(FINALPACKAGE),1) $(error Building final package requires a legacy Xcode install!) @@ -36,19 +36,22 @@ 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 +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 = 7.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 = $(XCODE9_PATH)/Contents/Developer +THEOS_PLATFORM_SDK_ROOT_arm64 = $(XCODE9_PATH)/Contents/Developer endif include framework/makefiles/common.mk From dbc9984bc20660151a0de60496a9f45a38a9054a Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 30 Mar 2019 15:31:01 -0400 Subject: [PATCH 54/65] Public Release 1.0.7 beta 3 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 31f67be..15af97e 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.7~beta2 +Version: 1.0.7~beta3 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ From 5d030a1517c532a8304af4a6d8f6eed542b3b6ce Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 12 May 2019 16:28:35 -0400 Subject: [PATCH 55/65] Support pointer authentication in clients when ROCKETBOOTSTRAP_LOAD_DYNAMIC is set in client libraries (requires recompile to take advantage on arm64e) --- rocketbootstrap_dynamic.h | 75 ++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/rocketbootstrap_dynamic.h b/rocketbootstrap_dynamic.h index 7a65403..e5fe5c9 100644 --- a/rocketbootstrap_dynamic.h +++ b/rocketbootstrap_dynamic.h @@ -2,16 +2,43 @@ // Set ROCKETBOOTSTRAP_LOAD_DYNAMIC and then include rocketbootstrap.h #include +#if __has_include() +#include + +__attribute__((unused)) +static void *_rocketbootstrap_dlsym_func(const char *name) { + void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); + if (handle) { + void *result = dlsym(handle, name); + if (result) { + return ptrauth_sign_unauthenticated(ptrauth_strip(result, ptrauth_key_function_pointer), ptrauth_key_function_pointer, 0); + } + } + return NULL; +} + +#else + +__attribute__((unused)) +static void *_rocketbootstrap_dlsym_func(const char *name) { + void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); + if (handle) { + return dlsym(handle, name); + } + return NULL; +} + +#endif + __attribute__((unused)) static kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp) { static kern_return_t (*impl)(mach_port_t bp, const name_t service_name, mach_port_t *sp); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_look_up"); - if (!impl) + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_look_up"); + if (!impl) { impl = bootstrap_look_up; + } } return impl(bp, service_name, sp); } @@ -21,11 +48,10 @@ static kern_return_t rocketbootstrap_unlock(const name_t service_name) { static kern_return_t (*impl)(const name_t service_name); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_unlock"); - if (!impl) + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_unlock"); + if (!impl) { return -1; + } } return impl(service_name); } @@ -36,11 +62,10 @@ static kern_return_t rocketbootstrap_register(mach_port_t bp, name_t service_nam { static kern_return_t (*impl)(mach_port_t bp, name_t service_name, mach_port_t sp); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_register"); - if (!impl) + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_register"); + if (!impl) { impl = bootstrap_register; + } } return impl(bp, service_name, sp); } @@ -52,11 +77,10 @@ static CFMessagePortRef rocketbootstrap_cfmessageportcreateremote(CFAllocatorRef { static CFMessagePortRef (*impl)(CFAllocatorRef allocator, CFStringRef name); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_cfmessageportcreateremote"); - if (!impl) + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_cfmessageportcreateremote"); + if (!impl) { impl = CFMessagePortCreateRemote; + } } return impl(allocator, name); } @@ -65,11 +89,10 @@ static kern_return_t rocketbootstrap_cfmessageportexposelocal(CFMessagePortRef m { static kern_return_t (*impl)(CFMessagePortRef messagePort); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_cfmessageportexposelocal"); - if (!impl) + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_cfmessageportexposelocal"); + if (!impl) { return -1; + } } return impl(messagePort); } @@ -82,9 +105,7 @@ static void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessag { static void (*impl)(CPDistributedMessagingCenter *messagingCenter); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_distributedmessagingcenter_apply"); + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_distributedmessagingcenter_apply"); if (!impl) return; } @@ -98,9 +119,7 @@ static xpc_connection_t rocketbootstrap_xpc_connection_create(const char *name, { static xpc_connection_t (*impl)(const char *name, dispatch_queue_t targetq, uint64_t flags); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_xpc_connection_create"); + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_xpc_connection_create"); if (!impl) return NULL; } @@ -112,9 +131,7 @@ static xpc_object_t rocketbootstrap_xpc_connection_copy_application_identifier(x { static xpc_object_t (*impl)(xpc_connection_t connection); if (!impl) { - void *handle = dlopen("/usr/lib/librocketbootstrap.dylib", RTLD_LAZY); - if (handle) - impl = dlsym(handle, "rocketbootstrap_xpc_connection_copy_application_identifier"); + impl = _rocketbootstrap_dlsym_func("rocketbootstrap_xpc_connection_copy_application_identifier"); if (!impl) return NULL; } From 12d4f5c89e09d65dd202df044fbece5c4f3083f6 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sun, 12 May 2019 16:35:48 -0400 Subject: [PATCH 56/65] Support pointer authentication when calling jb_connect/jb_fix_suid_now/jb_disconnect (which may be required, not sure?) --- rocketd_reenable.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/rocketd_reenable.c b/rocketd_reenable.c index a897a24..9204bde 100644 --- a/rocketd_reenable.c +++ b/rocketd_reenable.c @@ -2,15 +2,29 @@ #import #import +#ifdef __LP64__ +#if __has_include() +#include +#define sign_function(ptr) ({ \ + __typeof__(ptr) _ptr = ptr; \ + ptr ? ptrauth_sign_unauthenticated(_ptr, ptrauth_key_function_pointer, 0) : _ptr; \ +}) +#else +#define sign_function(ptr) ptr +#endif +#else +#define sign_function(ptr) ptr +#endif + #ifdef __arm64__ #import "libjailbreak_xpc.h" static int fix_setuid(void) { void *libjailbreak = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); if (libjailbreak) { - jb_connection_t (*jb_connect)(void) = dlsym(libjailbreak, "jb_connect"); - int (*jb_fix_setuid_now)(jb_connection_t connection, pid_t pid) = dlsym(libjailbreak, "jb_fix_setuid_now"); - void (*jb_disconnect)(jb_connection_t connection) = dlsym(libjailbreak, "jb_disconnect"); + jb_connection_t (*jb_connect)(void) = sign_function(dlsym(libjailbreak, "jb_connect")); + int (*jb_fix_setuid_now)(jb_connection_t connection, pid_t pid) = sign_function(dlsym(libjailbreak, "jb_fix_setuid_now")); + void (*jb_disconnect)(jb_connection_t connection) = sign_function(dlsym(libjailbreak, "jb_disconnect")); if (jb_connect && jb_fix_setuid_now && jb_disconnect) { jb_connection_t connection = jb_connect(); if (connection) { From 31f8d189ae1aa878d9de31019a228c6b20883085 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 9 Mar 2020 08:41:15 -0400 Subject: [PATCH 57/65] Use normal repository --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 15af97e..4c195e6 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.7~beta3 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ -Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ +Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ +Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 1c19b119d3e6571086bc0b3992aa747c4a5863de Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Mon, 9 Mar 2020 08:41:26 -0400 Subject: [PATCH 58/65] Public Release 1.0.7 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 4c195e6..c3315fb 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.7~beta3 +Version: 1.0.7 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ From 686dfc66ab0a43dd27d1d43057ed6f38d5782115 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 11 Apr 2020 20:56:33 -0400 Subject: [PATCH 59/65] Use rocketd always, and try redirection first before rocketd --- rocketbootstrap_internal.h | 3 ++- rocketd.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rocketbootstrap_internal.h b/rocketbootstrap_internal.h index 4089209..afb6ac3 100644 --- a/rocketbootstrap_internal.h +++ b/rocketbootstrap_internal.h @@ -41,7 +41,8 @@ static inline bool rocketbootstrap_uses_name_redirection(void) static int state; int currentState = state; if (currentState == 0) { - currentState = state = dlsym(RTLD_DEFAULT, "substitute_hook_functions") ? 1 : 2; + int check = sandbox_check(getpid(), "mach-lookup", SANDBOX_FILTER_LOCAL_NAME | SANDBOX_CHECK_NO_REPORT, "cy:rbs"); + currentState = check == 0 ? 1 : 2; } return currentState - 1; } diff --git a/rocketd.c b/rocketd.c index 2ddc558..01f73ac 100644 --- a/rocketd.c +++ b/rocketd.c @@ -59,7 +59,7 @@ static void machPortCallback(CFMachPortRef port, void *bytes, CFIndex size, void int main(int argc, char *argv[]) { - if (rocketbootstrap_uses_name_redirection() || rocketbootstrap_is_passthrough()) { + if (rocketbootstrap_is_passthrough()) { return 0; } allowedNames = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); From 0733a38e3b9ae835e63dc98e8df1cf9ac25797dc Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 11 Apr 2020 21:02:02 -0400 Subject: [PATCH 60/65] Perform both types of unlocking when name redirection is supported --- Tweak.x | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tweak.x b/Tweak.x index 9628d77..0fe737a 100644 --- a/Tweak.x +++ b/Tweak.x @@ -211,13 +211,13 @@ kern_return_t rocketbootstrap_unlock(const name_t service_name) }); CFRunLoopWakeUp(runLoop); return 0; + } else { + err = bootstrap_register(bootstrap, redirected_name, service); + if (err != 0) { + mach_port_deallocate(mach_task_self(), service); + return err; + } } - err = bootstrap_register(bootstrap, redirected_name, service); - if (err != 0) { - mach_port_deallocate(mach_task_self(), service); - return err; - } - return 0; } NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *serviceNameString = [NSString stringWithUTF8String:service_name]; From 994e624197747246e4b69fe1883568a2e6ba6878 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 11 Apr 2020 21:12:49 -0400 Subject: [PATCH 61/65] Fully enable rocketd fallback --- Tweak.x | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tweak.x b/Tweak.x index 0fe737a..db0f3e3 100644 --- a/Tweak.x +++ b/Tweak.x @@ -60,7 +60,10 @@ static kern_return_t rocketbootstrap_look_up_with_timeout(mach_port_t bp, const if (!fill_redirected_name(redirected_name, service_name)) { return 1; } - return bootstrap_look_up(bp, redirected_name, sp); + kern_return_t result = bootstrap_look_up(bp, redirected_name, sp); + if (result == 0) { + return 0; + } } if (rocketbootstrap_is_passthrough() || isDaemon) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_5_0) { @@ -554,9 +557,6 @@ static void SanityCheckNotificationCallback(CFUserNotificationRef userNotificati %ctor { %init(); - if (rocketbootstrap_uses_name_redirection()) { - return; - } // Attach rockets when in the com.apple.ReportCrash.SimulateCrash job // (can't check in using the launchd APIs because it hates more than one checkin; this will do) const char **_argv = *_NSGetArgv(); From 41615c0149ecbd52f861314c4bbee572ede66c35 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 11 Apr 2020 21:15:33 -0400 Subject: [PATCH 62/65] Switch to beta repo --- layout/DEBIAN/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index c3315fb..627b979 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -4,8 +4,8 @@ Name: RocketBootstrap Version: 1.0.7 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes -Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/ -Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/ +Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ +Homepage: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ Maintainer: BigBoss Author: Ryan Petrich Sponsor: thebigboss.org From 0d728a7fd2a9f0f455740eb11fd7aa69254430fa Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 11 Apr 2020 21:15:46 -0400 Subject: [PATCH 63/65] Public Release 1.0.8 beta 1 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 627b979..33f0e83 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.7 +Version: 1.0.8~beta1 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/ From 6ddc1b9c1608ce4d2573a16f3d9144be0dd27ea2 Mon Sep 17 00:00:00 2001 From: CoolStar Date: Fri, 24 Apr 2020 19:15:34 -0700 Subject: [PATCH 64/65] Fix boot hang on chimera1n --- Tweak.x | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tweak.x b/Tweak.x index db0f3e3..5fb5942 100644 --- a/Tweak.x +++ b/Tweak.x @@ -428,6 +428,10 @@ static pid_t pid_of_process(const char *process_name) struct kinfo_proc * newprocess = NULL; do { + if (size == 0){ + st = sysctl(mib, miblen, NULL, &size, NULL, 0); + } + size += size / 10; newprocess = (struct kinfo_proc *)realloc(process, size); From 75068f9e4791f81e89e00ef433c961d7aff5b4c7 Mon Sep 17 00:00:00 2001 From: Ryan Petrich Date: Sat, 25 Apr 2020 22:14:50 -0400 Subject: [PATCH 65/65] Public Release 1.0.9 --- layout/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index 33f0e83..2bce6bd 100644 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,7 +1,7 @@ Package: com.rpetrich.rocketbootstrap Depends: mobilesubstrate (>= 0.9.5000), firmware (>= 3.0) Name: RocketBootstrap -Version: 1.0.8~beta1 +Version: 1.0.9 Architecture: iphoneos-arm Description: Support library allowing tweaks to communicate with sandboxed processes Depiction: https://www.rpetrich.com/cydia/rocketbootstrap/beta/