Skip to content

Commit 21681b7

Browse files
committed
woo, inject seems to work on all platforms
1 parent c2728b5 commit 21681b7

File tree

7 files changed

+298
-145
lines changed

7 files changed

+298
-145
lines changed

Makefile

+20-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARCH := -arch x86_64
55
XCFLAGS := -O3 -Wall -Wextra -Werror -Ilib $(ARCH)
66
override CC := $(CC) $(XCFLAGS) $(CFLAGS)
77
override CXX := $(CXX) $(XCFLAGS) $(CFLAGS) -fno-exceptions -fno-asynchronous-unwind-tables
8-
LIB_LDFLAGS := -lobjc -dynamiclib -fvisibility=hidden
8+
LIB_LDFLAGS := -lobjc -dynamiclib -fvisibility=hidden -install_name /usr/lib/libsubstitute.dylib
99
IMAON2 := /Users/comex/c/imaon2
1010
GEN_JS := node --harmony --harmony_arrow_functions $(IMAON2)/tables/gen.js
1111

@@ -54,28 +54,35 @@ out/libsubstitute.dylib: $(LIB_OBJS)
5454
# this doesn't need to be done on the building machine, just in case someone is
5555
# trying to build with some Linux compiler that doesn't support all the
5656
# architectures or something - meh
57-
ASCLANG := clang -dynamiclib -nostartfiles -nodefaultlibs
58-
out/inject-asm-raw-x86_64.o: lib/darwin/inject-asm-raw.S Makefile
59-
$(ASCLANG) -arch x86_64 -o $@ $<
60-
out/inject-asm-raw-i386.o: lib/darwin/inject-asm-raw.S Makefile
61-
$(ASCLANG) -arch i386 -o $@ $<
62-
out/inject-asm-raw-arm.o: lib/darwin/inject-asm-raw.S Makefile
63-
$(ASCLANG) -arch armv7 -o $@ $<
64-
out/inject-asm-raw-arm64.o: lib/darwin/inject-asm-raw.S Makefile
65-
$(ASCLANG) -arch arm64 -o $@ $<
57+
# Did you know? With -Oz + -marm, Apple clang-600.0.56 actually generated
58+
# wrong code for the ARM version. It works with -Os and with newer clang.
59+
IACLANG := clang -Os -dynamiclib -nostartfiles -nodefaultlibs -isysroot /dev/null -fPIC
60+
out/inject-asm-raw-x86_64.o: lib/darwin/inject-asm-raw.c Makefile
61+
$(IACLANG) -arch x86_64 -o $@ $<
62+
out/inject-asm-raw-i386.o: lib/darwin/inject-asm-raw.c Makefile
63+
$(IACLANG) -arch i386 -o $@ $<
64+
out/inject-asm-raw-arm.o: lib/darwin/inject-asm-raw.c Makefile
65+
$(IACLANG) -arch armv7 -marm -o $@ $<
66+
out/inject-asm-raw-arm64.o: lib/darwin/inject-asm-raw.c Makefile
67+
$(IACLANG) -arch arm64 -o $@ $<
6668
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
6769
out/inject-asm.S: $(IAR_BINS) Makefile
70+
(echo ".align 12"; \
71+
echo ".globl _inject_page_start"; \
72+
echo "_inject_page_start:"; \
6873
for i in x86_64 i386 arm arm64; do \
69-
echo ".globl inject_start_$$i"; \
70-
echo "inject_start_$$i:"; \
7174
echo ".align 2"; \
75+
echo ".globl _inject_start_$$i"; \
76+
echo "_inject_start_$$i:"; \
7277
printf ".byte "; \
7378
xxd -i < out/inject-asm-raw-$$i.bin | xargs echo; \
74-
done > $@
79+
done) > $@ || rm -f $@
7580

7681
define define_test
7782
out/test-$(1): test/test-$(2).[cm]* $(HEADERS) $(GENERATED) Makefile out/libsubstitute.dylib
7883
$(3) -g -o $$@ $$< -Ilib -Isubstrate -Lout -lsubstitute
84+
ldid -Sent.plist $$@
85+
install_name_tool -change /usr/lib/libsubstitute.dylib '@executable_path/libsubstitute.dylib' $$@
7986
all: out/test-$(1)
8087
endef
8188
$(eval $(call define_test,tdarm-simple,td-simple,$(CC) -std=c11 -DHDR='"arm/dis-arm.inc.h"' -Dxdis=dis_arm -DFORCE_TARGET_arm))

