Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4d315c1
why so strict
stek29 Jan 8, 2018
d8b9049
_dyld_get_all_image_infos fix
stek29 Jan 8, 2018
3737af1
jtool > ldid (broken FAT)
stek29 Jan 8, 2018
7b97f00
Add config/make stuff to gitignore
stek29 Jan 8, 2018
b20c201
Add platform-application to ent.plist
stek29 Jan 8, 2018
af2bf2b
Fix safety-dance for iOS 11
stek29 Jan 8, 2018
1a59d66
Change iphoneos-version-min in configure
stek29 Jan 8, 2018
4055999
Add arm64 to README
stek29 Jan 8, 2018
fc23857
Fix syntax error in ent.plist :X
stek29 Jan 8, 2018
7c34c90
coolstar's jailbreakd
stek29 Jan 8, 2018
7a9ddc9
Use ldid2. Disable errors on warnings due to syscall() deprecation
coolstar Jan 11, 2018
952f8f7
emergency bugfix
comex Feb 17, 2018
3e23648
Fixed crashes when the same function is hooked twice; sext was evalua…
sbingner Mar 3, 2018
eb51ea8
Merge pull request #1 from sbingner/master
coolstar Mar 3, 2018
061eae0
Fix SubGetImageByName for iOS versions with ImageLoaderMegaDylib (iOS…
sbingner Apr 13, 2018
347acb0
Merge branch 'master' of https://github.com/sbingner/substitute
coolstar Apr 13, 2018
34fda9d
Make it compile on iOS11 without patching SDK
sbingner Apr 13, 2018
8e8f2c7
Merge branch 'master' of https://github.com/sbingner/substitute
coolstar Apr 13, 2018
6c27854
Stop using x18 on arm64
rweichler Jul 16, 2018
f16a56b
Merge pull request #3 from rweichler/patch-1
coolstar Jul 20, 2018
1136e84
Fix linker issue on iOS 11+ sdk
coolstar Feb 19, 2019
bdedbd3
Add arm64e to configure script
coolstar Feb 19, 2019
722f1f1
Initial arm64e support
coolstar Feb 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
*.swp
out
Makefile
config.log
config.status
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Alpha. Currently only build tested on Mac, targeting Mac and iOS.

To compile for iOS:

./configure --xcode-sdk=iphoneos --enable-ios-bootstrap && make -j8 && ./script/gen-deb.sh
./configure --xcode-sdk=iphoneos --xcode-archs=arm64 && make -j8 && ./script/gen-deb.sh

You may want to turn off IB_VERBOSE in darwin-bootstrap/ib-log.h, which
currently spams a lot of files to /tmp and spams the syslog. I will turn it
Expand Down
6 changes: 3 additions & 3 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,20 @@ if settings.enable_ios_bootstrap:

if settings.enable_werror:
for mach in machs + [settings.host_machine()]:
settings[mach.name].cflags = ['-Werror'] + settings[mach.name].cflags
settings[mach.name].cflags = ['-Wno-error'] + settings[mach.name].cflags

# XXX this is a mess and wrong
flags = ['-O3']
if settings.host_machine().is_ios():
flags.append('-miphoneos-version-min=8.0')
flags.append('-miphoneos-version-min=11.0')
for i in ('cflags', 'ldflags'):
settings.host[i] = flags + settings.host[i]
settings.host.cflags = ['-fvisibility=hidden'] + settings.host.cflags
settings.host.ldflags = ['-dead_strip'] + settings.host.ldflags

# todo make overridable?
cc_argv = c.cc.argv()
if 'armv7' in cc_argv or 'arm64' in cc_argv:
if 'armv7' in cc_argv or 'arm64' in cc_argv or 'arm64e' in cc_argv:
settings.modify_link = lambda env: (
env['cmds'].append(ldid_tool.argv() + ['-S'+settings.src+'/ent.plist', env['outs'][0]]),
env['ins'].append(settings.src+'/ent.plist')
Expand Down
76 changes: 76 additions & 0 deletions darwin-bootstrap/posixspawn-hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,76 @@
#include <pthread.h>
#include <libkern/OSByteOrder.h>

#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>

#define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_AFTER_DELAY 4
struct __attribute__((__packed__)) JAILBREAKD_ENTITLE_PID_AND_SIGCONT {
uint8_t Command;
int32_t PID;
};

void calljailbreakd(pid_t PID){
#define BUFSIZE 1024

int sockfd, portno, n;
int serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
char *hostname;
char buf[BUFSIZE];

hostname = "127.0.0.1";
portno = 5;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
printf("ERROR opening socket\n");

/* gethostbyname: get the server's DNS entry */
server = gethostbyname(hostname);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host as %s\n", hostname);
exit(0);
}

/* build the server's Internet address */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);

/* get a message from the user */
bzero(buf, BUFSIZE);

struct JAILBREAKD_ENTITLE_PID_AND_SIGCONT entitlePacket;
entitlePacket.Command = JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_AFTER_DELAY;
entitlePacket.PID = PID;

memcpy(buf, &entitlePacket, sizeof(struct JAILBREAKD_ENTITLE_PID_AND_SIGCONT));

serverlen = sizeof(serveraddr);
n = sendto(sockfd, buf, sizeof(struct JAILBREAKD_ENTITLE_PID_AND_SIGCONT), 0, (const struct sockaddr *)&serveraddr, serverlen);
if (n < 0)
printf("Error in sendto\n");
}


