From 9d79cefcbed6e10f562709ad1b6ec9ac085cd3eb Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 22 Jun 2013 17:24:30 -0700 Subject: [PATCH 1/1] Correct all blocking 32/64-bit incompatibilities. --- Baton.hpp | 4 +++- Console.cpp | 4 ++-- Handler.mm | 6 +++--- Mach/Inject.cpp | 54 +++++++++++++++++++++++++++---------------------- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/Baton.hpp b/Baton.hpp index 8607893..48d103d 100644 --- a/Baton.hpp +++ b/Baton.hpp @@ -19,6 +19,8 @@ **/ /* }}} */ +#include "Standard.hpp" + #include #include #include @@ -27,4 +29,4 @@ struct Baton { mach_vm_address_t dyld; pid_t pid; char library[]; -}; +} _packed; diff --git a/Console.cpp b/Console.cpp index c2a8761..e955311 100644 --- a/Console.cpp +++ b/Console.cpp @@ -116,7 +116,7 @@ void Setup(CYOutput &out, CYDriver &driver, CYOptions &options) { static CYUTF8String Run(CYPool &pool, int client, CYUTF8String code) { const char *json; - size_t size; + uint32_t size; if (client == -1) { mode_ = Running; @@ -137,7 +137,7 @@ static CYUTF8String Run(CYPool &pool, int client, CYUTF8String code) { CYSendAll(client, code.data, code.size); mode_ = Waiting; CYRecvAll(client, &size, sizeof(size)); - if (size == _not(size_t)) + if (size == _not(uint32_t)) json = NULL; else { char *temp(new(pool) char[size + 1]); diff --git a/Handler.mm b/Handler.mm index c1e9693..39624e3 100644 --- a/Handler.mm +++ b/Handler.mm @@ -89,7 +89,7 @@ struct CYClient : dispatch = false; for (;;) { - size_t size; + uint32_t size; if (!CYRecvAll(socket_, &size, sizeof(size))) return; @@ -107,7 +107,7 @@ struct CYClient : const char *json; if (parser.parse() != 0 || !driver.errors_.empty()) { json = NULL; - size = _not(size_t); + size = _not(uint32_t); } else { NSAutoreleasePool *ar = [[NSAutoreleasePool alloc] init]; @@ -125,7 +125,7 @@ struct CYClient : else [client execute:value]; json = execute.data_; - size = json == NULL ? _not(size_t) : strlen(json); + size = json == NULL ? _not(uint32_t) : strlen(json); [ar release]; } diff --git a/Mach/Inject.cpp b/Mach/Inject.cpp index a6dcf9f..c629939 100644 --- a/Mach/Inject.cpp +++ b/Mach/Inject.cpp @@ -20,7 +20,9 @@ /* }}} */ #include + #include +#include #include @@ -36,17 +38,6 @@ void InjectLibrary(pid_t pid) { const char *library(CY_LIBRARY); - static const size_t Stack_(8 * 1024); - size_t length(strlen(library) + 1), depth(sizeof(Baton) + length); - depth = (depth + sizeof(uintptr_t) + 1) / sizeof(uintptr_t) * sizeof(uintptr_t); - - CYPool pool; - uint8_t *local(pool.malloc(depth)); - Baton *baton(reinterpret_cast(local)); - - baton->pid = getpid(); - memcpy(baton->library, library, length); - mach_port_t self(mach_task_self()), task; _krncall(task_for_pid(self, pid, &task)); @@ -57,14 +48,6 @@ void InjectLibrary(pid_t pid) { _krncall(task_info(task, TASK_DYLD_INFO, reinterpret_cast(&info), &count)); _assert(count == TASK_DYLD_INFO_COUNT); _assert(info.all_image_info_addr != 0); - baton->dyld = info.all_image_info_addr; - - vm_size_t size(depth + Stack_); - vm_address_t stack; - _krncall(vm_allocate(task, &stack, size, true)); - - vm_address_t data(stack + Stack_); - _krncall(vm_write(task, data, reinterpret_cast(baton), depth)); thread_act_t thread; _krncall(thread_create(task, &thread)); @@ -88,16 +71,19 @@ void InjectLibrary(pid_t pid) { _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: @@ -105,15 +91,35 @@ void InjectLibrary(pid_t pid) { } #elif defined(__arm__) trampoline = &Trampoline_armv6_; + align = 4; push = 0; #else #error XXX: implement #endif - vm_address_t code; - _krncall(vm_allocate(task, &code, trampoline->size_, true)); - _krncall(vm_write(task, code, reinterpret_cast(trampoline->data_), trampoline->size_)); - _krncall(vm_protect(task, code, trampoline->size_, false, VM_PROT_READ | VM_PROT_EXECUTE)); + 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(depth)); + Baton *baton(reinterpret_cast(local)); + + baton->dyld = info.all_image_info_addr; + baton->pid = getpid(); + memcpy(baton->library, library, length); + + mach_vm_size_t size(depth + Stack_); + mach_vm_address_t stack; + _krncall(mach_vm_allocate(task, &stack, size, true)); + + mach_vm_address_t data(stack + Stack_); + _krncall(mach_vm_write(task, data, reinterpret_cast(baton), depth)); + + mach_vm_address_t code; + _krncall(mach_vm_allocate(task, &code, trampoline->size_, true)); + _krncall(mach_vm_write(task, code, reinterpret_cast(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) @@ -148,7 +154,7 @@ void InjectLibrary(pid_t pid) { #endif if (sizeof(frame) != 0) - _krncall(vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame))); + _krncall(mach_vm_write(task, stack + Stack_ - sizeof(frame), reinterpret_cast(frame), sizeof(frame))); _krncall(thread_set_state(thread, flavor, reinterpret_cast(&state), count)); _krncall(thread_resume(thread)); -- 2.45.2