--- /dev/null
+_
+debs
+extrainst_
+postrm
+*.dylib
+*.deb
--- /dev/null
+Package: com.saurik.patcyh
+Priority: optional
+Section: System
+Maintainer: Jay Freeman (saurik) <saurik@saurik.com>
+Architecture: iphoneos-arm
+Version:
+Description: patch for installd to support uikittools
+Name: Patcyh
+Author: Jay Freeman (saurik) <saurik@saurik.com>
+Depiction: http://cydia.saurik.com/info/com.saurik.patcyh/
+Depends: firmware (>= 8.3), coreutils-bin, ldid
+Tag: cydia::obsolete
--- /dev/null
+#!/bin/bash
+dir=$1
+dir=${dir:=_}
+sed -e "s@^\(Version:\).*@\1 $(./version.sh)@" control
+echo "Installed-Size: $(du -s "${dir}" | cut -f 1)"
--- /dev/null
+/* patcyh - you should pronounce it like patch
+ * Copyright (C) 2015 Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cydia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cydia is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#import <Foundation/Foundation.h>
+
+#include <notify.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "patch.hpp"
+
+int main(int argc, const char *argv[]) {
+ if (argc < 2 || (
+ strcmp(argv[1], "install") != 0 &&
+ strcmp(argv[1], "upgrade") != 0 &&
+ true)) return 0;
+
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+
+ if (!PatchInstall(false, false))
+ return 1;
+ system("launchctl stop com.apple.mobile.installd");
+
+ [pool release];
+ return 0;
+}
--- /dev/null
+library := libpatcyh.dylib
+package := com.saurik.patcyh
+control := extrainst_ postrm
+
+all: $(library)
+
+clean:
+ rm -f $(library) $(control)
+
+.PHONY: all clean package
+
+flags := -Os -Werror
+flags += -framework CoreFoundation
+flags += -framework Foundation
+
+lib%.dylib: %.mm
+ cycc -i2.0 -o$@ -- -dynamiclib $(flags) $(filter-out %.hpp,$^) $($@) -lobjc
+
+%: %.mm patch.hpp
+ cycc -i2.0 -o$@ -- $(filter-out %.hpp,$^) $(flags) $($@)
+
+package: all $(control)
+ sudo rm -rf _
+ mkdir -p _/usr/lib
+ cp -a $(library) _/usr/lib
+ mkdir -p _/DEBIAN
+ ./control.sh _ >_/DEBIAN/control
+ cp -a extrainst_ _/DEBIAN/
+ cp -a postrm _/DEBIAN/
+ mkdir -p debs
+ ln -sf debs/$(package)_$$(./version.sh)_iphoneos-arm.deb $(package).deb
+ sudo chown -R 0 _
+ sudo chgrp -R 0 _
+ dpkg-deb -b _ $(package).deb
+ readlink $(package).deb
--- /dev/null
+/* patcyh - you should pronounce it like patch
+ * Copyright (C) 2015 Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cydia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cydia is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#ifndef PATCH_HPP
+#define PATCH_HPP
+
+#include <dlfcn.h>
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <mach-o/loader.h>
+
+#define INSTALLD "/usr/libexec/installd"
+#define LIBUICACHE "/usr/lib/libpatcyh.dylib"
+
+static void *(*$memmem)(const void *, size_t, const void *, size_t) = reinterpret_cast<void *(*)(const void *, size_t, const void *, size_t)>(dlsym(RTLD_DEFAULT, "memmem"));
+
+template <typename Header>
+static bool PatchInstall(bool uninstall, void *data) {
+ Header *header(reinterpret_cast<Header *>(data));
+
+ load_command *command(reinterpret_cast<load_command *>(header + 1));
+ for (size_t i(0); i != header->ncmds; ++i, command = reinterpret_cast<load_command *>(reinterpret_cast<uint8_t *>(command) + command->cmdsize)) {
+ if (command->cmdsize > sizeof(Header) + header->sizeofcmds - (reinterpret_cast<uint8_t *>(command) - reinterpret_cast<uint8_t *>(header))) {
+ fprintf(stderr, "load command is to long to fit in header\n");
+ return false;
+ }
+
+ if (command->cmd != LC_LOAD_DYLIB)
+ continue;
+
+ dylib_command *load(reinterpret_cast<dylib_command *>(command));
+ const char *name(reinterpret_cast<char *>(command) + load->dylib.name.offset);
+ if (strcmp(name, LIBUICACHE) != 0)
+ continue;
+
+ if (!uninstall)
+ return true;
+
+ if (i != header->ncmds - 1) {
+ fprintf(stderr, "load command not in final position %zd %zd\n", i, header->ncmds);
+ return false;
+ }
+
+ if (reinterpret_cast<uint8_t *>(command) + command->cmdsize != reinterpret_cast<uint8_t *>(header + 1) + header->sizeofcmds) {
+ fprintf(stderr, "load command header size integrity fail\n");
+ return false;
+ }
+
+ --header->ncmds;
+ header->sizeofcmds -= command->cmdsize;
+ memset(command, 0, command->cmdsize);
+
+ return true;
+ }
+
+ if (reinterpret_cast<uint8_t *>(command) != reinterpret_cast<uint8_t *>(header + 1) + header->sizeofcmds) {
+ fprintf(stderr, "load command header size integrity fail\n");
+ return false;
+ }
+
+ if (uninstall)
+ return true;
+
+ dylib_command *load(reinterpret_cast<dylib_command *>(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(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));
+ 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);
+ uint32_t magic(*reinterpret_cast<uint32_t *>(data));
+ switch (magic) {
+ case MH_MAGIC:
+ changed = PatchInstall<mach_header>(uninstall, data);
+ break;
+ case MH_MAGIC_64:
+ changed = PatchInstall<mach_header_64>(uninstall, data);
+ break;
+ default:
+ fprintf(stderr, "unknown header magic on installd: %08x\n", magic);
+ return false;
+ }
+
+ munmap(data, size);
+
+ if (changed) {
+ system("ldid -s "INSTALLD"");
+ system("cp -af "INSTALLD" "INSTALLD"_");
+ system("mv -f "INSTALLD"_ "INSTALLD"");
+ }
+
+ return true;
+}
+
+#endif//PATCH_HPP
--- /dev/null
+/* patcyh - you should pronounce it like patch
+ * Copyright (C) 2015 Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cydia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cydia is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#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]));
+ NSURL *destiny([manager destinationOfSymbolicLinkAtURL:url error:NULL]);
+ if (destiny == nil)
+ return _MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$(self, _cmd, url, YES, error);
+
+ NSArray *prefix([url pathComponents]);
+ size_t skip([[destiny pathComponents] count]);
+ NSMutableArray *items([NSMutableArray array]);
+ for (NSURL *item in _MIFileManager$urlsForItemsInDirectoryAtURL$ignoringSymlinks$error$(self, _cmd, destiny, YES, error)) {
+ NSArray *components([item pathComponents]);
+ [items addObject:[NSURL fileURLWithPathComponents:[prefix arrayByAddingObjectsFromArray:[components subarrayWithRange:NSMakeRange(skip, [components count] - skip)]]]];
+ }
+
+ return items;
+}
+
+__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$));
+}
--- /dev/null
+/* patcyh - you should pronounce it like patch
+ * Copyright (C) 2015 Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cydia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cydia is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cydia. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#include <Foundation/Foundation.h>
+
+#include "patch.hpp"
+
+int main(int argc, const char *argv[]) {
+ if (argc < 2 || (
+ strcmp(argv[1], "abort-install") != 0 &&
+ strcmp(argv[1], "remove") != 0 &&
+ true)) return 0;
+
+ bool abort(strcmp(argv[1], "abort-install") == 0);
+
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+
+ if (!PatchInstall(true, abort))
+ return 1;
+ system("launchctl stop com.apple.mobile.installd");
+
+ [pool release];
+ return 0;
+}
--- /dev/null
+#!/bin/bash
+echo -n "$(git describe --tags --dirty="+" --match="v*" | sed -e 's@-\([^-]*\)-\([^-]*\)$@+\1.\2@;s@^v@@')"
+grep '#define ForRelease 0' MobileCydia.mm &>/dev/null && echo -n '~srk'
+echo