ent.plist

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0"><dict><key>get-task-allow</key><true/><key>run-unsigned-code</key><true/><key>task_for_pid-allow</key><true/></dict></plist>

lib/darwin/inject-asm-raw.S

-113
This file was deleted.

lib/darwin/inject-asm-raw.c

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#ifdef __arm64__
2+
#define _PAGE_SIZE 0x4000
3+
#else
4+
#define _PAGE_SIZE 0x1000
5+
#endif
6+
7+
#define REG(var, reg) register long _##var asm(#reg) = var
8+
#define OREG(var, reg) register long var asm(#reg)
9+
10+
__attribute__((always_inline))
11+
#if defined(__x86_64__)
12+
static int syscall(long s, long a, long b, long c, long d, long _) {
13+
if (s < 0)
14+
s = -s | 1 << 24;
15+
else
16+
s |= 2 << 24;
17+
REG(s, rax); REG(a, rdi); REG(b, rsi); REG(c, rdx); REG(d, rcx);
18+
OREG(out, rax);
19+
asm volatile("syscall" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d));
20+
return out;
21+
}
22+
#elif defined(__i386__)
23+
static int syscall(long s, long a, long b, long c, long d, long e) {
24+
REG(s, eax);
25+
OREG(out, eax);
26+
OREG(sp, ecx);
27+
asm volatile("mov %%esp, %0" : "=r"(sp));
28+
asm volatile("push %0" :: "r"(e));
29+
asm volatile("push %0" :: "r"(d));
30+
asm volatile("push %0" :: "r"(c));
31+
asm volatile("push %0" :: "r"(b));
32+
asm volatile("push %0" :: "r"(a));
33+
asm volatile("call 1f; 1: pop %%edx; add $(2f-1b), %%edx;"
34+
"sysenter; 2:"
35+
: "=r"(out) : "r"(_s) : "edx");
36+
return out;
37+
}
38+
#elif defined(__arm__)
39+
static int syscall(long s, long a, long b, long c, long d, long _) {
40+
REG(s, r12); REG(a, r0); REG(b, r1); REG(c, r2); REG(d, r3);
41+
OREG(out, r0);
42+
asm volatile("svc #0x80" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d));
43+
return out;
44+
}
45+
#elif defined(__arm64__)
46+
static int syscall(long s, long a, long b, long c, long d, long _) {
47+
REG(s, x16); REG(a, x0); REG(b, x1); REG(c, x2); REG(d, x3);
48+
OREG(out, x0);
49+
asm volatile("svc #0x80" : "=r"(out) : "r"(_s), "r"(_a), "r"(_b), "r"(_c), "r"(_d));
50+
return out;
51+
}
52+
#else
53+
#error ?
54+
#endif
55+
56+
57+
struct baton {
58+
int (*pthread_create)(int *, void *, void *(*)(void *), void *);
59+
void (*dlopen)(const char *, int);
60+
const char *path;
61+
long done;
62+
};
63+
struct baton2 {
64+
void (*dlopen)(const char *, int);
65+
const char *path;
66+
int port;
67+
};
68+
static void *bsd_thread_func(void *);
69+
#if defined(__i386__)
70+
__attribute__((fastcall))
71+
#endif
72+
/* xxx need to change this to have host allocate two pages - way easier */
73+
void entry(struct baton *baton) {
74+
int pt;
75+
baton->pthread_create(&pt, 0, bsd_thread_func, baton);
76+
unsigned long ptr = (unsigned long) baton & ~(_PAGE_SIZE - 1);
77+
while (!baton->done)
78+
syscall(-62 /*clock_sleep_trap */, 0, 1, 0, 8000 /*ns*/, -1);
79+
syscall(361 /*bsdthread_terminate*/, ptr, 0x2000, 0, 0, 0);
80+
((void (*)()) 0xbad)();
81+
}
82+
static void *bsd_thread_func(void *arg) {
83+
struct baton *baton = arg;
84+
baton->dlopen(baton->path, 0);
85+
baton->done = 1;
86+
return 0;
87+
}

