From fc627a0269b276f4a36727c8254f6b5bd0ddddcd Mon Sep 17 00:00:00 2001 From: Sam Bingner Date: Thu, 5 Dec 2019 13:17:44 -1000 Subject: Update uikittools --- data/uikittools/1_uicache.diff | 1170 ---------------------------------------- 1 file changed, 1170 deletions(-) delete mode 100644 data/uikittools/1_uicache.diff (limited to 'data/uikittools/1_uicache.diff') diff --git a/data/uikittools/1_uicache.diff b/data/uikittools/1_uicache.diff deleted file mode 100644 index 8a01dd2e3..000000000 --- a/data/uikittools/1_uicache.diff +++ /dev/null @@ -1,1170 +0,0 @@ -diff -urN uikittools/sbreload.c uikittools+uicache/sbreload.c ---- uikittools/sbreload.c 2018-10-04 15:58:42.000000000 -1000 -+++ uikittools+uicache/sbreload.c 1969-12-31 14:00:00.000000000 -1000 -@@ -1,270 +0,0 @@ --/* UIKit Tools - command-line utilities for UIKit -- * Copyright (C) 2008-2012 Jay Freeman (saurik) --*/ -- --/* Modified BSD License {{{ */ --/* -- * Redistribution and use in source and binary -- * forms, with or without modification, are permitted -- * provided that the following conditions are met: -- * -- * 1. Redistributions of source code must retain the -- * above copyright notice, this list of conditions -- * and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the -- * above copyright notice, this list of conditions -- * and the following disclaimer in the documentation -- * and/or other materials provided with the -- * distribution. -- * 3. The name of the author may not be used to endorse -- * or promote products derived from this software -- * without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --*/ --/* }}} */ -- --#include --#include -- --#include --#include -- --#include -- --/* Set platform binary flag */ --#define FLAG_PLATFORMIZE (1 << 1) --#include -- --void platformizeme() { -- void* handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); -- if (!handle) return; -- -- // Reset errors -- dlerror(); -- typedef void (*fix_entitle_prt_t)(pid_t pid, uint32_t what); -- fix_entitle_prt_t ptr = (fix_entitle_prt_t)dlsym(handle, "jb_oneshot_entitle_now"); -- -- const char *dlsym_error = dlerror(); -- if (dlsym_error) { -- return; -- } -- -- ptr(getpid(), FLAG_PLATFORMIZE); --} -- --launch_data_t --CF2launch_data(CFTypeRef cfr); -- --void --myCFDictionaryApplyFunction(const void *key, const void *value, void *context) --{ -- launch_data_t ik, iw, where = context; -- -- ik = CF2launch_data(key); -- iw = CF2launch_data(value); -- -- launch_data_dict_insert(where, iw, launch_data_get_string(ik)); -- launch_data_free(ik); --} -- --launch_data_t --CF2launch_data(CFTypeRef cfr) --{ -- launch_data_t r; -- CFTypeID cft = CFGetTypeID(cfr); -- -- if (cft == CFStringGetTypeID()) { -- char buf[4096]; -- CFStringGetCString(cfr, buf, sizeof(buf), kCFStringEncodingUTF8); -- r = launch_data_alloc(LAUNCH_DATA_STRING); -- launch_data_set_string(r, buf); -- } else if (cft == CFBooleanGetTypeID()) { -- r = launch_data_alloc(LAUNCH_DATA_BOOL); -- launch_data_set_bool(r, CFBooleanGetValue(cfr)); -- } else if (cft == CFArrayGetTypeID()) { -- CFIndex i, ac = CFArrayGetCount(cfr); -- r = launch_data_alloc(LAUNCH_DATA_ARRAY); -- for (i = 0; i < ac; i++) { -- CFTypeRef v = CFArrayGetValueAtIndex(cfr, i); -- if (v) { -- launch_data_t iv = CF2launch_data(v); -- launch_data_array_set_index(r, iv, i); -- } -- } -- } else if (cft == CFDictionaryGetTypeID()) { -- r = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -- CFDictionaryApplyFunction(cfr, myCFDictionaryApplyFunction, r); -- } else if (cft == CFDataGetTypeID()) { -- r = launch_data_alloc(LAUNCH_DATA_ARRAY); -- launch_data_set_opaque(r, CFDataGetBytePtr(cfr), CFDataGetLength(cfr)); -- } else if (cft == CFNumberGetTypeID()) { -- long long n; -- double d; -- CFNumberType cfnt = CFNumberGetType(cfr); -- switch (cfnt) { -- case kCFNumberSInt8Type: -- case kCFNumberSInt16Type: -- case kCFNumberSInt32Type: -- case kCFNumberSInt64Type: -- case kCFNumberCharType: -- case kCFNumberShortType: -- case kCFNumberIntType: -- case kCFNumberLongType: -- case kCFNumberLongLongType: -- CFNumberGetValue(cfr, kCFNumberLongLongType, &n); -- r = launch_data_alloc(LAUNCH_DATA_INTEGER); -- launch_data_set_integer(r, n); -- break; -- case kCFNumberFloat32Type: -- case kCFNumberFloat64Type: -- case kCFNumberFloatType: -- case kCFNumberDoubleType: -- CFNumberGetValue(cfr, kCFNumberDoubleType, &d); -- r = launch_data_alloc(LAUNCH_DATA_REAL); -- launch_data_set_real(r, d); -- break; -- default: -- r = NULL; -- break; -- } -- } else { -- r = NULL; -- } -- return r; --} -- --CFPropertyListRef --CreateMyPropertyListFromFile(const char *posixfile) --{ -- CFPropertyListRef propertyList; -- CFStringRef errorString; -- CFDataRef resourceData; -- SInt32 errorCode; -- CFURLRef fileURL; -- -- fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false); -- if (!fileURL) { -- fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); -- } -- if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) { -- fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); -- } -- propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString); -- if (!propertyList) { -- fprintf(stderr, "%s: propertyList is NULL\n", getprogname()); -- } -- -- return propertyList; --} -- --#define _assert(test, format, args...) do { \ -- if (test) break; \ -- fprintf(stderr, format "\n", ##args); \ -- return 1; \ --} while (false) -- --void stop() { -- sleep(1); --} -- --#define SpringBoard_plist "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" -- --int main(int argc, const char *argv[]) { -- platformizeme(); -- _assert(argc == 1, "usage: sbreload"); -- -- CFDictionaryRef plist = CreateMyPropertyListFromFile(SpringBoard_plist); -- _assert(plist != NULL, "CreateMyPropertyListFromFile() == NULL"); -- -- launch_data_t job = CF2launch_data(plist); -- _assert(job != NULL, "CF2launch_data() == NULL"); -- -- launch_data_t data, request, response; -- -- data = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL); -- _assert(data != NULL, "launch_data_dict_lookup(LABEL) == NULL"); -- const char *label = launch_data_get_string(data); -- -- request = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -- launch_data_dict_insert(request, launch_data_new_string(label), LAUNCH_KEY_GETJOB); -- -- response = launch_msg(request); -- _assert(response != NULL, "launch_msg(GetJob) == NULL"); -- launch_data_free(request); -- -- pid_t pid; -- -- if (launch_data_get_type(response) == LAUNCH_DATA_ERRNO) { -- int error = launch_data_get_errno(response); -- _assert(error == ESRCH, "GetJob(%s): %s", label, strerror(error)); -- pid = -1; -- } else if (launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY) { -- data = launch_data_dict_lookup(response, LAUNCH_JOBKEY_PID); -- _assert(data != NULL, "launch_data_dict_lookup(PID) == NULL"); -- pid = launch_data_get_integer(data); -- } else _assert(false, "launch_data_get_type() not in (DICTIONARY, ERRNO)"); -- -- launch_data_free(response); -- -- // 600 is being used to approximate 4.x/5.x boundary -- if (kCFCoreFoundationVersionNumber < 600) { -- fprintf(stderr, "notify_post(com.apple.mobile.springboard_teardown)\n"); -- notify_post("com.apple.mobile.springboard_teardown"); -- } else { -- // XXX: this code is preferable to launchctl unoad but it requires libvproc? :( -- //vproc_err_t *error = _vproc_send_signal_by_label(label, VPROC_MAGIC_UNLOAD_SIGNAL); -- //_assert(error == NULL, "_vproc_send_signal_by_label(UNLOAD) != NULL"); -- -- fprintf(stderr, "launchctl unload SpringBoard.plist\n"); -- system("launchctl unload " SpringBoard_plist); -- } -- -- if (pid != -1) { -- fprintf(stderr, "waiting for kill(%u) != 0...\n", pid); -- while (kill(pid, 0) == 0) -- stop(); -- -- int error = errno; -- _assert(error == ESRCH, "kill(%u): %s", pid, strerror(error)); -- } -- -- request = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -- launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB); -- -- for (;;) { -- response = launch_msg(request); -- _assert(response != NULL, "launch_msg(SubmitJob) == NULL"); -- -- _assert(launch_data_get_type(response) == LAUNCH_DATA_ERRNO, "launch_data_get_type() != ERRNO"); -- int error = launch_data_get_errno(response); -- launch_data_free(response); -- -- const char *string = strerror(error); -- -- if (error == EEXIST) { -- fprintf(stderr, "SubmitJob(%s): %s, retrying...\n", label, string); -- stop(); -- } else { -- _assert(error == 0, "SubmitJob(%s): %s", label, string); -- break; -- } -- } -- -- launch_data_free(request); -- -- return 0; --} -diff -urN uikittools/sbreload.m uikittools+uicache/sbreload.m ---- uikittools/sbreload.m 1969-12-31 14:00:00.000000000 -1000 -+++ uikittools+uicache/sbreload.m 2019-06-07 22:37:29.000000000 -1000 -@@ -0,0 +1,336 @@ -+/* UIKit Tools - command-line utilities for UIKit -+ * Copyright (C) 2008-2012 Jay Freeman (saurik) -+*/ -+ -+/* Modified BSD License {{{ */ -+/* -+ * Redistribution and use in source and binary -+ * forms, with or without modification, are permitted -+ * provided that the following conditions are met: -+ * -+ * 1. Redistributions of source code must retain the -+ * above copyright notice, this list of conditions -+ * and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the -+ * above copyright notice, this list of conditions -+ * and the following disclaimer in the documentation -+ * and/or other materials provided with the -+ * distribution. -+ * 3. The name of the author may not be used to endorse -+ * or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+/* }}} */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include -+ -+/* Set platform binary flag */ -+#define FLAG_PLATFORMIZE (1 << 1) -+#include -+#include -+ -+@interface FBSSystemService -++(id)sharedService; -+-(void)sendActions:(NSSet*)actions withResult:(id)result; -+@end -+ -+typedef enum { -+ None = 0, -+ RestartRenderServer = (1 << 0), // also relaunch backboardd -+ SnapshotTransition = (1 << 1), -+ FadeToBlackTransition = (1 << 2), -+} SBSRelaunchActionStyle; -+ -+@interface SBSRelaunchAction -++(id)actionWithReason:(id)reason options:(int64_t)options targetURL:(NSURL*)url; -+@end -+ -+void platformizeme() { -+ void* handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); -+ if (!handle) return; -+ -+ // Reset errors -+ dlerror(); -+ typedef void (*fix_entitle_prt_t)(pid_t pid, uint32_t what); -+ fix_entitle_prt_t ptr = (fix_entitle_prt_t)dlsym(handle, "jb_oneshot_entitle_now"); -+ -+ const char *dlsym_error = dlerror(); -+ if (dlsym_error) { -+ return; -+ } -+ -+ ptr(getpid(), FLAG_PLATFORMIZE); -+} -+ -+launch_data_t -+CF2launch_data(CFTypeRef cfr); -+ -+void -+myCFDictionaryApplyFunction(const void *key, const void *value, void *context) -+{ -+ launch_data_t ik, iw, where = context; -+ -+ ik = CF2launch_data(key); -+ iw = CF2launch_data(value); -+ -+ launch_data_dict_insert(where, iw, launch_data_get_string(ik)); -+ launch_data_free(ik); -+} -+ -+launch_data_t -+CF2launch_data(CFTypeRef cfr) -+{ -+ launch_data_t r; -+ CFTypeID cft = CFGetTypeID(cfr); -+ -+ if (cft == CFStringGetTypeID()) { -+ char buf[4096]; -+ CFStringGetCString(cfr, buf, sizeof(buf), kCFStringEncodingUTF8); -+ r = launch_data_alloc(LAUNCH_DATA_STRING); -+ launch_data_set_string(r, buf); -+ } else if (cft == CFBooleanGetTypeID()) { -+ r = launch_data_alloc(LAUNCH_DATA_BOOL); -+ launch_data_set_bool(r, CFBooleanGetValue(cfr)); -+ } else if (cft == CFArrayGetTypeID()) { -+ CFIndex i, ac = CFArrayGetCount(cfr); -+ r = launch_data_alloc(LAUNCH_DATA_ARRAY); -+ for (i = 0; i < ac; i++) { -+ CFTypeRef v = CFArrayGetValueAtIndex(cfr, i); -+ if (v) { -+ launch_data_t iv = CF2launch_data(v); -+ launch_data_array_set_index(r, iv, i); -+ } -+ } -+ } else if (cft == CFDictionaryGetTypeID()) { -+ r = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -+ CFDictionaryApplyFunction(cfr, myCFDictionaryApplyFunction, r); -+ } else if (cft == CFDataGetTypeID()) { -+ r = launch_data_alloc(LAUNCH_DATA_ARRAY); -+ launch_data_set_opaque(r, CFDataGetBytePtr(cfr), CFDataGetLength(cfr)); -+ } else if (cft == CFNumberGetTypeID()) { -+ long long n; -+ double d; -+ CFNumberType cfnt = CFNumberGetType(cfr); -+ switch (cfnt) { -+ case kCFNumberSInt8Type: -+ case kCFNumberSInt16Type: -+ case kCFNumberSInt32Type: -+ case kCFNumberSInt64Type: -+ case kCFNumberCharType: -+ case kCFNumberShortType: -+ case kCFNumberIntType: -+ case kCFNumberLongType: -+ case kCFNumberLongLongType: -+ CFNumberGetValue(cfr, kCFNumberLongLongType, &n); -+ r = launch_data_alloc(LAUNCH_DATA_INTEGER); -+ launch_data_set_integer(r, n); -+ break; -+ case kCFNumberFloat32Type: -+ case kCFNumberFloat64Type: -+ case kCFNumberFloatType: -+ case kCFNumberDoubleType: -+ CFNumberGetValue(cfr, kCFNumberDoubleType, &d); -+ r = launch_data_alloc(LAUNCH_DATA_REAL); -+ launch_data_set_real(r, d); -+ break; -+ default: -+ r = NULL; -+ break; -+ } -+ } else { -+ r = NULL; -+ } -+ return r; -+} -+ -+CFPropertyListRef -+CreateMyPropertyListFromFile(const char *posixfile) -+{ -+ CFPropertyListRef propertyList; -+ CFStringRef errorString; -+ CFDataRef resourceData; -+ SInt32 errorCode; -+ CFURLRef fileURL; -+ -+ fileURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)posixfile, strlen(posixfile), false); -+ if (!fileURL) { -+ fprintf(stderr, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile); -+ } -+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, fileURL, &resourceData, NULL, NULL, &errorCode)) { -+ fprintf(stderr, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile, (int)errorCode); -+ } -+ propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListMutableContainers, &errorString); -+ if (!propertyList) { -+ fprintf(stderr, "%s: propertyList is NULL\n", getprogname()); -+ } -+ -+ return propertyList; -+} -+ -+#define _assert(test, format, args...) do { \ -+ if (test) break; \ -+ fprintf(stderr, format "\n", ##args); \ -+ return 1; \ -+} while (false) -+ -+void stop() { -+ sleep(1); -+} -+ -+#define SpringBoard_plist "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" -+ -+pid_t launch_get_job_pid(const char * job) -+{ -+ launch_data_t resp; -+ launch_data_t msg; -+ -+ msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -+ if (msg == NULL) { -+ return -1; -+ } -+ -+ launch_data_dict_insert(msg, launch_data_new_string(job), LAUNCH_KEY_GETJOB); -+ -+ resp = launch_msg(msg); -+ launch_data_free(msg); -+ -+ if (resp == NULL) { -+ return -1; -+ } -+ -+ if (launch_data_get_type(resp) != LAUNCH_DATA_DICTIONARY) return -1; -+ -+ launch_data_t pid_data = launch_data_dict_lookup(resp, "PID"); -+ if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) return -1; -+ -+ pid_t pid = (pid_t)launch_data_get_integer(pid_data); -+ launch_data_free(resp); -+ return pid; -+} -+ -+int main(int argc, const char *argv[]) { -+ platformizeme(); -+ _assert(argc == 1, "usage: sbreload"); -+ -+ if (kCFCoreFoundationVersionNumber >= 1443.00) { -+ dlopen("/System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices", RTLD_LAZY); -+ dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY); -+ Class $SBSRelaunchAction = objc_getClass("SBSRelaunchAction"); -+ Class $FBSSystemService = objc_getClass("FBSSystemService"); -+ pid_t sb_pid = launch_get_job_pid("com.apple.SpringBoard"); -+ if ($SBSRelaunchAction && $FBSSystemService) { -+ @autoreleasepool { -+ id action = [$SBSRelaunchAction actionWithReason:@"respring" options:RestartRenderServer targetURL:nil]; -+ id sharedService = [$FBSSystemService sharedService]; -+ [sharedService sendActions:[NSSet setWithObject:action] withResult:nil]; -+ for (int i=0; i<100; i++) { -+ if (kill(sb_pid, 0)) { -+ return 0; -+ } -+ usleep(1000); -+ } -+ } -+ } -+ } -+ CFDictionaryRef plist = CreateMyPropertyListFromFile(SpringBoard_plist); -+ _assert(plist != NULL, "CreateMyPropertyListFromFile() == NULL"); -+ -+ launch_data_t job = CF2launch_data(plist); -+ _assert(job != NULL, "CF2launch_data() == NULL"); -+ -+ launch_data_t data, request, response; -+ -+ data = launch_data_dict_lookup(job, LAUNCH_JOBKEY_LABEL); -+ _assert(data != NULL, "launch_data_dict_lookup(LABEL) == NULL"); -+ const char *label = launch_data_get_string(data); -+ -+ request = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -+ launch_data_dict_insert(request, launch_data_new_string(label), LAUNCH_KEY_GETJOB); -+ -+ response = launch_msg(request); -+ _assert(response != NULL, "launch_msg(GetJob) == NULL"); -+ launch_data_free(request); -+ -+ pid_t pid; -+ -+ if (launch_data_get_type(response) == LAUNCH_DATA_ERRNO) { -+ int error = launch_data_get_errno(response); -+ _assert(error == ESRCH, "GetJob(%s): %s", label, strerror(error)); -+ pid = -1; -+ } else if (launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY) { -+ data = launch_data_dict_lookup(response, LAUNCH_JOBKEY_PID); -+ _assert(data != NULL, "launch_data_dict_lookup(PID) == NULL"); -+ pid = launch_data_get_integer(data); -+ } else _assert(false, "launch_data_get_type() not in (DICTIONARY, ERRNO)"); -+ -+ launch_data_free(response); -+ -+ // 600 is being used to approximate 4.x/5.x boundary -+ if (kCFCoreFoundationVersionNumber < 600) { -+ fprintf(stderr, "notify_post(com.apple.mobile.springboard_teardown)\n"); -+ notify_post("com.apple.mobile.springboard_teardown"); -+ } else { -+ // XXX: this code is preferable to launchctl unoad but it requires libvproc? :( -+ //vproc_err_t *error = _vproc_send_signal_by_label(label, VPROC_MAGIC_UNLOAD_SIGNAL); -+ //_assert(error == NULL, "_vproc_send_signal_by_label(UNLOAD) != NULL"); -+ -+ fprintf(stderr, "launchctl unload SpringBoard.plist\n"); -+ system("launchctl unload " SpringBoard_plist); -+ } -+ -+ if (pid != -1) { -+ fprintf(stderr, "waiting for kill(%u) != 0...\n", pid); -+ while (kill(pid, 0) == 0) -+ stop(); -+ -+ int error = errno; -+ _assert(error == ESRCH, "kill(%u): %s", pid, strerror(error)); -+ } -+ -+ request = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -+ launch_data_dict_insert(request, job, LAUNCH_KEY_SUBMITJOB); -+ -+ for (;;) { -+ response = launch_msg(request); -+ _assert(response != NULL, "launch_msg(SubmitJob) == NULL"); -+ -+ _assert(launch_data_get_type(response) == LAUNCH_DATA_ERRNO, "launch_data_get_type() != ERRNO"); -+ int error = launch_data_get_errno(response); -+ launch_data_free(response); -+ -+ const char *string = strerror(error); -+ -+ if (error == EEXIST) { -+ fprintf(stderr, "SubmitJob(%s): %s, retrying...\n", label, string); -+ stop(); -+ } else { -+ _assert(error == 0, "SubmitJob(%s): %s", label, string); -+ break; -+ } -+ } -+ -+ launch_data_free(request); -+ -+ return 0; -+} -diff -urN uikittools/sbreload.xml uikittools+uicache/sbreload.xml ---- uikittools/sbreload.xml 1969-12-31 14:00:00.000000000 -1000 -+++ uikittools+uicache/sbreload.xml 2019-06-07 22:37:29.000000000 -1000 -@@ -0,0 +1,13 @@ -+ -+ -+ -+ com.apple.frontboard.launchapplications -+ -+ com.apple.frontboard.shutdown -+ -+ platform-application -+ -+ com.apple.private.skip-library-validation -+ -+ -+ -diff -urN uikittools/uicache.mm uikittools+uicache/uicache.mm ---- uikittools/uicache.mm 2018-10-04 15:58:19.000000000 -1000 -+++ uikittools+uicache/uicache.mm 2019-06-07 22:37:39.000000000 -1000 -@@ -1,7 +1,17 @@ - /* UIKit Tools - command-line utilities for UIKit - * Copyright (C) 2008-2012 Jay Freeman (saurik) -+ * Portions Copyright (C) 2019 Sam Bingner - */ - -+/* uicache.mm -+ * -+ * Licensed under GPL v2.0 license as available at: -+ * https://www.gnu.org/licenses/gpl2.txt -+ * -+ * In adition, usage must meet the following -+ * Modified BSD terms: -+ */ -+ - /* Modified BSD License {{{ */ - /* - * Redistribution and use in source and binary -@@ -38,13 +48,16 @@ - /* }}} */ - - #import -- --#include --#include --#include --#include -- --#include -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import -+#import - - #include "csstore.hpp" - -@@ -81,6 +94,12 @@ - - @end - -+@interface LSApplicationProxy : NSObject -+- (NSString*) applicationIdentifier; -+- (NSURL*) resourcesDirectoryURL; -+- (NSDate*) registeredDate; -+@end -+ - @interface LSApplicationWorkspace : NSObject - + (id) defaultWorkspace; - - (BOOL) registerApplication:(id)application; -@@ -89,16 +108,188 @@ - - (BOOL) registerApplicationDictionary:(id)application; - - (BOOL) installApplication:(id)application withOptions:(id)options; - - (BOOL) _LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)system internal:(BOOL)internal user:(BOOL)user; -+- (NSArray*) allApplications; -+@end -+ -+@interface MCMAppDataContainer -++(id)containerWithIdentifier:(NSString*)identifier createIfNecessary:(bool)create existed:(bool*)existed error:(NSError*)error; -+-(NSURL*)url; -+@end -+ -+@interface FBSSystemService -++(id)sharedService; -+-(void)sendActions:(NSSet*)actions withResult:(id)result; - @end - --int main(int argc, const char *argv[]) { -- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -+typedef enum { -+ None = 0, -+ RestartRenderServer = (1 << 0), // also relaunch backboardd -+ SnapshotTransition = (1 << 1), -+ FadeToBlackTransition = (1 << 2), -+} SBSRelaunchActionStyle; -+ -+@interface SBSRelaunchAction -++(id)actionWithReason:(id)reason options:(int64_t)options targetURL:(NSURL*)url; -+@end -+ -+static int verbose=0; -+static int standard_uicache(void); -+static Class $MCMPluginKitPluginDataContainer; -+static Class $MCMAppDataContainer; -+static Class $LSApplicationWorkspace; -+LSApplicationWorkspace *workspace=nil; -+ -+NSString *getAppPath(NSString *path) -+{ -+ path = [path stringByResolvingSymlinksInPath]; -+ if (![path hasPrefix:@"/Applications/"]) { -+ fprintf(stderr, "Error: Path must be within /Applications/\n"); -+ return nil; -+ } -+ return [NSString pathWithComponents:[[path pathComponents] subarrayWithRange:NSMakeRange(0, 3)]]; -+} - -- Class $LSApplicationWorkspace(objc_getClass("LSApplicationWorkspace")); -- LSApplicationWorkspace *workspace($LSApplicationWorkspace == nil ? nil : [$LSApplicationWorkspace defaultWorkspace]); -+bool appIsRegistered(NSString *path) -+{ -+ @autoreleasepool { -+ path = getAppPath(path); -+ if (!path) return false; -+ for (LSApplicationProxy *app in [workspace allApplications]) { -+ if ([path isEqualToString:[[app resourcesDirectoryURL] path]]) return true; -+ } -+ return false; -+ } -+} - -- if (kCFCoreFoundationVersionNumber > 1000) // this API is on iOS 7 but invaliding the icon cache is harder there -- if ([workspace respondsToSelector:@selector(_LSPrivateRebuildApplicationDatabasesForSystemApps:internal:user:)]) { -+bool unregisterPath(NSString *path) -+{ -+ @autoreleasepool { -+ if (verbose) fprintf(stderr, "Unregistering %s\n", path.lastPathComponent.UTF8String); -+ path = getAppPath(path); -+ if (!path) return false; -+ if (appIsRegistered(path) && ![workspace unregisterApplication:[NSURL fileURLWithPath:path]]) { -+ fprintf(stderr, "Error: unregisterApplication failed for %s\n", path.lastPathComponent.UTF8String); -+ return false; -+ } -+ } -+ return true; -+} -+ -+// Credit to coolstar for finding how to do this and not sharing with the community thereby forcing me to figure out how to do the same thing. -+bool registerPath(NSString *path) -+{ -+ if (!path) { -+ if (verbose) fprintf(stderr, "registerPath called with no path\n"); -+ return false; -+ } -+ NSString *realPath = getAppPath(path); -+ if (!realPath) { -+ if (verbose) fprintf(stderr, "unable to determine path for %s\n", path.UTF8String); -+ return false; -+ } -+ NSDictionary *infoDictionary = [NSDictionary dictionaryWithContentsOfFile: -+ [realPath stringByAppendingPathComponent:@"Info.plist"]]; -+ NSString *bundleID = [infoDictionary objectForKey:@"CFBundleIdentifier"]; -+ -+ if (bundleID) { -+ NSFileManager *fm = [NSFileManager defaultManager]; -+ -+ if ([infoDictionary objectForKey:@"CFBundleExecutable"]) { -+ NSString *executable = [realPath stringByAppendingPathComponent:[infoDictionary objectForKey:@"CFBundleExecutable"]]; -+ if (![fm fileExistsAtPath:executable]) { -+ fprintf(stderr, "Error: CFBundleExecutable defined but missing for %s - this is a fatal error. Aborting.\n", realPath.lastPathComponent.UTF8String); -+ return false; -+ } -+ } -+ -+ NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: -+ @"System", @"ApplicationType", -+ @YES, @"BundleNameIsLocalized", -+ bundleID, @"CFBundleIdentifier", -+ @NO, @"CompatibilityState", -+ @NO, @"IsDeletable", -+ realPath, @"Path", -+ [NSMutableDictionary dictionary], @"_LSBundlePlugins", -+ nil]; -+ -+ id appContainer = [$MCMAppDataContainer containerWithIdentifier:bundleID -+ createIfNecessary:YES existed:NULL error:nil]; -+ -+ NSString *appContainerPath = [[appContainer url] path]; -+ if (appContainerPath) { -+ dict[@"Container"] = appContainerPath; -+ } -+ NSString *pluginsPath = [realPath stringByAppendingPathComponent:@"PlugIns"]; -+ for (NSString *plugin in [fm contentsOfDirectoryAtPath:pluginsPath error:nil]) { -+ NSString *pluginPath = [pluginsPath stringByAppendingPathComponent:plugin]; -+ NSString *pluginInfoPlistPath = [pluginPath stringByAppendingPathComponent:@"Info.plist"]; -+ NSString *pluginBundleIdentifier = [[NSDictionary dictionaryWithContentsOfFile:pluginInfoPlistPath] objectForKey:@"CFBundleIdentifier"]; -+ if (pluginBundleIdentifier) { -+ id pluginContainer = [$MCMPluginKitPluginDataContainer containerWithIdentifier:pluginBundleIdentifier -+ createIfNecessary:YES existed:NULL error:nil]; -+ NSURL *pluginContainerURL = [pluginContainer url]; -+ NSString *pluginContainerPath = [pluginContainerURL path]; -+ dict[@"_LSBundlePlugins"][pluginBundleIdentifier] = @{ -+ @"ApplicationType": @"PluginKitPlugin", -+ @"BundleNameIsLocalized": @YES, -+ @"CFBundleIdentifier": pluginBundleIdentifier, -+ @"CompatibilityState": @NO, -+ @"Container": pluginContainerPath, -+ @"Path": pluginPath, -+ @"PluginOwnerBundleID": bundleID -+ }; -+ } -+ } -+ if (![[$LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:dict]) { -+ fprintf(stderr, "Error: registerApplicationDictionary failed for %s\n", path.lastPathComponent.UTF8String); -+ return false; -+ } -+ } else { -+ return unregisterPath(realPath); -+ } -+ return true; -+} -+ -+void usage(void) -+{ -+ fprintf(stderr, "Usage: %s [-hrv] [[-p | -u] /Applications/App.app]]\n", getprogname()); -+ exit(EXIT_FAILURE); -+} -+ -+pid_t launch_get_job_pid(const char * job) -+{ -+ launch_data_t resp; -+ launch_data_t msg; -+ -+ msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY); -+ if (msg == NULL) { -+ return -1; -+ } -+ -+ launch_data_dict_insert(msg, launch_data_new_string(job), LAUNCH_KEY_GETJOB); -+ -+ resp = launch_msg(msg); -+ launch_data_free(msg); -+ -+ if (resp == NULL) { -+ return -1; -+ } -+ -+ if (launch_data_get_type(resp) != LAUNCH_DATA_DICTIONARY) return -1; -+ -+ launch_data_t pid_data = launch_data_dict_lookup(resp, "PID"); -+ if (launch_data_get_type(pid_data) != LAUNCH_DATA_INTEGER) return -1; -+ -+ pid_t pid = (pid_t)launch_data_get_integer(pid_data); -+ launch_data_free(resp); -+ return pid; -+} -+ -+int standard_uicache(void) -+{ -+ @autoreleasepool { -+ if (kCFCoreFoundationVersionNumber > 1000 && // this API is on iOS 7 but invaliding the icon cache is harder there -+ [workspace respondsToSelector:@selector(_LSPrivateRebuildApplicationDatabasesForSystemApps:internal:user:)]) { - if (![workspace _LSPrivateRebuildApplicationDatabasesForSystemApps:YES internal:YES user:NO]) - fprintf(stderr, "failed to rebuild application databases"); - return 0; -@@ -226,12 +417,247 @@ - system("killall -SIGCONT SpringBoard"); - } - -- if (respring) -- system("launchctl stop com.apple.SpringBoard"); -- else -- notify_post("com.apple.mobile.application_installed"); -- -- [pool release]; -+ notify_post("com.apple.mobile.application_installed"); - - return 0; -+ } -+} -+ -+pid_t pidOfCydia(void) { -+ launch_data_t request = launch_data_new_string(LAUNCH_KEY_GETJOBS); -+ launch_data_t response = launch_msg(request); -+ launch_data_free(request); -+ __block pid_t pid=-1; -+ -+ if (response == NULL || launch_data_get_type(response) != LAUNCH_DATA_DICTIONARY) return -1; -+ -+ xpc_dictionary_apply((xpc_object_t)response, ^bool(const char *key, xpc_object_t value) { -+ if (xpc_get_type(value) == XPC_TYPE_DICTIONARY) { -+ const char *program = xpc_dictionary_get_string(value, "Program"); -+ if (program && strcmp(program, "/Applications/Cydia.app/Cydia") == 0) { -+ pid = (pid_t)xpc_dictionary_get_int64(value, "PID"); -+ if (verbose) fprintf(stderr, "Found Cydia running with PID: %d\n", pid); -+ return false; -+ } -+ } -+ return true; -+ }); -+ -+ if (pid>0) { -+ return pid; -+ } -+ return -1; -+} -+ -+int optimized_uicache(void) { -+ __block int rv=0; -+ NSMutableDictionary *registered = [NSMutableDictionary new]; -+ static void (^readHandler)(NSFileHandle*) = ^(NSFileHandle *fh) { -+ NSData *output = [fh readDataToEndOfFile]; -+ if (output.length==0) return; -+ const char *found_path = (const char *)[output bytes]; -+ NSArray *found = [@(found_path) pathComponents]; -+ if (found.count >= 3) { -+ NSString *appPath = [@"/Applications" stringByAppendingPathComponent:found[2]]; -+ @synchronized (registered) { -+ if (registered[appPath]) return; -+ if (verbose) fprintf(stderr, "Updating %s\n", appPath.lastPathComponent.UTF8String); -+ registered[appPath] = @YES; -+ } -+ pid_t cydia_pid; -+ if ([found[2] isEqualToString:@"Cydia.app"] && -+ (cydia_pid = pidOfCydia()) > 0) { -+ // We are in cydia and trying to refresh it - this will kill it. Let's schedule it for later. -+ if (verbose) fprintf(stderr, "Waiting to refresh Cydia...\n"); -+ pid_t pid = fork(); -+ if (pid == 0) { -+ setpgrp(); -+ signal(SIGHUP, SIG_IGN); -+ signal(SIGPIPE, SIG_IGN); -+ fclose(stdin); -+ freopen("/dev/null", "a", stderr); -+ freopen("/dev/null", "a", stdout); -+ pid = fork(); -+ if (pid == 0) { -+ while (kill(cydia_pid, 0)==0) { -+ sleep(1); -+ } -+ const char *uicache = (*_NSGetArgv())[0]; -+ execl(uicache, uicache, "-vvvvvvv", NULL); -+ fprintf(stderr, "Unable to exec\n"); -+ fflush(stderr); -+ exit(-1); -+ } -+ exit(0); -+ } else if (pid > 0) { -+ int stat; -+ waitpid(pid, &stat, 0); -+ return; -+ } else { -+ fprintf(stderr, "Unable to fork\n"); -+ } -+ } -+ if (!registerPath(appPath)) rv++; -+ } -+ }; -+ NSFileManager *fm = [NSFileManager defaultManager]; -+ NSMutableDictionary *apps = [NSMutableDictionary new]; -+ NSMutableArray *cleanup = [NSMutableArray new]; -+ NSMutableArray *finds = [NSMutableArray new]; -+ if (verbose>1) fprintf(stderr, "Enumerating apps\n"); -+ for (LSApplicationProxy *app in [workspace allApplications]) { -+ NSString *path = [[app resourcesDirectoryURL] path]; -+ if (![path hasPrefix:@"/Applications/"]) continue; -+ if (verbose>1) fprintf(stderr, "Checking %s\n", path.lastPathComponent.UTF8String); -+ -+ NSDate *lastRegistered = [app registeredDate]; -+ -+ if ([fm fileExistsAtPath:path]) { -+ // Check for updated components -+ NSTask *find = [NSTask new]; -+ [find setLaunchPath:@"/usr/bin/find"]; -+ [find setStandardOutput:[NSPipe pipe]]; -+ NSString *stampPath = [NSString stringWithFormat:@"/var/tmp/uicache.stamp.%@", app.applicationIdentifier]; -+ [fm createFileAtPath:stampPath contents:nil attributes:@{NSFileModificationDate: lastRegistered}]; -+ [cleanup addObject:stampPath]; -+ [find setArguments:@[ path, @"-newer", stampPath, @"-print0", @"-quit"]]; -+ [finds addObject:find]; -+ [find launch]; -+ apps[path.lastPathComponent] = app; -+ } else { -+ if (verbose) fprintf(stderr, "De-registering removed app: %s\n", path.lastPathComponent.UTF8String); -+ @synchronized (registered) { -+ if (registered[path]) continue; -+ registered[path] = @YES; -+ } -+ if (!unregisterPath(path)) rv++; -+ } -+ } -+ -+ for (NSString* existing in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/Applications" error:nil]) { -+ NSString *path = [@"/Applications" stringByAppendingPathComponent:existing]; -+ if (apps[existing] || registered[path] || ![existing hasSuffix:@".app"]) continue; -+ if (verbose) fprintf(stderr, "Registering new app: %s\n", existing.UTF8String); -+ @synchronized (registered) { -+ registered[path] = @YES; -+ } -+ if (!registerPath(path)) rv++; -+ } -+ for (NSTask *find in finds) { -+ if (verbose>2) fprintf(stderr, "waiting for find %s\n", [find.arguments componentsJoinedByString:@" "].UTF8String); -+ readHandler([find.standardOutput fileHandleForReading]); -+ [find waitUntilExit]; -+ } -+ for (NSString *path in cleanup) { -+ [fm removeItemAtPath:path error:nil]; -+ } -+ return rv; -+} -+ -+int main(int argc, const char *argv[]) -+{ -+ if (getuid() == 0) { -+ // Be mobile -+ if (setuid(501)) { -+ fprintf(stderr, "Error: unable to become mobile"); -+ return -1; -+ } -+ } -+ dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_LAZY); -+ dlopen("/System/Library/PrivateFrameworks/FrontBoardServices.framework/FrontBoardServices", RTLD_LAZY); -+ dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY); -+ Class $SBSRelaunchAction = objc_getClass("SBSRelaunchAction"); -+ Class $FBSSystemService = objc_getClass("FBSSystemService"); -+ $MCMPluginKitPluginDataContainer = objc_getClass("MCMPluginKitPluginDataContainer"); -+ $MCMAppDataContainer = objc_getClass("MCMAppDataContainer"); -+ $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace"); -+ workspace = [$LSApplicationWorkspace defaultWorkspace]; -+ -+ static int rv=0; -+ @autoreleasepool { -+ bool respring=false, do_all=false; -+ void (*jb_oneshot_entitle_now)(pid_t a, uint64_t b); -+ void *libjb = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); -+ -+ if (libjb) { -+ dlerror(); -+ jb_oneshot_entitle_now = (void (*)(pid_t, uint64_t))dlsym(libjb, "jb_oneshot_entitle_now"); -+ if (!dlerror()) jb_oneshot_entitle_now(getpid(), 2); -+ } -+ -+ NSMutableDictionary *paths = [NSMutableDictionary new]; -+ NSMutableDictionary *unregister_paths = [NSMutableDictionary new]; -+ static struct option long_options[] = -+ { -+ {"all", no_argument, 0, 'a'}, -+ {"help", no_argument, 0, 'h'}, -+ {"path", required_argument, 0, 'p'}, -+ {"unregister", required_argument, 0, 'u'}, -+ {"respring", no_argument, 0, 'r'}, -+ {"verbose", no_argument, 0, 'v'}, -+ {0, 0, 0, 0} -+ }; -+ int option_index = 0; -+ char ch; -+ bool have_path = false; -+ while ((ch = getopt_long(argc, (char *const *)argv, "ap:ru:vh?", long_options, &option_index)) != -1) { -+ switch (ch) -+ { -+ case 'a': -+ do_all = true; -+ break; -+ case 'h': -+ usage(); -+ break; -+ case 'p': -+ paths[@(optarg)] = @YES; -+ have_path = true; -+ break; -+ case 'r': -+ respring = true; -+ break; -+ case 'u': -+ unregister_paths[@(optarg)] = @YES; -+ have_path = true; -+ break; -+ case 'v': -+ verbose++; -+ break; -+ default: -+ break; -+ } -+ } -+ if (do_all || !$MCMPluginKitPluginDataContainer || !$MCMAppDataContainer || !$LSApplicationWorkspace) { -+ rv = standard_uicache(); -+ } else if (have_path) { -+ for (NSString *path in [paths allKeys]) { -+ if (verbose) fprintf(stderr, "Refreshing %s\n", path.UTF8String); -+ if (!registerPath(path)) rv++; -+ } -+ for (NSString *path in [unregister_paths allKeys]) { -+ if (!unregisterPath(path)) rv++; -+ } -+ } else { -+ rv += optimized_uicache(); -+ } -+ if ( respring ) -+ { -+ pid_t sb_pid = launch_get_job_pid("com.apple.SpringBoard"); -+ if ($SBSRelaunchAction && $FBSSystemService) { -+ id action = [$SBSRelaunchAction actionWithReason:@"respring" options:RestartRenderServer targetURL:nil]; -+ id sharedService = [$FBSSystemService sharedService]; -+ [sharedService sendActions:[NSSet setWithObject:action] withResult:nil]; -+ for (int i=0; i<100; i++) { -+ if (kill(sb_pid, 0)) { -+ break; -+ } -+ usleep(1000); -+ } -+ } else { -+ system("launchctl stop com.apple.SpringBoard"); -+ system("launchctl stop com.apple.backboardd"); -+ } -+ } -+ } // @autoreleasepool -+ return rv; - } -diff -urN uikittools/uicache.xml uikittools+uicache/uicache.xml ---- uikittools/uicache.xml 2018-10-04 15:58:37.000000000 -1000 -+++ uikittools+uicache/uicache.xml 2019-06-07 22:37:29.000000000 -1000 -@@ -4,23 +4,22 @@ - com.apple.private.mobileinstall.allowedSPI - - InstallForLaunchServices -+ UninstallForLaunchServices - -- - com.apple.lsapplicationworkspace.rebuildappdatabases - -- - com.apple.private.MobileContainerManager.allowed - -- - com.apple.private.kernel.override-cpumon - -- - com.apple.vpn.installer_events - -- -+ com.apple.frontboard.launchapplications -+ -+ com.apple.frontboard.shutdown -+ - platform-application - -- - com.apple.private.skip-library-validation - - -- cgit v1.2.3