diff options
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | generated/darwin-inject-asm.S (renamed from lib/darwin/inject-asm.S) | 0 | ||||
-rw-r--r-- | lib/darwin/inject-asm-raw.c | 18 | ||||
-rw-r--r-- | lib/darwin/inject.c | 15 | ||||
-rw-r--r-- | lib/substitute-internal.h | 6 | ||||
-rw-r--r-- | test/test-inject.c | 2 |
6 files changed, 35 insertions, 31 deletions
@@ -5,7 +5,7 @@ ARCH := -arch x86_64 XCFLAGS := -O3 -Wall -Wextra -Werror -Ilib $(ARCH) override CC := $(CC) $(XCFLAGS) $(CFLAGS) override CXX := $(CXX) $(XCFLAGS) $(CFLAGS) -fno-exceptions -fno-asynchronous-unwind-tables -LIB_LDFLAGS := -lobjc -dynamiclib -fvisibility=hidden -install_name /usr/lib/libsubstitute.dylib +LIB_LDFLAGS := -lobjc -dynamiclib -fvisibility=hidden -install_name /usr/lib/libsubstitute.dylib -dead_strip IMAON2 := /Users/comex/c/imaon2 GEN_JS := node --harmony --harmony_arrow_functions $(IMAON2)/tables/gen.js @@ -30,6 +30,8 @@ $(eval $(call do_prefix,arm64,,AArch64)) out/%.o: lib/%.c Makefile $(HEADERS) @mkdir -p $(dir $@) $(CC) -fvisibility=hidden -std=c11 -c -o $@ $< +out/%.o: generated/%.S Makefile $(HEADERS) + $(CC) -fvisibility=hidden -c -o $@ $< out/%.o: lib/%.S Makefile $(HEADERS) @mkdir -p $(dir $@) $(CC) -fvisibility=hidden -c -o $@ $< @@ -39,14 +41,14 @@ out/transform-dis.o: $(GENERATED) LIB_OBJS := \ out/darwin/find-syms.o \ out/darwin/inject.o \ - out/darwin/inject-asm.o \ out/darwin/interpose.o \ out/darwin/objc-asm.o \ out/darwin/objc.o \ out/darwin/read.o \ out/darwin/substrate-compat.o \ out/jump-dis.o \ - out/transform-dis.o + out/transform-dis.o \ + out/darwin-inject-asm.o out/libsubstitute.dylib: $(LIB_OBJS) $(CC) -o $@ $(LIB_OBJS) $(LIB_LDFLAGS) @@ -66,22 +68,13 @@ out/inject-asm-raw-arm.o: lib/darwin/inject-asm-raw.c Makefile out/inject-asm-raw-arm64.o: lib/darwin/inject-asm-raw.c Makefile $(IACLANG) -arch arm64 -o $@ $< IAR_BINS := out/inject-asm-raw-x86_64.bin out/inject-asm-raw-i386.bin out/inject-asm-raw-arm.bin out/inject-asm-raw-arm64.bin -out/inject-asm.S: $(IAR_BINS) Makefile - (echo ".align 12"; \ - echo ".globl _inject_page_start"; \ - echo "_inject_page_start:"; \ - for i in x86_64 i386 arm arm64; do \ - echo ".align 2"; \ - echo ".globl _inject_start_$$i"; \ - echo "_inject_start_$$i:"; \ - printf ".byte "; \ - xxd -i < out/inject-asm-raw-$$i.bin | xargs echo; \ - done) > $@ || rm -f $@ +out/inject-asm.S: $(IAR_BINS) Makefile script/gen-inject-asm.sh + ./script/gen-inject-asm.sh > $@ || rm -f $@ define define_test out/test-$(1): test/test-$(2).[cm]* $(HEADERS) $(GENERATED) Makefile out/libsubstitute.dylib $(3) -g -o $$@ $$< -Ilib -Isubstrate -Lout -lsubstitute - ldid -Sent.plist $$@ + lipo -info $$@ | grep -q arm && ldid -Sent.plist $$@ || true install_name_tool -change /usr/lib/libsubstitute.dylib '@executable_path/libsubstitute.dylib' $$@ all: out/test-$(1) endef @@ -101,7 +94,7 @@ $(eval $(call define_test,substrate,substrate,$(CXX) -std=c++98)) $(eval $(call define_test,imp-forwarding,imp-forwarding,$(CC) -std=c11 -framework Foundation -lobjc)) $(eval $(call define_test,objc-hook,objc-hook,$(CC) -std=c11 -framework Foundation -lsubstitute)) $(eval $(call define_test,interpose,interpose,$(CC) -std=c11 -lsubstitute)) -$(eval $(call define_test,inject,inject,$(CC) -std=c11 -lsubstitute)) +$(eval $(call define_test,inject,inject,$(CC) -std=c11 -lsubstitute out/darwin/inject.o out/darwin/read.o)) out/insns-arm.o: test/insns-arm.S Makefile clang -arch armv7 -c -o $@ $< diff --git a/lib/darwin/inject-asm.S b/generated/darwin-inject-asm.S index a909879..a909879 100644 --- a/lib/darwin/inject-asm.S +++ b/generated/darwin-inject-asm.S diff --git a/lib/darwin/inject-asm-raw.c b/lib/darwin/inject-asm-raw.c index bb92828..0519dc6 100644 --- a/lib/darwin/inject-asm-raw.c +++ b/lib/darwin/inject-asm-raw.c @@ -9,14 +9,16 @@ __attribute__((always_inline)) #if defined(__x86_64__) -static int syscall(long s, long a, long b, long c, long d, long _) { +static int syscall(long s, long a, long b, long c, long d, long e) { if (s < 0) s = -s | 1 << 24; else s |= 2 << 24; REG(s, rax); REG(a, rdi); REG(b, rsi); REG(c, rdx); REG(d, rcx); OREG(out, rax); - asm volatile("syscall" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); + asm volatile("push %1; syscall; pop %1" + : "=r"(out) + : "r"(e), "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); return out; } #elif defined(__i386__) @@ -36,17 +38,21 @@ static int syscall(long s, long a, long b, long c, long d, long e) { return out; } #elif defined(__arm__) -static int syscall(long s, long a, long b, long c, long d, long _) { +static int syscall(long s, long a, long b, long c, long d, long e) { REG(s, r12); REG(a, r0); REG(b, r1); REG(c, r2); REG(d, r3); OREG(out, r0); - asm volatile("svc #0x80" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); + asm volatile("push {%1}; svc #0x80; pop {%1}" + : "=r"(out) + : "r"(e), "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); return out; } #elif defined(__arm64__) -static int syscall(long s, long a, long b, long c, long d, long _) { +static int syscall(long s, long a, long b, long c, long d, long e) { REG(s, x16); REG(a, x0); REG(b, x1); REG(c, x2); REG(d, x3); OREG(out, x0); - asm volatile("svc #0x80" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); + asm volatile("str %1, [sp, #-0x10]!\n svc #0x80\n ldr %1, [sp], #0x10" + : "=r"(out) + : "r"(e), "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d)); return out; } #else diff --git a/lib/darwin/inject.c b/lib/darwin/inject.c index fb35a10..2c0c1ce 100644 --- a/lib/darwin/inject.c +++ b/lib/darwin/inject.c @@ -206,6 +206,7 @@ static int get_foreign_image_export(mach_port_t task, uint64_t hdr_addr, if (total_size > hdr_buf_size) { vm_deallocate(mach_task_self(), (vm_offset_t) hdr_buf, (vm_size_t) hdr_buf_size); hdr_buf_size = total_size; + hdr_buf = 0; kr = mach_vm_remap(mach_task_self(), &hdr_buf, hdr_buf_size, 0, VM_FLAGS_ANYWHERE, task, hdr_addr, /*copy*/ true, &cur, &max, VM_INHERIT_NONE); @@ -277,7 +278,7 @@ static int get_foreign_image_export(mach_port_t task, uint64_t hdr_addr, } uint64_t linkedit_addr = vmaddr + slide; - mach_vm_address_t linkedit_buf; + mach_vm_address_t linkedit_buf = 0; kr = mach_vm_remap(mach_task_self(), &linkedit_buf, filesize, 0, VM_FLAGS_ANYWHERE, task, linkedit_addr, /*copy*/ true, &cur, &max, VM_INHERIT_NONE); @@ -375,8 +376,6 @@ struct _arm_thread_state_64 { uint32_t cpsr, pad; }; - -EXPORT int substitute_dlopen_in_pid(int pid, const char *filename, int options, char **error) { mach_port_t task; mach_vm_address_t target_stack = 0; @@ -421,6 +420,7 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options, char ** } } + __attribute__((unused)) extern char inject_page_start[], inject_start_x86_64[], inject_start_i386[], @@ -479,7 +479,6 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options, char ** p[2] = (uint32_t) vals[2]; } - printf("target_stack=%llx\n", target_stack_top); kr = mach_vm_write(task, target_stack_top, (mach_vm_address_t) stackbuf, baton_len + filelen_rounded); free(stackbuf); @@ -500,6 +499,7 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options, char ** memset(&u, 0, sizeof(u)); switch (cputype) { +#if defined(__x86_64__) || defined(__i386__) case CPU_TYPE_X86_64: u.x64.rsp = target_stack_top; u.x64.rdi = target_stack_top; @@ -514,6 +514,8 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options, char ** state_size = sizeof(u.x32); flavor = 1; break; +#endif +#if defined(__arm__) || defined(__arm64__) case CPU_TYPE_ARM: u.a32.sp = target_stack_top; u.a32.r[0] = target_stack_top; @@ -528,6 +530,11 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options, char ** state_size = sizeof(u.a64); flavor = 6; break; +#endif + default: + asprintf(error, "unknown target cputype %d", cputype); + ret = SUBSTITUTE_ERR_MISC; + goto fail; } mach_port_t thread; diff --git a/lib/substitute-internal.h b/lib/substitute-internal.h index b21a190..f078688 100644 --- a/lib/substitute-internal.h +++ b/lib/substitute-internal.h @@ -55,10 +55,8 @@ typedef struct section section_x; #endif #ifdef __APPLE__ -/* This could graduate to a public API but is not yet. */ -enum { - SUBSTITUTE_DIP_INJECT_MAIN_THREAD, /* not yet */ -}; +/* This could graduate to a public API but is not yet. Needs more + * functionality. */ enum { /* substitute_dlopen_in_pid: task_for_pid failed; on OS X the reasons this diff --git a/test/test-inject.c b/test/test-inject.c index 53918db..96ad46a 100644 --- a/test/test-inject.c +++ b/test/test-inject.c @@ -7,7 +7,7 @@ int main(int argc, char **argv) { if (argc <= 2) { - printf("usage: test-inject <pid> <dylib>n"); + printf("usage: test-inject <pid> <dylib>\n"); return 1; } int pid = atoi(argv[1]); |