lib/darwin/inject-asm.S

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.align 12
2+
.globl _inject_page_start
3+
_inject_page_start:
4+
.align 2
5+
.globl _inject_start_x86_64
6+
_inject_start_x86_64:
7+
.byte 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0x48, 0x8d, 0x15, 0x53, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x7d, 0xf4, 0x31, 0xf6, 0x48, 0x89, 0xd9, 0xff, 0x13, 0xeb, 0x15, 0xb8, 0x3e, 0x00, 0x00, 0x01, 0x31, 0xff, 0xbe, 0x01, 0x00, 0x00, 0x00, 0x31, 0xd2, 0xb9, 0x40, 0x1f, 0x00, 0x00, 0x0f, 0x05, 0x48, 0x83, 0x7b, 0x18, 0x00, 0x74, 0xe4, 0x48, 0x81, 0xe3, 0x00, 0xf0, 0xff, 0xff, 0xb8, 0x69, 0x01, 0x00, 0x02, 0xbe, 0x00, 0x20, 0x00, 0x00, 0x31, 0xd2, 0x31, 0xc9, 0x48, 0x89, 0xdf, 0x0f, 0x05, 0xb9, 0xad, 0x0b, 0x00, 0x00, 0x31, 0xc0, 0xff, 0xd1, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xc3, 0x55, 0x48, 0x89, 0xe5, 0x53, 0x50, 0x48, 0x89, 0xfb, 0x48, 0x8b, 0x7b, 0x10, 0x31, 0xf6, 0xff, 0x53, 0x08, 0x48, 0xc7, 0x43, 0x18, 0x01, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0x5d, 0xc3
8+
.align 2
9+
.globl _inject_start_i386
10+
_inject_start_i386:
11+
.byte 0x55, 0x89, 0xe5, 0x53, 0x57, 0x56, 0x83, 0xec, 0x1c, 0x89, 0xce, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x58, 0x89, 0x74, 0x24, 0x0c, 0x8d, 0x80, 0x90, 0x00, 0x00, 0x00, 0x89, 0x44, 0x24, 0x08, 0x8d, 0x45, 0xf0, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x16, 0x8b, 0x46, 0x0c, 0x89, 0xe1, 0x83, 0xf8, 0x00, 0x75, 0x33, 0x31, 0xff, 0xbb, 0x01, 0x00, 0x00, 0x00, 0xb8, 0xff, 0xff, 0xff, 0xff, 0x50, 0xb8, 0x40, 0x1f, 0x00, 0x00, 0x50, 0x57, 0x53, 0x57, 0xb8, 0xc2, 0xff, 0xff, 0xff, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0xc2, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x34, 0x8b, 0x46, 0x0c, 0x89, 0xe1, 0x83, 0xf8, 0x00, 0x74, 0xd4, 0x81, 0xe6, 0x00, 0xf0, 0xff, 0xff, 0x31, 0xc0, 0x50, 0x50, 0x50, 0xb8, 0x00, 0x20, 0x00, 0x00, 0x50, 0x56, 0xb8, 0x69, 0x01, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0xc2, 0x09, 0x00, 0x00, 0x00, 0x0f, 0x34, 0xb8, 0xad, 0x0b, 0x00, 0x00, 0xff, 0xd0, 0x83, 0xc4, 0x1c, 0x5e, 0x5f, 0x5b, 0x5d, 0xc3, 0x55, 0x89, 0xe5, 0x56, 0x83, 0xec, 0x14, 0x8b, 0x75, 0x08, 0x8b, 0x46, 0x08, 0x89, 0x04, 0x24, 0xc7, 0x44, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0x56, 0x04, 0xc7, 0x46, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x83, 0xc4, 0x14, 0x5e, 0x5d, 0xc3
12+
.align 2
13+
.globl _inject_start_arm
14+
_inject_start_arm:
15+
.byte 0x90, 0x40, 0x2d, 0xe9, 0x04, 0x70, 0x8d, 0xe2, 0x04, 0xd0, 0x4d, 0xe2, 0x00, 0x40, 0xa0, 0xe1, 0x0d, 0x00, 0xa0, 0xe1, 0x00, 0x90, 0x94, 0xe5, 0x60, 0x20, 0x00, 0xe3, 0x00, 0x20, 0x40, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0x02, 0x20, 0x8f, 0xe0, 0x04, 0x30, 0xa0, 0xe1, 0x39, 0xff, 0x2f, 0xe1, 0x0c, 0x00, 0x94, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x1a, 0x3d, 0xc0, 0xe0, 0xe3, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x7d, 0x3d, 0xa0, 0xe3, 0x00, 0x00, 0xa0, 0xe3, 0x80, 0x00, 0x00, 0xef, 0x0c, 0x00, 0x94, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0xfa, 0xff, 0xff, 0x0a, 0x1f, 0x40, 0xcb, 0xe7, 0x69, 0xc1, 0x00, 0xe3, 0x02, 0x1a, 0xa0, 0xe3, 0x00, 0x20, 0xa0, 0xe3, 0x04, 0x00, 0xa0, 0xe1, 0x00, 0x30, 0xa0, 0xe3, 0x80, 0x00, 0x00, 0xef, 0xad, 0x0b, 0x00, 0xe3, 0x30, 0xff, 0x2f, 0xe1, 0x04, 0xd0, 0x47, 0xe2, 0x90, 0x80, 0xbd, 0xe8, 0x90, 0x40, 0x2d, 0xe9, 0x00, 0x40, 0xa0, 0xe1, 0x00, 0x10, 0xa0, 0xe3, 0xd4, 0x20, 0xc4, 0xe1, 0x04, 0x70, 0x8d, 0xe2, 0x03, 0x00, 0xa0, 0xe1, 0x32, 0xff, 0x2f, 0xe1, 0x01, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x84, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x90, 0x80, 0xbd, 0xe8
16+
.align 2
17+
.globl _inject_start_arm64
18+
_inject_start_arm64:
19+
.byte 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xff, 0x43, 0x00, 0xd1, 0xf3, 0x03, 0x00, 0xaa, 0x68, 0x02, 0x40, 0xf9, 0x01, 0x00, 0x80, 0xd2, 0x62, 0x03, 0x00, 0x10, 0x1f, 0x20, 0x03, 0xd5, 0xe0, 0x33, 0x00, 0x91, 0xe3, 0x03, 0x13, 0xaa, 0x00, 0x01, 0x3f, 0xd6, 0x68, 0x0e, 0x40, 0xf9, 0x28, 0x01, 0x00, 0xb5, 0xb0, 0x07, 0x80, 0x92, 0xe1, 0x03, 0x40, 0xb2, 0x03, 0xe8, 0x83, 0xd2, 0x02, 0x00, 0x80, 0xd2, 0x00, 0x00, 0x80, 0xd2, 0x01, 0x10, 0x00, 0xd4, 0x68, 0x0e, 0x40, 0xf9, 0xa8, 0xff, 0xff, 0xb4, 0x60, 0xc6, 0x72, 0x92, 0x30, 0x2d, 0x80, 0xd2, 0xe1, 0x03, 0x73, 0xb2, 0x02, 0x00, 0x80, 0xd2, 0x03, 0x00, 0x80, 0xd2, 0x01, 0x10, 0x00, 0xd4, 0xa8, 0x75, 0x81, 0xd2, 0x00, 0x01, 0x3f, 0xd6, 0xbf, 0x43, 0x00, 0xd1, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0xc0, 0x03, 0x5f, 0xd6, 0xf4, 0x4f, 0xbe, 0xa9, 0xfd, 0x7b, 0x01, 0xa9, 0xfd, 0x43, 0x00, 0x91, 0xf3, 0x03, 0x00, 0xaa, 0x68, 0x82, 0x40, 0xa9, 0x01, 0x00, 0x80, 0x52, 0x00, 0x01, 0x3f, 0xd6, 0xe8, 0x03, 0x40, 0xb2, 0x68, 0x0e, 0x00, 0xf9, 0x00, 0x00, 0x80, 0xd2, 0xfd, 0x7b, 0x41, 0xa9, 0xf4, 0x4f, 0xc2, 0xa8, 0xc0, 0x03, 0x5f, 0xd6

0 commit comments

Comments
 (0)