1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#include "darwin/manual-syscall.h"
#ifdef __arm64__
#define _PAGE_SIZE 0x4000
#else
#define _PAGE_SIZE 0x1000
#endif
struct baton {
int (*pthread_create)(int *, void *, void *(*)(void *), void *);
void *(*dlopen)(const char *, int);
void *(*dlsym)(void *, const char *);
int (*munmap)(void *, long);
const char *path;
/* bsd_thread_func uses this to wait for entry to go away */
long sem_port;
long nshuttle;
char shuttle[0];
};
static int bsd_thread_func(void *);
#if defined(__i386__)
__attribute__((fastcall))
#endif
void entry(struct baton *baton) {
int pt;
baton->pthread_create(&pt, 0, (void *) bsd_thread_func, baton);
manual_syscall(361 /* bsdthread_terminate */, 0, 0, 0, baton->sem_port);
((void (*)()) 0xbad)();
}
static int bsd_thread_func(void *arg) {
struct baton *baton = arg;
void *r = baton->dlopen(baton->path, 0);
if (r) {
__attribute__((section("__TEXT,__text")))
static char name[] = "substitute_init";
void (*init)(void *, unsigned long) = baton->dlsym(r, name);
if (init)
init(baton->shuttle, baton->nshuttle);
}
manual_syscall(-36 /* semaphore_wait_trap */, baton->sem_port, 0, 0, 0);
unsigned long ptr = (unsigned long) baton & ~(_PAGE_SIZE - 1);
return baton->munmap((void *) ptr, 0x2000);
}
|