]> git.saurik.com Git - safemode-ios.git/blobdiff - Tweak.xm
Force build to use the only working Xcode (5.1.1).
[safemode-ios.git] / Tweak.xm
index cbab28d24c4cf9820e1d4dc47947244c2d03c41c..2e85f78fb427dd29da48cec37a1622e04accb034 100644 (file)
--- a/Tweak.xm
+++ b/Tweak.xm
@@ -88,6 +88,7 @@ void SafeModeAlertItem$configure$requirePasscodeForActions$(id self, SEL sel, BO
     UIAlertView *sheet([self alertSheet]);
 
     [sheet setDelegate:self];
+    [sheet setTitle:@""];
     [sheet setBodyText:@"We apologize for the inconvenience, but SpringBoard has just crashed.\n\nMobileSubstrate /did not/ cause this problem: it has protected you from it.\n\nYour device is now running in Safe Mode. All extensions that support this safety system are disabled.\n\nReboot (or restart SpringBoard) to return to the normal mode. To return to this dialog touch the status bar.\n\nTap \"Help\" below for more tips."];
     [sheet addButtonWithTitle:@"OK"];
     [sheet addButtonWithTitle:@"Restart"];
@@ -205,15 +206,33 @@ static void AlertIfNeeded() {
     MSAlert();
 }
 
+// iOS 7
+%hook SBLockScreenManager
+- (void) _finishUIUnlockFromSource:(int)source withOptions:(id)options {
+    %orig;
+    AlertIfNeeded();
+} %end
 
-// on iOS 4.3 and above we can use this advertisement, which seems to check every time the user unlocks
-// XXX: verify that this still works on iOS 5.0
+// iOS 6
+%hook SBAwayController
+- (void) _finishUnlockWithSound:(BOOL)sound unlockSource:(int)source isAutoUnlock:(BOOL)is {
+    %orig;
+    AlertIfNeeded();
+} %end
 
-%hook AAAccountManager
-+ (void) showMobileMeOfferIfNecessary {
+// iOS 5
+%hook SBAwayController
+- (void) _unlockWithSound:(BOOL)sound isAutoUnlock:(BOOL)is unlockSource:(int)source {
+    %orig;
     AlertIfNeeded();
 } %end
 
+// iOS 4.3 XXX: check lower versions
+%hook SBAwayController
+- (void) _unlockWithSound:(BOOL)sound isAutoUnlock:(BOOL)is unlockType:(int)type {
+    %orig;
+    AlertIfNeeded();
+} %end
 
 // -[SBIconController showInfoAlertIfNeeded] explains how to drag icons around the iPhone home screen
 // it used to be shown to users when they unlocked their screen for the first time, and happened every unlock
@@ -269,6 +288,11 @@ static void AlertIfNeeded() {
 
 #define Paper_ "/Library/MobileSubstrate/MobileSafety.png"
 
+%hook SBWallpaperImage
++ (id) alloc {
+    return nil;
+} %end
+
 %hook UIImage
 + (UIImage *) defaultDesktopImage {
     return [UIImage imageWithContentsOfFile:@Paper_];
@@ -290,15 +314,6 @@ static void AlertIfNeeded() {
 } %end
 
 
-// notification widgets ("wee apps" or "bulletin board sections") are capable of crashing SpringBoard
-// unfortunately, which ones are in use are stored in SpringBoard's defaults, so we need to turn them off
-
-%hook BBSectionInfo
-- (BOOL) showsInNotificationCenter {
-    return NO;
-} %end
-
-
 // on iOS 6.0, Apple split parts of SpringBoard into a daemon called backboardd, including app launches
 // in order to allow safe mode to propogate into applications, we need to then tell backboardd here
 // XXX: (all of this should be replaced, however, with per-process launchd-mediated exception handling)
@@ -313,9 +328,49 @@ static void AlertIfNeeded() {
     return %orig(modified);
 } %end
 
+
+// this highly-general hook replaces all previous attempts to protect SpringBoard from spurious code
+// the main purpose is to protect SpringBoard from non-Substrate "away view plug-ins" and "wee apps"
+
+const char *dylibs_[] = {
+    "/usr/lib",
+    "/System/Library/Frameworks",
+    "/System/Library/PrivateFrameworks",
+    "/System/Library/CoreServices",
+    "/System/Library/AccessibilityBundles",
+    NULL,
+};
+
+MSHook(void *, dlopen, const char *path, int mode) {
+    // we probably don't need this whitelist, but it has the nifty benefit of letting Cycript inject
+    // that said, older versions of iOS (before 3.1) will need a special case due to now shared cache
+
+    for (const char **dylib = dylibs_; *dylib != NULL; ++dylib) {
+        size_t length(strlen(*dylib));
+        if (strncmp(path, *dylib, length) != 0)
+            continue;
+        if (path[length] != '/')
+            continue;
+        goto load;
+    }
+
+    // if the file is not on disk, and isn't already loaded (LC_ID_DYLIB), it is in the shared cache
+    // files loaded from the shared cache are "trusted". ones that don't exist are clearly harmless.
+    // this allows us to load most of the dynamic functionality of SpringBoard without going nuts ;P
+
+    if (access(path, F_OK) == 0)
+        mode |= RTLD_NOLOAD;
+
+  load:
+    return _dlopen(path, mode);
+}
+
+
 %ctor {
     NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
 
+    MSHookFunction(&dlopen, MSHake(dlopen));
+
     // on iOS 6, backboardd is in charge of brightness, and freaks out when SpringBoard restarts :(
     // the result is that the device is super dark until we attempt to update the brightness here.