#define _pid_hash(pidp) (*(pidp))
#define _pid_eq(pid1p, pid2p) (*(pid1p) == *(pid2p))
#define _pid_null(pidp) (!*(pidp))
Expand Down Expand Up @@ -368,6 +438,10 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old,
}
if (IB_VERBOSE)
ib_log("**");
if (!g_is_launchd) {
ib_log("non-launchd, calling jailbreakd on ourselves");
calljailbreakd(getpid());
}
int ret = old(pidp, path, file_actions, &my_attr, argv, envp_to_use);
if (IB_VERBOSE)
ib_log("ret=%d pid=%ld", ret, (long) *pidp);
Expand All @@ -390,6 +464,8 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old,
pthread_mutex_unlock(&g_state_lock);
}

//calljailbreakd(pid);

goto cleanup;
crap:
ib_log("posixspawn-hook: weird error - OOM? skipping our stuff");
Expand Down
5 changes: 5 additions & 0 deletions darwin-bootstrap/safety-dance/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,13 @@ - (void)loadStuff {
@"returnButton": returnButton,
@"continueButton": continueButton,
@"grid": autoGrid,
#ifdef __IPHONE_11_0
@"topGuide": self.view.safeAreaLayoutGuide.topAnchor,
@"bottomGuide": self.view.safeAreaLayoutGuide.bottomAnchor,
#else
@"topGuide": self.topLayoutGuide,
@"bottomGuide": self.bottomLayoutGuide,
#endif
};
NSMutableArray *constraints = [[NSMutableArray alloc] init];
[constraints addObjectsFromArray:
Expand Down
15 changes: 14 additions & 1 deletion ent.plist
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<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>
<plist version="1.0">
<dict>
<key>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>run-unsigned-code</key>
<true/>
</dict>
</plist>
2 changes: 1 addition & 1 deletion lib/arm/jump-patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ static inline int jump_patch_size(uint_tptr pc,
static inline void make_jump_patch(void **codep, uint_tptr pc,
uint_tptr dpc,
struct arch_dis_ctx arch) {
struct assemble_ctx actx = {codep, pc, arch.pc_low_bit, 0xe};
struct assemble_ctx actx = {codep, (void*)pc, arch.pc_low_bit, 0xe};
LDR_PC(actx, dpc);
}
2 changes: 1 addition & 1 deletion lib/arm64/arch-dis.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static inline void arch_dis_ctx_init(struct arch_dis_ctx *ctx) {
}

static inline int arm64_get_unwritten_temp_reg(struct arch_dis_ctx *ctx) {
uint32_t avail = ~ctx->regs_possibly_written & ((1 << 19) - (1 << 9));
uint32_t avail = ~ctx->regs_possibly_written & ((1 << 18) - (1 << 9));
if (!avail)
__builtin_abort();
return 31 - __builtin_clz(avail);
Expand Down
6 changes: 4 additions & 2 deletions lib/arm64/dis-main.inc.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
static INLINE void P(adrlabel_label_unk_Xd_1_ADR)(tdis_ctx ctx, struct bitslice Xd, struct bitslice label) {
return P(pcrel)(ctx, ctx->base.pc + sext(bs_get(label, ctx->base.op), 22),
return P(pcrel)(ctx, ctx->base.pc + sext(bs_get(label, ctx->base.op), 21),
(struct arch_pcrel_info) {bs_get(Xd, ctx->base.op), PLM_ADR});
}
static INLINE void P(adrplabel_label_unk_Xd_1_ADRP)(tdis_ctx ctx, struct bitslice Xd, struct bitslice label) {
return P(pcrel)(ctx, ctx->base.pc + (sext(bs_get(label, ctx->base.op), 22) << 12),
return P(pcrel)(ctx,
(ctx->base.pc & ~0xfff) +
(sext(bs_get(label, ctx->base.op), 21) << 12),
(struct arch_pcrel_info) {bs_get(Xd, ctx->base.op), PLM_ADR});
}
static INLINE void P(am_b_target_addr_B_1_B)(tdis_ctx ctx, struct bitslice addr) {
Expand Down
4 changes: 4 additions & 0 deletions lib/darwin/execmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ static bool apply_one_pcp_with_state(native_thread_state *state,
#elif defined(__i386__)
pcp = (uintptr_t *) &state->__eip;
#elif defined(__arm__) || defined(__arm64__)
#if __DARWIN_OPAQUE_ARM_THREAD_STATE64
pcp = (uintptr_t *) &state->__opaque_pc;
#else
pcp = (uintptr_t *) &state->__pc;
#endif
#endif
uintptr_t old = *pcp;
#ifdef __arm__
Expand Down
61 changes: 53 additions & 8 deletions lib/darwin/find-syms.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,26 @@
#include "substitute-internal.h"
#include "dyld_cache_format.h"

extern const struct dyld_all_image_infos *_dyld_get_all_image_infos();
const struct dyld_all_image_infos *__dyld_get_all_image_infos() {
struct task_dyld_info dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
if (task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count) == KERN_SUCCESS) {
return (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
} else {
abort();
}
}
const struct dyld_all_image_infos *(*dyld_get_all_image_infos)();

static pthread_once_t dyld_inspect_once = PTHREAD_ONCE_INIT;
/* and its fruits: */
static uintptr_t (*ImageLoaderMachO_getSlide)(void *);
static const struct mach_header *(*ImageLoaderMachO_machHeader)(void *);
static bool (*dyld_validImage)(void *);
uintptr_t (*ImageLoaderMegaDylib_getSlide)(void*);
void *(*ImageLoaderMegaDylib_getIndexedMachHeader)(void*, unsigned index);
void *(*ImageLoaderMegaDylib_isCacheHandle)(void*proxy, void* handle, unsigned* index, uint8_t* flags);
void **dyld_sAllCacheImagesProxy;

static const struct dyld_cache_header *_Atomic s_cur_shared_cache_hdr;
static int s_cur_shared_cache_fd;
Expand Down Expand Up @@ -280,18 +294,26 @@ ok2: ;
*/

static void inspect_dyld() {
const struct dyld_all_image_infos *aii = _dyld_get_all_image_infos();
const struct dyld_all_image_infos *aii = dyld_get_all_image_infos();
const void *dyld_hdr = aii->dyldImageLoadAddress;

const char *names[2] = { "__ZNK16ImageLoaderMachO8getSlideEv",
"__ZNK16ImageLoaderMachO10machHeaderEv" };
void *syms[2];
const char *names[6] = { "__ZNK16ImageLoaderMachO8getSlideEv",
"__ZNK16ImageLoaderMachO10machHeaderEv",
"__ZN4dyldL20sAllCacheImagesProxyE",
"__ZN20ImageLoaderMegaDylib13isCacheHandleEPvPjPh",
"__ZNK20ImageLoaderMegaDylib8getSlideEv",
"__ZNK20ImageLoaderMegaDylib20getIndexedMachHeaderEj" };
void *syms[6];
intptr_t dyld_slide = -1;
find_syms_raw(dyld_hdr, &dyld_slide, names, syms, 2);
find_syms_raw(dyld_hdr, &dyld_slide, names, syms, 6);
if (!syms[0] || !syms[1])
substitute_panic("couldn't find ImageLoader methods\n");
ImageLoaderMachO_getSlide = syms[0];
ImageLoaderMachO_machHeader = syms[1];
dyld_sAllCacheImagesProxy = syms[2];
ImageLoaderMegaDylib_isCacheHandle = syms[3];
ImageLoaderMegaDylib_getSlide = syms[4];
ImageLoaderMegaDylib_getIndexedMachHeader = syms[5];
}

/* 'dlhandle' keeps the image alive */
Expand All @@ -303,8 +325,20 @@ struct substitute_image *substitute_open_image(const char *filename) {
if (!dlhandle)
return NULL;

const void *image_header = ImageLoaderMachO_machHeader(dlhandle);
intptr_t slide = ImageLoaderMachO_getSlide(dlhandle);
void* image = (void*)(((uintptr_t)dlhandle) & (-4));
unsigned index;
uint8_t mode;
const void *image_header;
intptr_t slide;
if (ImageLoaderMegaDylib_isCacheHandle != NULL && ImageLoaderMegaDylib_isCacheHandle(*dyld_sAllCacheImagesProxy, image, &index, &mode)) {
if (ImageLoaderMegaDylib_getSlide == NULL || ImageLoaderMegaDylib_getIndexedMachHeader == NULL)
substitute_panic("couldn't find ImageLoaderMegaDylib methods\n");
slide = ImageLoaderMegaDylib_getSlide(*dyld_sAllCacheImagesProxy);
image_header = ImageLoaderMegaDylib_getIndexedMachHeader(*dyld_sAllCacheImagesProxy, index);
} else {
image_header = ImageLoaderMachO_machHeader(image);
slide = ImageLoaderMachO_getSlide(image);
}

struct substitute_image *im = malloc(sizeof(*im));
if (!im)
Expand All @@ -330,4 +364,15 @@ int substitute_find_private_syms(struct substitute_image *im,
return SUBSTITUTE_OK;
}


__attribute__((constructor))
void init(void) {
void *lib = dlopen("/usr/lib/system/libdyld.dylib", RTLD_LAZY);
if (lib != NULL)
dyld_get_all_image_infos = dlsym(lib, "_dyld_get_all_image_infos");

if (dyld_get_all_image_infos == NULL) {
dyld_get_all_image_infos = __dyld_get_all_image_infos;
}
}
#endif /* __APPLE__ */
12 changes: 10 additions & 2 deletions lib/darwin/inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <stdio.h>
#include <stdbool.h>

extern const struct dyld_all_image_infos *_dyld_get_all_image_infos();
extern const struct dyld_all_image_infos *dyld_get_all_image_infos();

#define DEFINE_STRUCTS

Expand Down Expand Up @@ -104,7 +104,7 @@ static int find_foreign_images(mach_port_t task,
* look up the symbols locally and don't have to do the rest of the
* syscalls... not sure if this is any faster, but whatever. */
if (FIELD(version) >= 13) {
const struct dyld_all_image_infos *local_aii = _dyld_get_all_image_infos();
const struct dyld_all_image_infos *local_aii = dyld_get_all_image_infos();
if (local_aii->version >= 13 &&
FIELD(sharedCacheSlide) == local_aii->sharedCacheSlide &&
!memcmp(FIELD(sharedCacheUUID), local_aii->sharedCacheUUID, 16)) {
Expand Down Expand Up @@ -706,9 +706,17 @@ int substitute_dlopen_in_pid(int pid, const char *filename, int options,
flavor = ARM_THREAD_STATE;
break;
case CPU_TYPE_ARM64:
#if __DARWIN_OPAQUE_ARM_THREAD_STATE64
u.a64.__opaque_sp = target_stack_top;
#else
u.a64.__sp = target_stack_top;
#endif
u.a64.__x[0] = target_stack_top;
#if __DARWIN_OPAQUE_ARM_THREAD_STATE64
u.a64.__opaque_pc = target_code_page + (inject_start_arm64 - inject_page_start);
#else
u.a64.__pc = target_code_page + (inject_start_arm64 - inject_page_start);
#endif
state_size = sizeof(u.a64);
flavor = ARM_THREAD_STATE64;
break;
Expand Down
2 changes: 1 addition & 1 deletion lib/dis.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct bitslice {
const struct bitslice_run *runs;
};

static inline int sext(unsigned val, int bits) {
static inline uint_tptr sext(unsigned val, int bits) {
return val & (1 << (bits - 1)) ? ((int)val - (1 << bits)) : (int)val;
}

Expand Down