summaryrefslogtreecommitdiff
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
parent445ca7c40d970d9ed973e67040123c2e020fd294 (diff)
On iOS 8.3, allow symbolic links as /Applications.
-rw-r--r--.gitignore1
-rw-r--r--control5
-rw-r--r--extrainst_.mm103
-rw-r--r--libuicache.mm27
-rw-r--r--makefile10
5 files changed, 143 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index f891275..cfeb3bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ uicache
uiduid
uiopen
uishoot
+libuicache.dylib
diff --git a/control b/control
index 328d4f5..7fbeadb 100644
--- 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
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]);
diff --git a/libuicache.mm b/libuicache.mm
new file mode 100644
index 0000000..800beb9
--- /dev/null
+++ b/libuicache.mm
@@ -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$));
+}
diff --git a/makefile b/makefile
index 27410ef..7ba5ac8 100644
--- 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/