sysroot.sim
lex.cy.cpp
/cycript
-Trampoline.t.hpp
Bridge.hpp
package
aclocal.m4
+++ /dev/null
-/* 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;
#ifndef CYCRIPT_EXCEPTION_HPP
#define CYCRIPT_EXCEPTION_HPP
+#include <cstdlib>
+
#ifdef CY_EXECUTE
#include <JavaScriptCore/JSBase.h>
#endif
#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_)); \
/* }}} */
#include <Foundation/Foundation.h>
+#include <dlfcn.h>
#include <pthread.h>
#include <unistd.h>
#include <sstream>
_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_;
**/
/* }}} */
-#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);
}
+++ /dev/null
-/* 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
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
@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) \
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 \
@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
+++ /dev/null
-/* 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_;
-};
+++ /dev/null
-/* 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());
-}
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
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>
+++ /dev/null
-#!/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