From 71b6516daec193c1eb13aa0030ff866301b17e0d Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 25 Jun 2015 13:12:08 +0000 Subject: On 8.3+, CS_RESTRICT breaks DYLD_INSERT_LIBRARIES. --- extrainst_.mm | 105 +++++++++++++++++++++++++--------------------------------- 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/extrainst_.mm b/extrainst_.mm index 8d4d15b..d5f5e04 100644 --- a/extrainst_.mm +++ b/extrainst_.mm @@ -47,6 +47,7 @@ #include #include #include +#include #include "csstore.hpp" @@ -133,9 +134,47 @@ void FixCache(NSString *home, NSString *plist) { } #define INSTALLD "/usr/libexec/installd" +#define LIBUICACHE "/usr/lib/libuicache.dylib" static void *(*$memmem)(const void *, size_t, const void *, size_t); +template +static bool PatchInstall(void *data) { + Header *header(reinterpret_cast
(data)); + + load_command *command(reinterpret_cast(header + 1)); + for (size_t i(0); i != header->ncmds; ++i) { + command = reinterpret_cast(reinterpret_cast(command) + command->cmdsize); + if (command->cmd != LC_LOAD_DYLIB) + continue; + + dylib_command *load(reinterpret_cast(command)); + const char *name(reinterpret_cast(command) + load->dylib.name.offset); + if (strcmp(name, LIBUICACHE) == 0) + return false; + } + + if (reinterpret_cast(command) != reinterpret_cast(header + 1) + header->sizeofcmds) + return false; + + dylib_command *load(reinterpret_cast(command)); + memset(load, 0, sizeof(*load)); + load->cmd = LC_LOAD_DYLIB; + + load->cmdsize = sizeof(*load) + sizeof(LIBUICACHE); + load->cmdsize = (load->cmdsize + 15) / 16 * 16; + memset(load + 1, 0, load->cmdsize - sizeof(*load)); + + dylib *dylib(&load->dylib); + dylib->name.offset = sizeof(*load); + memcpy(load + 1, LIBUICACHE, sizeof(LIBUICACHE)); + + ++header->ncmds; + header->sizeofcmds += load->cmdsize; + + return true; +} + static bool PatchInstall() { int fd(open(INSTALLD, O_RDWR)); if (fd == -1) @@ -154,14 +193,13 @@ static bool PatchInstall() { return false; bool changed(false); - for (;;) { - void *name($memmem(data, size, "__restrict", 10)); - if (name == NULL) + switch (*reinterpret_cast(data)) { + case MH_MAGIC: + changed = PatchInstall(data); + break; + case MH_MAGIC_64: + changed = PatchInstall(data); break; - else { - memcpy(name, "__uicache_", 10); - changed = true; - } } munmap(data, size); @@ -175,56 +213,6 @@ static bool PatchInstall() { 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 && @@ -237,8 +225,7 @@ int main(int argc, const char *argv[]) { if (kCFCoreFoundationVersionNumber >= 1143) // XXX: iOS 8.3+ if (PatchInstall()) - if (HookInstall()) - FinishCydia("reboot"); + system("launchctl stop com.apple.mobile.installd"); if (kCFCoreFoundationVersionNumber >= 700 && kCFCoreFoundationVersionNumber < 800) { // XXX: iOS 6.x NSString *home(@"/var/mobile"); -- cgit v1.2.3