]> git.saurik.com Git - cycript.git/commitdiff
Port to Substrate: use cynject (this is GPL-safe).
authorJay Freeman (saurik) <saurik@saurik.com>
Wed, 28 Oct 2015 12:18:00 +0000 (05:18 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Wed, 28 Oct 2015 13:57:28 +0000 (06:57 -0700)
13 files changed:
.gitignore
Baton.hpp [deleted file]
Exception.hpp
Handler.mm
Mach/Inject.cpp
Mach/Memory.hpp [deleted file]
Makefile.am
Makefile.in
Trampoline.hpp [deleted file]
Trampoline.t.cpp [deleted file]
apple.mk
control.in
trampoline.sh [deleted file]

index c5806c147e2ff97e2a212080e96cc1c5bf80e567..142ae537e45fcc647798751bb08b0dae49ce1ac9 100644 (file)
@@ -27,7 +27,6 @@ sysroot.ios
 sysroot.sim
 lex.cy.cpp
 /cycript
-Trampoline.t.hpp
 Bridge.hpp
 package
 aclocal.m4
diff --git a/Baton.hpp b/Baton.hpp
deleted file mode 100644 (file)
index d7de13d..0000000
--- a/Baton.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
-*/
-
-/* GNU Affero General Public License, Version 3 {{{ */
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 Affero General Public License for more details.
-
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-/* }}} */
-
-#include "Standard.hpp"
-
-#include <dlfcn.h>
-#include <mach/mach.h>
-#include <sys/types.h>
-
-struct Baton {
-    uint64_t dyld;
-    pid_t pid;
-    char error[1024];
-    char library[];
-} _packed;
index 889f92fa277d4392da4d28dc90664334433b79bb..67feb2e91f0ced37bc96a5f455c06809ca9a6058 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef CYCRIPT_EXCEPTION_HPP
 #define CYCRIPT_EXCEPTION_HPP
 
+#include <cstdlib>
+
 #ifdef CY_EXECUTE
 #include <JavaScriptCore/JSBase.h>
 #endif
@@ -101,12 +103,6 @@ static _finline bool CYContains(int value, size_t many, const int *okay) {
 #define _syscall(expr) \
     _syscall_(expr, 0, {})
 
-#define _krncall(expr) \
-    do { \
-        kern_return_t _krnstatus((expr)); \
-        _assert_("krncall", _krnstatus == KERN_SUCCESS, #expr, " [return=0x%x]", _krnstatus); \
-    } while (false)
-
 #define _sqlcall(expr) ({ \
     __typeof__(expr) _value = (expr); \
     _assert_("sqlcall", _value == 0 || _value >= 100 && _value < 200, #expr, " %u:%s", _value sqlite3_errmsg(database_)); \
index f4c87053eef0805e1401a088b7e3510dcd46656c..ebd96b9031c3c57de84ef110455c464144a5c974 100644 (file)
@@ -20,6 +20,7 @@
 /* }}} */
 
 #include <Foundation/Foundation.h>
+#include <dlfcn.h>
 #include <pthread.h>
 #include <unistd.h>
 #include <sstream>
@@ -140,23 +141,50 @@ extern "C" void CYHandleClient(int socket) {
     _assert(pthread_create(&client->thread_, NULL, &OnClient, client) == 0);
 }
 
-extern "C" void CYHandleServer(pid_t pid) {
+static void CYHandleProcess(pid_t pid) {
     CYInitializeDynamic();
 
-    int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0))); try {
-        struct sockaddr_un address;
-        memset(&address, 0, sizeof(address));
-        address.sun_family = AF_UNIX;
-        sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
-
-        _syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
-        CYHandleClient(socket);
-    } catch (const CYException &error) {
-        CYPool pool;
-        fprintf(stderr, "%s\n", error.PoolCString(pool));
-    }
+    int socket(_syscall(::socket(PF_UNIX, SOCK_STREAM, 0)));
+
+    struct sockaddr_un address;
+    memset(&address, 0, sizeof(address));
+    address.sun_family = AF_UNIX;
+    sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
+
+    _syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
+    CYHandleClient(socket);
 }
 
+extern "C" void CYHandleServer(pid_t pid) { try {
+    CYHandleProcess(pid);
+} catch (const CYException &error) {
+    CYPool pool;
+    fprintf(stderr, "%s\n", error.PoolCString(pool));
+} }
+
+extern "C" char *MSmain0(int argc, char *argv[]) { try {
+    _assert(argc == 2);
+    auto arg(argv[1]);
+
+    char *end;
+    pid_t pid(strtoul(arg, &end, 10));
+    _assert(end == arg + strlen(arg));
+
+    static void *handle(NULL);
+    if (handle == NULL) {
+        Dl_info info;
+        _assert(dladdr(reinterpret_cast<void *>(&MSmain0), &info) != 0);
+        handle = dlopen(info.dli_fname, RTLD_NOLOAD);
+    }
+
+    CYHandleProcess(pid);
+
+    return NULL;
+} catch (const CYException &error) {
+    CYPool pool;
+    return strdup(error.PoolCString(pool));
+} }
+
 struct CYServer {
     pthread_t thread_;
     uint16_t port_;
index d109cddb243cd6fadba749791841f736066a18d7..3e30ae56bcc501308b44d490fbe8e34e9bc9d00b 100644 (file)
 **/
 /* }}} */
 
-#include "TargetConditionals.h"
-#if TARGET_OS_IPHONE
-#undef __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
-#define __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ __IPHONE_5_0
-#endif
+#include <string>
 
 #include <dlfcn.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include <mach/mach.h>
-#include <mach/vm_map.h>
-#include <mach/mach_vm.h>
-
-#include <mach/machine/thread_status.h>
-
-#ifdef __arm__
-#include "Mach/Memory.hpp"
-#endif
 
-#include "Baton.hpp"
 #include "Exception.hpp"
 #include "Pooling.hpp"
-#include "Trampoline.t.hpp"
 
-extern "C" void CYHandleServer(pid_t);
+#if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
+#include <sys/fcntl.h>
+#include <sys/mman.h>
 
-extern "C" void *_dyld_get_all_image_infos();
+#include <mach-o/loader.h>
 
-void InjectLibrary(pid_t pid) {
-    Dl_info addr;
-    _assert(dladdr(reinterpret_cast<void *>(&CYHandleServer), &addr) != 0);
+#define CS_OPS_PIDOFFSET 6
 
-    size_t flength(strlen(addr.dli_fname));
-    char library[flength + 4 + 1];
-    memcpy(library, addr.dli_fname, flength);
-    library[flength] = '\0';
-    _assert(strcmp(library + flength - 6, ".dylib") == 0);
-#if !TARGET_OS_IPHONE
-    strcpy(library + flength - 6, "-###.dylib");
+extern "C" int csops(pid_t pid, unsigned int ops, void *useraddr, size_t usersize);
+extern "C" int proc_pidpath(int pid, void *buffer, uint32_t buffersize);
 #endif
 
-    mach_port_t self(mach_task_self()), task;
-    _krncall(task_for_pid(self, pid, &task));
+int main(int argc, char * const argv[], char const * const envp[]);
+extern "C" char *MSmain0(int argc, char *argv[]);
 
-    task_dyld_info info;
-#ifdef __arm__
-    union {
-        struct {
-            uint32_t all_image_info_addr;
-        } info_1;
+static std::string LibraryFor(void *address) {
+    Dl_info info;
+    _assert(dladdr(address, &info) != 0);
+    return info.dli_fname;
+}
 
-        struct {
-            uint32_t all_image_info_addr;
-            uint32_t all_image_info_size;
-            int32_t all_image_info_format;
-        } info32;
+template <typename Type_>
+Type_ *shift(Type_ *data, size_t size) {
+    return reinterpret_cast<Type_ *>(reinterpret_cast<uint8_t *>(data) + size);
+}
 
-        struct {
-            uint64_t all_image_info_addr;
-            uint64_t all_image_info_size;
-            int32_t all_image_info_format;
-        } info64;
-    } infoXX;
+void InjectLibrary(pid_t pid) {
+    auto cynject(LibraryFor(reinterpret_cast<void *>(&main)));
+    auto slash(cynject.rfind('/'));
+    _assert(slash != std::string::npos);
+    cynject = cynject.substr(0, slash) + "/cynject";
 
-    mach_msg_type_number_t count(sizeof(infoXX) / sizeof(natural_t));
-    _krncall(task_info(task, TASK_DYLD_INFO, reinterpret_cast<task_info_t>(&infoXX), &count));
+    auto library(LibraryFor(reinterpret_cast<void *>(&MSmain0)));
 
-    bool broken;
+#if defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
+    off_t offset;
+    _assert(csops(pid, CS_OPS_PIDOFFSET, &offset, sizeof(offset)) != -1);
 
-    switch (count) {
-        case sizeof(infoXX.info_1) / sizeof(natural_t):
-            broken = true;
-            info.all_image_info_addr = infoXX.info_1.all_image_info_addr;
-            info.all_image_info_size = 0;
-            info.all_image_info_format = TASK_DYLD_ALL_IMAGE_INFO_32;
-            break;
-        case sizeof(infoXX.info32) / sizeof(natural_t):
-            broken = true;
-            info.all_image_info_addr = infoXX.info32.all_image_info_addr;
-            info.all_image_info_size = infoXX.info32.all_image_info_size;
-            info.all_image_info_format = infoXX.info32.all_image_info_format;
-            break;
-        case sizeof(infoXX.info64) / sizeof(natural_t):
-            broken = false;
-            info.all_image_info_addr = infoXX.info64.all_image_info_addr;
-            info.all_image_info_size = infoXX.info64.all_image_info_size;
-            info.all_image_info_format = infoXX.info64.all_image_info_format;
-            break;
-        default:
-            _assert(false);
-    }
-#else
-    mach_msg_type_number_t count(TASK_DYLD_INFO_COUNT);
-    _krncall(task_info(task, TASK_DYLD_INFO, reinterpret_cast<task_info_t>(&info), &count));
-    _assert(count == TASK_DYLD_INFO_COUNT);
-#endif
-    _assert(info.all_image_info_addr != 0);
+    char path[PATH_MAX];
+    int writ(proc_pidpath(pid, path, sizeof(path)) != 0);
+    _assert(writ != 0);
 
-    thread_act_t thread;
-    _krncall(thread_create(task, &thread));
+    auto fd(_syscall(open(path, O_RDONLY)));
 
-    thread_state_t bottom;
-    thread_state_flavor_t flavor;
+    auto page(getpagesize());
+    auto size(page * 4);
+    auto map(_syscall(mmap(NULL, size, PROT_READ, MAP_SHARED, fd, offset)));
 
-#if defined (__i386__) || defined(__x86_64__)
-    x86_thread_state_t state;
-    memset(&state, 0, sizeof(state));
+    _syscall(close(fd)); // XXX: _scope
 
-    bottom = reinterpret_cast<thread_state_t>(&state);
-    flavor = MACHINE_THREAD_STATE;
-    count = MACHINE_THREAD_STATE_COUNT;
-#elif defined(__arm__) || defined(__arm64__)
-    arm_unified_thread_state_t state;
-    memset(&state, 0, sizeof(state));
+    auto header(reinterpret_cast<mach_header *>(map));
+    auto command(reinterpret_cast<load_command *>(header + 1));
 
-    switch (info.all_image_info_format) {
-        case TASK_DYLD_ALL_IMAGE_INFO_32:
-            bottom = reinterpret_cast<thread_state_t>(&state.ts_32);
-            flavor = ARM_THREAD_STATE;
-            count = ARM_THREAD_STATE_COUNT;
-            state.ash.flavor = ARM_THREAD_STATE32;
-            break;
-        case TASK_DYLD_ALL_IMAGE_INFO_64:
-            bottom = reinterpret_cast<thread_state_t>(&state.ts_64);
-            flavor = ARM_THREAD_STATE64;
-            count = ARM_THREAD_STATE64_COUNT + 1;
-            state.ash.flavor = ARM_THREAD_STATE64;
+    switch (header->magic) {
+        case MH_MAGIC_64:
+            command = shift(command, sizeof(uint32_t));
+        case MH_MAGIC:
             break;
         default:
             _assert(false);
     }
-#else
-    #error XXX: implement
-#endif
-
-    mach_msg_type_number_t read(count);
-    _krncall(thread_get_state(thread, flavor, bottom, &read));
-    _assert(read == count);
 
-    Trampoline *trampoline;
-    size_t align;
-    size_t push;
-
-#if defined(__i386__) || defined(__x86_64__)
-    switch (state.tsh.flavor) {
-        case i386_THREAD_STATE:
-            trampoline = &Trampoline_i386_;
-            align = 4;
-            push = 5;
-            break;
-        case x86_THREAD_STATE64:
-            trampoline = &Trampoline_x86_64_;
-            align = 8;
-            push = 2;
-            break;
-        default:
-            _assert(false);
-    }
-#elif defined(__arm__) || defined(__arm64__)
-    switch (state.ash.flavor) {
-        case ARM_THREAD_STATE32:
-            trampoline = &Trampoline_armv6_;
-            align = 4;
-            push = 0;
-            break;
-        case ARM_THREAD_STATE64:
-            trampoline = &Trampoline_arm64_;
-            align = 8;
-            push = 0;
-            break;
-        default:
-            _assert(false);
+    bool ios(false);
+    for (decltype(header->ncmds) i(0); i != header->ncmds; ++i) {
+        if (command->cmd == LC_VERSION_MIN_IPHONEOS)
+            ios = true;
+        command = shift(command, command->cmdsize);
     }
-#else
-    #error XXX: implement
-#endif
-
-    static const size_t Stack_(8 * 1024);
-    size_t length(strlen(library) + 1), depth(sizeof(Baton) + length);
-    depth = (depth + align + 1) / align * align;
-
-    CYPool pool;
-    uint8_t *local(pool.malloc<uint8_t>(depth));
-    Baton *baton(reinterpret_cast<Baton *>(local));
 
-    baton->dyld = info.all_image_info_addr;
-    baton->pid = getpid();
-    memset(baton->error, 0, sizeof(baton->error));
-    memcpy(baton->library, library, length);
+    _syscall(munmap(map, size)); // XXX: _scope
 
-    mach_vm_size_t size(depth + Stack_);
-    mach_vm_address_t stack;
-    _krncall(mach_vm_allocate(task, &stack, size, true));
+    auto length(library.size());
+    _assert(length >= 6);
+    length -= 6;
 
-    mach_vm_address_t data(stack + Stack_);
-    _krncall(mach_vm_write(task, data, reinterpret_cast<mach_vm_address_t>(baton), depth));
-
-    mach_vm_address_t code;
-    _krncall(mach_vm_allocate(task, &code, trampoline->size_, true));
-    _krncall(mach_vm_write(task, code, reinterpret_cast<vm_offset_t>(trampoline->data_), trampoline->size_));
-    _krncall(mach_vm_protect(task, code, trampoline->size_, false, VM_PROT_READ | VM_PROT_EXECUTE));
-
-    uint32_t frame[push];
-    if (sizeof(frame) != 0)
-        memset(frame, 0, sizeof(frame));
-
-#if defined(__i386__) || defined(__x86_64__)
-    switch (state.tsh.flavor) {
-        case i386_THREAD_STATE:
-            frame[1] = data;
-            state.uts.ts32.__eip = code + trampoline->entry_;
-            state.uts.ts32.__esp = stack + Stack_ - sizeof(frame);
-            break;
-        case x86_THREAD_STATE64:
-            state.uts.ts64.__rdi = data;
-            state.uts.ts64.__rip = code + trampoline->entry_;
-            state.uts.ts64.__rsp = stack + Stack_ - sizeof(frame);
-            break;
-        default:
-            _assert(false);
-    }
-#elif defined(__arm__) || defined(__arm64__)
-    switch (state.ash.flavor) {
-        case ARM_THREAD_STATE32:
-            state.ts_32.__r[0] = data;
-            state.ts_32.__pc = code + trampoline->entry_;
-            state.ts_32.__sp = stack + Stack_ - sizeof(frame);
-
-            if ((state.ts_32.__pc & 0x1) != 0) {
-                state.ts_32.__pc &= ~0x1;
-                state.ts_32.__cpsr |= 0x20;
-            }
-
-            break;
-
-        case ARM_THREAD_STATE64:
-            state.ts_64.__x[0] = data;
-            state.ts_64.__pc = code + trampoline->entry_;
-            state.ts_64.__sp = stack + Stack_ - sizeof(frame);
-            break;
-
-        default:
-            _assert(false);
-    }
-#else
-    #error XXX: implement
+    _assert(library.substr(length) == ".dylib");
+    library = library.substr(0, length);
+    library += ios ? "-sim" : "-sys";
+    library += ".dylib";
 #endif
 
-    if (sizeof(frame) != 0)
-        _krncall(mach_vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast<mach_vm_address_t>(frame), sizeof(frame)));
-
-    _krncall(thread_set_state(thread, flavor, bottom, read));
-    _krncall(thread_resume(thread));
-
-    loop: switch (kern_return_t status = thread_get_state(thread, flavor, bottom, &(read = count))) {
-        case KERN_SUCCESS:
-            usleep(10000);
-            goto loop;
-
-        case KERN_TERMINATED:
-        case MACH_SEND_INVALID_DEST:
-            break;
-
-        default:
-            _assert(false);
-    }
-
-    _krncall(mach_port_deallocate(self, thread));
-
-    mach_vm_size_t error(sizeof(baton->error));
-    _krncall(mach_vm_read_overwrite(task, data + offsetof(Baton, error), sizeof(baton->error), reinterpret_cast<mach_vm_address_t>(&baton->error), &error));
-    _assert(error == sizeof(baton->error));
-
-    if (baton->error[0] != '\0') {
-        baton->error[sizeof(baton->error) - 1] = '\0';
-        CYThrow("%s", baton->error);
-    }
-
-    _krncall(mach_vm_deallocate(task, code, trampoline->size_));
-    _krncall(mach_vm_deallocate(task, stack, size));
-
-    _krncall(mach_port_deallocate(self, task));
+    CYPool pool;
+    int status(system(pool.sprintf(1024, "%s %u %s %u", cynject.c_str(), pid, library.c_str(), getpid())));
+    _assert(status == 0);
 }
diff --git a/Mach/Memory.hpp b/Mach/Memory.hpp
deleted file mode 100644 (file)
index 6463215..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
-*/
-
-/* GNU Affero General Public License, Version 3 {{{ */
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 Affero General Public License for more details.
-
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-/* }}} */
-
-#ifndef MACH_MEMORY_HPP
-#define MACH_MEMORY_HPP
-
-static kern_return_t cy_vm_allocate(bool broken, vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags) {
-    if (!broken)
-        return mach_vm_allocate(target, address, size, flags);
-    vm_address_t address32(0);
-    kern_return_t value(vm_allocate(target, &address32, size, flags));
-    *address = address32;
-    return value;
-}
-
-#define mach_vm_allocate(a, b, c, d) \
-    cy_vm_allocate(broken, a, b, c, d)
-
-static kern_return_t cy_vm_deallocate(bool broken, vm_map_t target, mach_vm_address_t address, mach_vm_size_t size) {
-    if (!broken)
-        return mach_vm_deallocate(target, address, size);
-    return vm_deallocate(target, address, size);
-}
-
-#define mach_vm_deallocate(a, b, c) \
-    cy_vm_deallocate(broken, a, b, c)
-
-static kern_return_t cy_vm_protect(bool broken, vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, boolean_t set_maximum, vm_prot_t new_protection) {
-    if (!broken)
-        return mach_vm_protect(target_task, address, size, set_maximum, new_protection);
-    return vm_protect(target_task, address, size, set_maximum, new_protection);
-}
-
-#define mach_vm_protect(a, b, c, d, e) \
-    cy_vm_protect(broken, a, b, c, d, e)
-
-static kern_return_t cy_vm_read_overwrite(bool broken, vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize) {
-    if (!broken)
-        return mach_vm_read_overwrite(target_task, address, size, data, outsize);
-    vm_size_t outsize32(*outsize);
-    kern_return_t value(vm_read_overwrite(target_task, address, data, size, &outsize32));
-    *outsize = outsize32;
-    return value;
-}
-
-#define mach_vm_read_overwrite(a, b, c, d, e) \
-    cy_vm_read_overwrite(broken, a, b, c, d, e)
-
-static kern_return_t cy_vm_write(bool broken, vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt) {
-    if (!broken)
-        return mach_vm_write(target_task, address, data, dataCnt);
-    return vm_write(target_task, address, data, dataCnt);
-}
-
-#define mach_vm_write(a, b, c, d) \
-    cy_vm_write(broken, a, b, c, d)
-
-#endif//MACH_MEMORY_HPP
index 351fef38ac47758b0e1bc45670409596c21c1d29..c3679bc10de93510c4577531b8f9daae85fc0b58 100644 (file)
@@ -86,23 +86,7 @@ libcycript_la_SOURCES += Handler.mm
 
 if CY_CONSOLE
 cycript_SOURCES += Mach/Inject.cpp
-
 AM_CPPFLAGS += -DCY_ATTACH
-
-Mach/Inject.$(OBJEXT): Trampoline.t.hpp
-
-CLEANFILES += Trampoline.t.lo
-Trampoline.t.lo: Trampoline.t.cpp Trampoline.hpp Baton.hpp Standard.hpp
-       $(LTCXXCOMPILE) $(CY_ARCH) -c -o $@ $< -fno-stack-protector -O0
-
-CLEANFILES += libTrampoline.t.la
-libTrampoline.t.la: Trampoline.t.lo
-       $(CXXLINK) $(CY_ARCH) -rpath $(libdir) $^
-
-CLEANFILES += Trampoline.t.hpp
-Trampoline.t.hpp: libTrampoline.t.la trampoline.sh
-       $(srcdir)/trampoline.sh $@ .libs/libTrampoline.t.dylib Trampoline $(SED) $(LIPO) $(NM) $(OTOOL)
-       ! grep '## symbol stub for:' $@
 endif
 endif
 
index 9cbe866e9e91d3531f2135c926f881e904b4ade1..ee11ff8814aaa3ccc722a0382cb507e87d28f36d 100644 (file)
@@ -115,9 +115,6 @@ host_triplet = @host@
 @CY_MACH_TRUE@am__append_12 = Handler.mm
 @CY_CONSOLE_TRUE@@CY_MACH_TRUE@am__append_13 = Mach/Inject.cpp
 @CY_CONSOLE_TRUE@@CY_MACH_TRUE@am__append_14 = -DCY_ATTACH
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@am__append_15 = Trampoline.t.lo \
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        libTrampoline.t.la \
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        Trampoline.t.hpp
 subdir = .
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(top_srcdir)/configure $(am__configure_deps) \
@@ -530,9 +527,9 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = subdir-objects
-CLEANFILES = $(am__append_5) $(am__append_15) Cycript.yy Cycript.l \
-       lex.cy.cpp Cycript.tab.cc Cycript.tab.hh location.hh \
-       position.hh stack.hh Cycript.output
+CLEANFILES = $(am__append_5) Cycript.yy Cycript.l lex.cy.cpp \
+       Cycript.tab.cc Cycript.tab.hh location.hh position.hh stack.hh \
+       Cycript.output
 SUBDIRS = 
 ACLOCAL_AMFLAGS = -I m4
 AM_CPPFLAGS = -I$(srcdir)/include -DYYDEBUG=1 -include config.h \
@@ -1328,15 +1325,6 @@ uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES
 @CY_EXECUTE_TRUE@      $(srcdir)/Bridge.sh $< >$@
 @CY_EXECUTE_TRUE@Bridge.hpp: Bridge.gperf
 @CY_EXECUTE_TRUE@      $(GPERF) $< | $(SED) -e 's/defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__/0/' >$@
-
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@Mach/Inject.$(OBJEXT): Trampoline.t.hpp
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@Trampoline.t.lo: Trampoline.t.cpp Trampoline.hpp Baton.hpp Standard.hpp
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        $(LTCXXCOMPILE) $(CY_ARCH) -c -o $@ $< -fno-stack-protector -O0
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@libTrampoline.t.la: Trampoline.t.lo
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        $(CXXLINK) $(CY_ARCH) -rpath $(libdir) $^
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@Trampoline.t.hpp: libTrampoline.t.la trampoline.sh
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        $(srcdir)/trampoline.sh $@ .libs/libTrampoline.t.dylib Trampoline $(SED) $(LIPO) $(NM) $(OTOOL)
-@CY_CONSOLE_TRUE@@CY_MACH_TRUE@        ! grep '## symbol stub for:' $@
 Cycript.yy: Cycript.yy.in
        $(srcdir)/Filter.sh <$< >$@ $(filters)
 Cycript.l: Cycript.l.in
diff --git a/Trampoline.hpp b/Trampoline.hpp
deleted file mode 100644 (file)
index 23ad45c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
-*/
-
-/* GNU Affero General Public License, Version 3 {{{ */
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 Affero General Public License for more details.
-
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-/* }}} */
-
-struct Trampoline {
-    const unsigned char *data_;
-    size_t size_;
-    size_t entry_;
-};
diff --git a/Trampoline.t.cpp b/Trampoline.t.cpp
deleted file mode 100644 (file)
index 5a51be0..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2014  Jay Freeman (saurik)
-*/
-
-/* GNU Affero General Public License, Version 3 {{{ */
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 Affero General Public License for more details.
-
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-**/
-/* }}} */
-
-#include <TargetConditionals.h>
-#if defined(__arm__) || defined(__arm64__)
-#undef TARGET_IPHONE_SIMULATOR
-#define TARGET_IPHONE_SIMULATOR 1
-#endif
-#define _PTHREAD_ATTR_T
-#include <pthread_internals.h>
-#if defined(__arm__) || defined(__arm64__)
-#undef TARGET_IPHONE_SIMULATOR
-#endif
-
-#include <mach-o/dyld.h>
-#include <mach-o/dyld_images.h>
-#include <mach-o/loader.h>
-#include <mach-o/nlist.h>
-
-#include "Standard.hpp"
-#include "Baton.hpp"
-
-static void $bzero(void *data, size_t size) {
-    char *bytes(reinterpret_cast<char *>(data));
-    for (size_t i(0); i != size; ++i)
-        bytes[i] = 0;
-}
-
-__attribute__((__unused__))
-static void $memcpy(char *dst, const char *src, size_t size) {
-    for (size_t i(0); i != size; ++i)
-        dst[i] = src[i];
-}
-
-static int $strcmp(const char *lhs, const char *rhs) {
-    while (*lhs == *rhs) {
-        if (*lhs == '\0')
-            return 0;
-        ++lhs, ++rhs;
-    } return *lhs < *rhs ? -1 : 1;
-}
-
-static void $strlcpy(char *dst, const char *src, size_t size) {
-    if (src == NULL)
-        src = "(null)";
-    if (size == 0)
-        return;
-    size_t i(0);
-    while (i != size - 1) {
-        char value(src[i]);
-        if (value == '\0')
-            break;
-        dst[i++] = value;
-    } dst[i] = '\0';
-}
-
-__attribute__((__unused__))
-static char *$strstr(const char *haystack, const char *needle) {
-    if (*needle == '\0')
-        return NULL;
-    for (; *haystack != '\0'; ++haystack)
-        for (size_t i(0); ; ++i)
-            if (needle[i] == '\0')
-                return const_cast<char *>(haystack);
-            else if (needle[i] != haystack[i])
-                break;
-    return NULL;
-}
-
-__attribute__((__unused__))
-static size_t $strlen(const char *data) {
-    for (size_t i(0); ; ++i)
-        if (data[i] == '\0')
-            return i;
-}
-
-__attribute__((__unused__))
-static void $snprintfp(char *dst, size_t size, const void *pointer) {
-    uintptr_t value(reinterpret_cast<uintptr_t>(pointer));
-    char buffer[32];
-    char *end(buffer + sizeof(buffer));
-    *--end = '\0';
-    if (value == 0)
-        *--end = '0';
-    else do {
-        unsigned digit(value & 0xf);
-        value >>= 4;
-        *--end = (digit < 10 ? '0' : 'a' - 10) + digit;
-    } while (value != 0);
-    *--end = 'x';
-    *--end = '0';
-    $strlcpy(dst, end, size);
-}
-
-#ifdef __LP64__
-typedef struct mach_header_64 mach_header_xx;
-typedef struct nlist_64 nlist_xx;
-typedef struct segment_command_64 segment_command_xx;
-
-static const uint32_t LC_SEGMENT_XX = LC_SEGMENT_64;
-static const uint32_t MH_MAGIC_XX = MH_MAGIC_64;
-#else
-typedef struct mach_header mach_header_xx;
-typedef struct nlist nlist_xx;
-typedef struct segment_command segment_command_xx;
-
-static const uint32_t LC_SEGMENT_XX = LC_SEGMENT;
-static const uint32_t MH_MAGIC_XX = MH_MAGIC;
-#endif
-
-#define forlc(command, mach, lc, type) \
-    if (const struct load_command *load_commands = reinterpret_cast<const struct load_command *>(mach + 1)) \
-        if (const struct load_command *lcp = load_commands) \
-            for (uint32_t i(0); i != mach->ncmds; ++i, lcp = reinterpret_cast<const struct load_command *>(reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize)) \
-                if ( \
-                    lcp->cmdsize % sizeof(long) != 0 || lcp->cmdsize <= 0 || \
-                    reinterpret_cast<const uint8_t *>(lcp) + lcp->cmdsize > reinterpret_cast<const uint8_t *>(load_commands) + mach->sizeofcmds \
-                ) \
-                    break; \
-                else if (lcp->cmd != lc) \
-                    continue; \
-                else if (lcp->cmdsize < sizeof(type)) \
-                    break; \
-                else if (const type *command = reinterpret_cast<const type *>(lcp))
-
-static const mach_header_xx *Library(struct dyld_all_image_infos *infos, const char *name) {
-    for (uint32_t i(0); i != infos->infoArrayCount; ++i) {
-        const dyld_image_info &info(infos->infoArray[i]);
-        const mach_header_xx *mach(reinterpret_cast<const mach_header_xx *>(info.imageLoadAddress));
-        if (mach->magic != MH_MAGIC_XX)
-            continue;
-
-        const char *path(info.imageFilePath);
-        forlc (dylib, mach, LC_ID_DYLIB, dylib_command)
-            path = reinterpret_cast<const char *>(dylib) + dylib->dylib.name.offset;
-        if ($strcmp(path, name) != 0)
-            continue;
-
-        return mach;
-    }
-
-    return NULL;
-}
-
-static void *Symbol(const mach_header_xx *mach, const char *name) {
-    const struct symtab_command *stp(NULL);
-    forlc (command, mach, LC_SYMTAB, struct symtab_command)
-        stp = command;
-    if (stp == NULL)
-        return NULL;
-
-    size_t slide(_not(size_t));
-    const nlist_xx *symbols(NULL);
-    const char *strings(NULL);
-
-    forlc (segment, mach, LC_SEGMENT_XX, segment_command_xx) {
-        if (segment->fileoff == 0)
-            slide = reinterpret_cast<size_t>(mach) - segment->vmaddr;
-        if (stp->symoff >= segment->fileoff && stp->symoff < segment->fileoff + segment->filesize)
-            symbols = reinterpret_cast<const nlist_xx *>(stp->symoff - segment->fileoff + segment->vmaddr + slide);
-        if (stp->stroff >= segment->fileoff && stp->stroff < segment->fileoff + segment->filesize)
-            strings = reinterpret_cast<const char *>(stp->stroff - segment->fileoff + segment->vmaddr + slide);
-    }
-
-    if (slide == _not(size_t) || symbols == NULL || strings == NULL)
-        return NULL;
-
-    for (size_t i(0); i != stp->nsyms; ++i) {
-        const nlist_xx *symbol(&symbols[i]);
-        if (symbol->n_un.n_strx == 0 || (symbol->n_type & N_STAB) != 0)
-            continue;
-
-        const char *nambuf(strings + symbol->n_un.n_strx);
-        if ($strcmp(name, nambuf) != 0)
-            continue;
-
-        uintptr_t value(symbol->n_value);
-        if (value == 0)
-            continue;
-
-#ifdef __arm__
-        if ((symbol->n_desc & N_ARM_THUMB_DEF) != 0)
-            value |= 0x00000001;
-#endif
-
-        value += slide;
-        return reinterpret_cast<void *>(value);
-    }
-
-    return NULL;
-}
-
-template <typename Type_>
-static _finline void cyset(Type_ &function, const char *name, const mach_header_xx *mach) {
-    function = reinterpret_cast<Type_>(Symbol(mach, name));
-}
-
-static _finline const mach_header_xx *Library(Baton *baton, const char *name) {
-    struct dyld_all_image_infos *infos(reinterpret_cast<struct dyld_all_image_infos *>(baton->dyld));
-    return Library(infos, name);
-}
-
-#if defined(__i386__) || defined(__x86_64__)
-static bool Simulator(struct dyld_all_image_infos *infos) {
-    for (uint32_t i(0); i != infos->infoArrayCount; ++i) {
-        const dyld_image_info &info(infos->infoArray[i]);
-        const char *path(info.imageFilePath);
-        if ($strstr(path, "/SDKs/iPhoneSimulator") != NULL)
-            return true;
-    } return false;
-}
-
-static bool Simulator(Baton *baton) {
-    struct dyld_all_image_infos *infos(reinterpret_cast<struct dyld_all_image_infos *>(baton->dyld));
-    return Simulator(infos);
-}
-#endif
-
-void *Routine(void *arg) {
-    Baton *baton(reinterpret_cast<Baton *>(arg));
-
-    const mach_header_xx *dyld(NULL);
-    if (dyld == NULL)
-        dyld = Library(baton, "/usr/lib/system/libdyld.dylib");
-    if (dyld == NULL)
-        dyld = Library(baton, "/usr/lib/libSystem.B.dylib");
-
-    char *(*$dlerror)();
-    cyset($dlerror, "_dlerror", dyld);
-
-    void *(*$dlopen)(const char *, int);
-    cyset($dlopen, "_dlopen", dyld);
-
-#if defined(__i386__) || defined(__x86_64__)
-    size_t length($strlen(baton->library));
-    if (length >= 10 && $strcmp(baton->library + length - 10, "-###.dylib") == 0)
-        $memcpy(baton->library + length - 10, Simulator(baton) ? "-sim" : "-sys", 4);
-#endif
-
-    void *handle($dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL));
-    if (handle == NULL) {
-        $strlcpy(baton->error, $dlerror(), sizeof(baton->error));
-        return NULL;
-    }
-
-    void *(*$dlsym)(void *, const char *);
-    cyset($dlsym, "_dlsym", dyld);
-
-    void (*CYHandleServer)(pid_t);
-    CYHandleServer = reinterpret_cast<void (*)(pid_t)>($dlsym(handle, "CYHandleServer"));
-    if (CYHandleServer == NULL) {
-        $strlcpy(baton->error, $dlerror(), sizeof(baton->error));
-        return NULL;
-    }
-
-    CYHandleServer(baton->pid);
-    return NULL;
-}
-
-extern "C" void Start(Baton *baton) {
-    struct _pthread self;
-    $bzero(&self, sizeof(self));
-
-    const mach_header_xx *pthread(NULL);
-    if (pthread == NULL)
-        pthread = Library(baton, "/usr/lib/system/libsystem_pthread.dylib");
-    if (pthread == NULL)
-        pthread = Library(baton, "/usr/lib/system/libsystem_c.dylib");
-    if (pthread == NULL)
-        pthread = Library(baton, "/usr/lib/libSystem.B.dylib");
-
-    void (*$__pthread_set_self)(void **);
-    cyset($__pthread_set_self, "___pthread_set_self", pthread);
-
-    self.tsd[0] = &self;
-    $__pthread_set_self(&self.tsd[0]);
-
-    int (*$pthread_attr_init)(pthread_attr_t *);
-    cyset($pthread_attr_init, "_pthread_attr_init", pthread);
-
-#if 0
-    pthread_attr_t attr;
-    $pthread_attr_init(&attr);
-
-    int (*$pthread_attr_setdetachstate)(pthread_attr_t *, int);
-    cyset($pthread_attr_setdetachstate, "_pthread_attr_setdetachstate", pthread);
-
-    $pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-#endif
-
-    int (*$pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
-    cyset($pthread_create, "_pthread_create", pthread);
-
-    pthread_t thread;
-    $pthread_create(&thread, NULL, &Routine, baton);
-
-#if 0
-    int (*$pthread_attr_destroy)(pthread_attr_t *);
-    cyset($pthread_attr_destroy, "_pthread_attr_destroy", pthread);
-
-    $pthread_attr_destroy(&attr);
-#endif
-
-    int (*$pthread_join)(pthread_t, void **);
-    cyset($pthread_join, "_pthread_join", pthread);
-
-    void *status;
-    $pthread_join(thread, &status);
-
-    const mach_header_xx *kernel(NULL);
-    if (kernel == NULL)
-        kernel = Library(baton, "/usr/lib/system/libsystem_kernel.dylib");
-    if (kernel == NULL)
-        kernel = Library(baton, "/usr/lib/libSystem.B.dylib");
-
-    mach_port_t (*$mach_thread_self)();
-    cyset($mach_thread_self, "_mach_thread_self", kernel);
-
-    kern_return_t (*$thread_terminate)(thread_act_t);
-    cyset($thread_terminate, "_thread_terminate", kernel);
-
-    $thread_terminate($mach_thread_self());
-}
index bfaf2207dddd0c1677f6e11418afb7d848706f9e..2233aed1ff3135bc75254a3818df2e6f9b6c4f62 100644 (file)
--- a/apple.mk
+++ b/apple.mk
@@ -44,6 +44,7 @@ framework += Headers/Cycript.h
 framework := $(foreach os,ios osx,$(foreach file,$(framework),Cycript.$(os)/Cycript.framework/$(file)))
 
 links := 
+links += Cycript.lib/cynject
 links += Cycript.lib/libsubstrate.dylib
 links += Cycript.lib/cycript0.9
 
index e286226b6b0aa8fdd2b3992c3efd12f0b0a02afe..dfcb78c1880a4dfb5b58e9746c248004f43f5214 100644 (file)
@@ -6,7 +6,7 @@ Architecture: iphoneos-arm
 Version: #
 Description: runtime execution server and disassembler
 Name: Cycript
-Depends: readline, adv-cmds
+Depends: readline, adv-cmds, mobilesubstrate (>= 0.9.6100)
 Pre-Depends: dpkg (>= 1.14.25-8)
 Breaks: cydget (<< 0.9.4008)
 Author: Jay Freeman (saurik) <saurik@saurik.com>
diff --git a/trampoline.sh b/trampoline.sh
deleted file mode 100755 (executable)
index 0975a5d..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env bash
-
-# Cycript - Optimizing JavaScript Compiler/Runtime
-# Copyright (C) 2009-2014  Jay Freeman (saurik)
-
-# GNU Affero General Public License, Version 3 {{{
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-# }}}
-
-set -e
-
-hpp=$1
-object=$2
-name=$3
-sed=$4
-lipo=$5
-nm=$6
-otool=$7
-
-exec >"${hpp}"
-
-detailed=$("${lipo}" -detailed_info "${object}")
-
-regex=$'\nNon-fat file: .* is architecture: (.*)'
-if [[ ${detailed} =~ ${regex} ]]; then
-    archs=(${BASH_REMATCH[1]})
-    unset detailed
-else
-    archs=($(echo "${detailed}" | "${sed}" -e '/^architecture / { s/^architecture //; p; }; d;'))
-fi
-
-echo '#include "Trampoline.hpp"'
-
-for arch in "${archs[@]}"; do
-    if [[ "${detailed+@}" ]]; then
-        offset=$(echo "${detailed}" | "${sed}" -e '
-            /^architecture / { x; s/.*/0/; x; };
-            /^architecture '${arch}'$/ { x; s/.*/1/; x; };
-            x; /^1$/ { x; /^ *offset / { s/^ *offset //; p; }; x; }; x;
-            d;
-        ')
-    else
-        offset=0
-    fi
-
-    file=($("${otool}" -arch "${arch}" -l "${object}" | "${sed}" -e '
-        x; /^1$/ { x;
-            /^ *fileoff / { s/^.* //; p; };
-            /^ *filesize / { s/^.* //; p; };
-        x; }; x;
-
-        /^ *cmd LC_SEGMENT/ { x; s/.*/1/; x; };
-
-        d;
-    '))
-
-    fileoff=${file[0]}
-    filesize=${file[1]}
-
-    echo
-    echo "static const unsigned char ${name}_${arch}_data_[] = {"
-
-    LANG=C od -v -t x1 -t c -j "$((offset + fileoff))" -N "${filesize}" "${object}" | "${sed}" -e '
-        /^[0-7]/ ! {
-            s@^        @//  @;
-            s/\(....\)/ \1/g;
-            s@^ // @//@;
-            s/ *$/,/;
-        };
-
-        /^[0-7]/ {
-            s/^[^ ]*//;
-            s/  */ /g;
-            s/^ *//;
-            s/ $//;
-            s/ /,/g;
-            s/\([^,][^,]\)/0x\1/g;
-            s/$/,/;
-            /^,$/ ! { s/^/    /g; p; }; d;
-        };
-    '
-
-    echo "};"
-
-    echo
-    entry=$("${nm}" -arch "${arch}" "${object}" | "${sed}" -e '/ _Start$/ { s/ .*//; p; }; d;')
-    entry=${entry##*(0)}
-    echo "static size_t ${name}_${arch}_entry_ = 0x${entry:=0};"
-
-    echo
-    echo "/*"
-    "${otool}" -arch "${arch}" -vVt "${object}"
-    echo "*/"
-
-    echo
-    echo "_disused static Trampoline ${name}_${arch}_ = {"
-    echo "    ${name}_${arch}_data_,"
-    echo "    sizeof(${name}_${arch}_data_),"
-    echo "    ${name}_${arch}_entry_,"
-    echo "};"
-
-done