From 10fd0e0c7fc4459f65c1e6029d44cd522e18becb Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 25 Jun 2015 10:19:08 +0000 Subject: On iOS 8.3, allow symbolic links as /Applications. --- extrainst_.mm | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'extrainst_.mm') diff --git a/extrainst_.mm b/extrainst_.mm index a938b04..8d4d15b 100644 --- a/extrainst_.mm +++ b/extrainst_.mm @@ -44,6 +44,9 @@ #include #include #include +#include +#include +#include #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(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]); -- cgit v1.2.3