summaryrefslogtreecommitdiff
path: root/extrainst_.mm
diff options
context:
space:
mode:
authorJay Freeman (saurik) <saurik@saurik.com>2015-06-25 10:19:08 +0000
committerJay Freeman (saurik) <saurik@saurik.com>2015-06-25 11:59:32 +0000
commit10fd0e0c7fc4459f65c1e6029d44cd522e18becb (patch)
tree90bdf8374633501d71c8d606d5371da0ed96c217 /extrainst_.mm
parent445ca7c40d970d9ed973e67040123c2e020fd294 (diff)
On iOS 8.3, allow symbolic links as /Applications.
Diffstat (limited to 'extrainst_.mm')
-rw-r--r--extrainst_.mm103
1 files changed, 103 insertions, 0 deletions
diff --git a/extrainst_.mm b/extrainst_.mm
index a938b04..8d4d15b 100644
--- a/extrainst_.mm
+++ b/extrainst_.mm
@@ -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]);