]> git.saurik.com Git - uikittools.git/commitdiff
On iOS 8.3, allow symbolic links as /Applications.
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 25 Jun 2015 10:19:08 +0000 (10:19 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 25 Jun 2015 11:59:32 +0000 (11:59 +0000)
.gitignore
control
extrainst_.mm
libuicache.mm [new file with mode: 0644]
makefile

index f891275a67c7b8294071caf0061730c37e292ffe..cfeb3bc4f2529963db7eeadd09d53a124eac78c7 100644 (file)
@@ -11,3 +11,4 @@ uicache
 uiduid
 uiopen
 uishoot
+libuicache.dylib
diff --git a/control b/control
index 328d4f58c7d64d5316a44b3fda9dca9d7830e98b..7fbeadb72cb1a47ffb158e77997efb83188f112e 100644 (file)
--- a/control
+++ b/control
@@ -4,9 +4,12 @@ Section: Utilities
 Maintainer: Jay Freeman (saurik) <saurik@saurik.com>
 Architecture: iphoneos-arm
 Version: 
+Essential: yes
 Description: UIKit/GraphicsServices command line access
 Name: UIKit Tools
 Author: Jay Freeman (saurik) <saurik@saurik.com>
 Depiction: http://cydia.saurik.com/info/uikittools/
-Depends: coreutils-bin
+Depends: coreutils-bin, firmware (<< 8.2) | ldid
+Replaces: taiguicache
+Conflicts: taiguicache
 Tag: purpose::console, role::hacker
index a938b0415a47d1f5ffd2b447606e105beb212610..8d4d15b0f734128f212e6bc56477b250ee39fcc9 100644 (file)
@@ -44,6 +44,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <dlfcn.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <string.h>
 
 #include "csstore.hpp"
 
@@ -129,6 +132,99 @@ void FixCache(NSString *home, NSString *plist) {
         printf("you must reboot to finalize your cache.\n");
 }
 
+#define INSTALLD "/usr/libexec/installd"
+
+static void *(*$memmem)(const void *, size_t, const void *, size_t);
+
+static bool PatchInstall() {
+    int fd(open(INSTALLD, O_RDWR));
+    if (fd == -1)
+        return false;
+
+    struct stat stat;
+    if (fstat(fd, &stat) == -1) {
+        close(fd);
+        return false;
+    }
+
+    size_t size(stat.st_size);
+    void *data(mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
+    close(fd);
+    if (data == MAP_FAILED)
+        return false;
+
+    bool changed(false);
+    for (;;) {
+        void *name($memmem(data, size, "__restrict", 10));
+        if (name == NULL)
+            break;
+        else {
+            memcpy(name, "__uicache_", 10);
+            changed = true;
+        }
+    }
+
+    munmap(data, size);
+
+    if (changed) {
+        system("ldid -s "INSTALLD"");
+        system("cp -af "INSTALLD" "INSTALLD"_");
+        system("mv -f "INSTALLD"_ "INSTALLD"");
+    }
+
+    return true;
+}
+
+#define SubstrateLaunchDaemons_ "/Library/LaunchDaemons"
+#define SubstrateVariable_ "DYLD_INSERT_LIBRARIES"
+#define SubstrateLibrary_ "/usr/lib/libuicache.dylib"
+
+static bool HookInstall() {
+    NSString *file([NSString stringWithFormat:@"%@/%s.plist", @ SubstrateLaunchDaemons_, "com.apple.mobile.installd"]);
+    if (file == nil)
+        return false;
+
+    NSMutableDictionary *root([NSMutableDictionary dictionaryWithContentsOfFile:file]);
+    if (root == nil)
+        return false;
+
+    NSMutableDictionary *environment([root objectForKey:@"EnvironmentVariables"]);
+    if (environment == nil) {
+        environment = [NSMutableDictionary dictionaryWithCapacity:1];
+        if (environment == nil)
+            return false;
+
+        [root setObject:environment forKey:@"EnvironmentVariables"];
+    }
+
+    NSString *variable([environment objectForKey:@ SubstrateVariable_]);
+    if (variable == nil || [variable length] == 0)
+        [environment setObject:@ SubstrateLibrary_ forKey:@ SubstrateVariable_];
+    else {
+        NSArray *dylibs([variable componentsSeparatedByString:@":"]);
+        if (dylibs == nil)
+            return false;
+
+        NSUInteger index([dylibs indexOfObject:@ SubstrateLibrary_]);
+        if (index != NSNotFound)
+            return false;
+
+        [environment setObject:[NSString stringWithFormat:@"%@:%@", variable, @ SubstrateLibrary_] forKey:@ SubstrateVariable_];
+    }
+
+    NSString *error;
+    NSData *data([NSPropertyListSerialization dataFromPropertyList:root format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error]);
+    if (data == nil)
+        return false;
+
+    if (![data writeToFile:file atomically:YES])
+        return false;
+
+    system("launchctl unload /Library/LaunchDaemons/com.apple.mobile.installd.plist");
+    system("launchctl load /Library/LaunchDaemons/com.apple.mobile.installd.plist");
+    return true;
+}
+
 int main(int argc, const char *argv[]) {
     if (argc < 2 || (
         strcmp(argv[1], "install") != 0 &&
@@ -137,6 +233,13 @@ int main(int argc, const char *argv[]) {
 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
+    $memmem = reinterpret_cast<void *(*)(const void *, size_t, const void *, size_t)>(dlsym(RTLD_DEFAULT, "memmem"));
+
+    if (kCFCoreFoundationVersionNumber >= 1143) // XXX: iOS 8.3+
+        if (PatchInstall())
+            if (HookInstall())
+                FinishCydia("reboot");
+
     if (kCFCoreFoundationVersionNumber >= 700 && kCFCoreFoundationVersionNumber < 800) { // XXX: iOS 6.x
         NSString *home(@"/var/mobile");
         NSString *plist([NSString stringWithFormat:@"%@/Library/Caches/com.apple.mobile.installation.plist", home]);
diff --git a/libuicache.mm b/libuicache.mm
new file mode 100644 (file)
index 0000000..800beb9
--- /dev/null
@@ -0,0 +1,27 @@
+#include <objc/runtime.h>
+#include <Foundation/Foundation.h>
+
+@interface MIFileManager
++ (MIFileManager *) defaultManager;
+- (NSURL *) destinationOfSymbolicLinkAtURL:(NSURL *)url error:(NSError *)error;
+@end
+
+static Class $MIFileManager;
+
+static NSArray *(*_MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$)(MIFileManager *self, SEL _cmd, NSURL *url, BOOL ignoring, NSError *error);
+
+static NSArray *$MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$(MIFileManager *self, SEL _cmd, NSURL *url, BOOL ignoring, NSError *error) {
+    MIFileManager *manager(reinterpret_cast<MIFileManager *>([$MIFileManager defaultManager]));
+    if (NSURL *destiny = [manager destinationOfSymbolicLinkAtURL:url error:NULL])
+        url = destiny;
+    return _MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$(self, _cmd, url, NO, error);
+}
+
+__attribute__((__constructor__))
+static void initialize() {
+    $MIFileManager = objc_getClass("MIFileManager");
+    SEL sel(@selector(urlsForItemsInDirectoryAtURL:ignoringSymlinks:error:));
+    Method method(class_getInstanceMethod($MIFileManager, sel));
+    _MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$ = reinterpret_cast<NSArray *(*)(MIFileManager *, SEL, NSURL *, BOOL, NSError *)>(method_getImplementation(method));
+    method_setImplementation(method, reinterpret_cast<IMP>(&$MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$));
+}
index 27410ef6d78a28a5fd97cce8f608c6a22ab20788..7ba5ac8a88e8618cbef8e652ae50b34f09d713d0 100644 (file)
--- a/makefile
+++ b/makefile
@@ -1,4 +1,4 @@
-uikittools = uiduid uicache uiopen gssc sbdidlaunch sbreload cfversion iomfsetgamma
+uikittools = uiduid uicache uiopen gssc sbdidlaunch sbreload cfversion iomfsetgamma libuicache.dylib
 
 all: $(uikittools)
 
@@ -19,6 +19,10 @@ extrainst_ := -framework CoreFoundation -framework Foundation
 uicache: csstore.cpp
 extrainst_: csstore.cpp
 
+%.dylib: %.mm
+       $${PKG_TARG}-g++ -Wall -Werror -dynamiclib -o $@ $^ $($@) -F"$${PKG_ROOT}"/System/Library/PrivateFrameworks -lobjc -framework CoreFoundation -framework Foundation
+       ldid -S $@
+
 %: %.mm
        $${PKG_TARG}-g++ -Wall -Werror -o $@ $^ $($@) -F"$${PKG_ROOT}"/System/Library/PrivateFrameworks -lobjc
        ldid -S$(wildcard $@.xml) $@
@@ -33,8 +37,10 @@ iomfsetgamma: iomfsetgamma.c
 
 package: all extrainst_
        rm -rf _
+       mkdir -p _/usr/lib
+       cp -a $(filter %.dylib,$(uikittools)) _/usr/lib
        mkdir -p _/usr/bin
-       cp -a $(uikittools) _/usr/bin
+       cp -a $(filter-out %.dylib,$(uikittools)) _/usr/bin
        mkdir -p _/DEBIAN
        ./control.sh _ >_/DEBIAN/control
        cp -a extrainst_ _/DEBIAN/