From c3315f132c70d1b2f0eb8bc77a471d696f31c248 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 24 Oct 2015 06:06:28 -0700 Subject: [PATCH] Ensure moved applications are found in canOpenURL. --- extrainst_.mm | 3 ++- makefile | 1 + patch.hpp | 23 +++++++++++++----- patcyh.mm | 67 ++++++++++++++++++++++++++++++++++++++++++++++++--- postrm.mm | 3 ++- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/extrainst_.mm b/extrainst_.mm index 45e70b5..3aa841e 100644 --- a/extrainst_.mm +++ b/extrainst_.mm @@ -37,9 +37,10 @@ int main(int argc, const char *argv[]) { NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); + if (!PatchLaunch(false, false)) + return 1; if (!PatchInstall(false, false)) return 1; - system("launchctl stop com.apple.mobile.installd"); [pool release]; return 0; diff --git a/makefile b/makefile index f30dc74..dca5f8e 100644 --- a/makefile +++ b/makefile @@ -12,6 +12,7 @@ clean: flags := -Os -Werror flags += -framework CoreFoundation flags += -framework Foundation +flags += -marm lib%.dylib: %.mm cycc -i2.0 -o$@ -- -dynamiclib $(flags) $(filter-out %.hpp,$^) $($@) -lobjc diff --git a/patch.hpp b/patch.hpp index 658333e..e108eb4 100644 --- a/patch.hpp +++ b/patch.hpp @@ -22,6 +22,8 @@ #ifndef PATCH_HPP #define PATCH_HPP +#include + #include #include @@ -30,7 +32,6 @@ #include -#define INSTALLD "/usr/libexec/installd" #define LIBUICACHE "/usr/lib/libpatcyh.dylib" static void *(*$memmem)(const void *, size_t, const void *, size_t) = reinterpret_cast(dlsym(RTLD_DEFAULT, "memmem")); @@ -100,13 +101,13 @@ static bool PatchInstall(bool uninstall, void *data) { return true; } -static bool PatchInstall(bool uninstall, bool abort) { +static bool Patch(const std::string &path, const std::string &service, bool uninstall, bool abort) { if (!abort && system("ldid --") != 0) { fprintf(stderr, "this package requires ldid to be installed\n"); return false; } - int fd(open(INSTALLD, O_RDWR)); + int fd(open(path.c_str(), O_RDWR)); if (fd == -1) return false; @@ -139,12 +140,22 @@ static bool PatchInstall(bool uninstall, bool abort) { munmap(data, size); if (changed) { - system("ldid -s "INSTALLD""); - system("cp -af "INSTALLD" "INSTALLD"_"); - system("mv -f "INSTALLD"_ "INSTALLD""); + system(("ldid -s " + path + "").c_str()); + system(("cp -af " + path + " " + path + "_").c_str()); + system(("mv -f " + path + "_ " + path + "").c_str()); + system(("launchctl stop " + service + "").c_str()); } return true; } + +static bool PatchInstall(bool uninstall, bool abort) { + return Patch("/usr/libexec/installd", "com.apple.mobile.installd", uninstall, abort); +} + +static bool PatchLaunch(bool uninstall, bool abort) { + return Patch("/usr/libexec/lsd", "com.apple.lsd", uninstall, abort); +} + #endif//PATCH_HPP diff --git a/patcyh.mm b/patcyh.mm index 85ddfe4..a2c5039 100644 --- a/patcyh.mm +++ b/patcyh.mm @@ -45,14 +45,73 @@ static NSArray *$MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$err [items addObject:[NSURL fileURLWithPathComponents:[prefix arrayByAddingObjectsFromArray:[components subarrayWithRange:NSMakeRange(skip, [components count] - skip)]]]]; } + NSLog(@"items = %@", items); return items; } +static NSString *(*_NSURL$path)(NSURL *self, SEL _cmd); + +static NSString *$NSURL$path(NSURL *self, SEL _cmd) { + return [[_NSURL$path(self, _cmd) mutableCopy] autorelease]; +} + +static NSRange (*_NSString$rangeOfString$options$)(NSString *self, SEL _cmd, NSString *value, NSStringCompareOptions options); + +static NSRange $NSString$rangeOfString$options$(NSString *self, SEL _cmd, NSString *value, NSStringCompareOptions options) { + if ([value isEqualToString:@".app/"]) do { + char *real(realpath("/Applications", NULL)); + NSString *destiny([NSString stringWithUTF8String:real]); + free(real); + + if ([destiny isEqualToString:@"/Applications"]) + break; + + destiny = [destiny stringByAppendingString:@"/"]; + if (![self hasPrefix:destiny]) + break; + + if (![self hasSuffix:@".app"]) + break; + + BOOL directory; + if (![[NSFileManager defaultManager] fileExistsAtPath:self isDirectory:&directory]) + break; + if (!directory) + break; + + NSLog(@"path = %@", self); + // the trailing / allows lsd to "restart" its verification attempt + [(NSMutableString *) self setString:[NSString stringWithFormat:@"/Applications/%@/", [self substringFromIndex:[destiny length]]]]; + } while (false); + + return _NSString$rangeOfString$options$(self, _cmd, value, options); +} + __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(method_getImplementation(method)); - method_setImplementation(method, reinterpret_cast(&$MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$)); + + if ($MIFileManager != Nil) { + SEL sel(@selector(urlsForItemsInDirectoryAtURL:ignoringSymlinks:error:)); + if (Method method = class_getInstanceMethod($MIFileManager, sel)) { + _MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$ = reinterpret_cast(method_getImplementation(method)); + method_setImplementation(method, reinterpret_cast(&$MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$)); + } + } + + if (Class $NSURL = objc_getClass("NSURL")) { + SEL sel(@selector(path)); + if (Method method = class_getInstanceMethod($NSURL, sel)) { + _NSURL$path = reinterpret_cast(method_getImplementation(method)); + method_setImplementation(method, reinterpret_cast(&$NSURL$path)); + } + } + + if (Class $NSString = objc_getClass("NSString")) { + SEL sel(@selector(rangeOfString:options:)); + if (Method method = class_getInstanceMethod($NSString, sel)) { + _NSString$rangeOfString$options$ = reinterpret_cast(method_getImplementation(method)); + method_setImplementation(method, reinterpret_cast(&$NSString$rangeOfString$options$)); + } + } } diff --git a/postrm.mm b/postrm.mm index 57f18eb..faa1dbc 100644 --- a/postrm.mm +++ b/postrm.mm @@ -35,7 +35,8 @@ int main(int argc, const char *argv[]) { if (!PatchInstall(true, abort)) return 1; - system("launchctl stop com.apple.mobile.installd"); + if (!PatchLaunch(true, abort)) + return 1; [pool release]; return 0; -- 2.47.2