diff --git a/.gitignore b/.gitignore index 1ae5b42..a2021c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *.swp out +Makefile +config.log +config.status diff --git a/README.md b/README.md index a2e53c7..22f97e4 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/configure b/configure index 480d027..752fdf1 100755 --- a/configure +++ b/configure @@ -60,12 +60,12 @@ 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 @@ -73,7 +73,7 @@ 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') diff --git a/darwin-bootstrap/posixspawn-hook.c b/darwin-bootstrap/posixspawn-hook.c index 4bfbfb6..5a3cf8b 100644 --- a/darwin-bootstrap/posixspawn-hook.c +++ b/darwin-bootstrap/posixspawn-hook.c @@ -35,6 +35,76 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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)) @@ -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); @@ -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"); diff --git a/darwin-bootstrap/safety-dance/main.m b/darwin-bootstrap/safety-dance/main.m index 8366430..44ee862 100644 --- a/darwin-bootstrap/safety-dance/main.m +++ b/darwin-bootstrap/safety-dance/main.m @@ -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: diff --git a/ent.plist b/ent.plist index fc75011..6123f77 100644 --- a/ent.plist +++ b/ent.plist @@ -1,3 +1,16 @@ -get-task-allowrun-unsigned-codetask_for_pid-allow + + + platform-application + + get-task-allow + + com.apple.system-task-ports + + task_for_pid-allow + + run-unsigned-code + + + diff --git a/lib/arm/jump-patch.h b/lib/arm/jump-patch.h index 8787070..02e0d25 100644 --- a/lib/arm/jump-patch.h +++ b/lib/arm/jump-patch.h @@ -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); } diff --git a/lib/arm64/arch-dis.h b/lib/arm64/arch-dis.h index 142186f..d075cdd 100644 --- a/lib/arm64/arch-dis.h +++ b/lib/arm64/arch-dis.h @@ -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); diff --git a/lib/arm64/dis-main.inc.h b/lib/arm64/dis-main.inc.h index cb24065..e1db431 100644 --- a/lib/arm64/dis-main.inc.h +++ b/lib/arm64/dis-main.inc.h @@ -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) { diff --git a/lib/darwin/execmem.c b/lib/darwin/execmem.c index c7068f3..94b1ffd 100644 --- a/lib/darwin/execmem.c +++ b/lib/darwin/execmem.c @@ -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__ diff --git a/lib/darwin/find-syms.c b/lib/darwin/find-syms.c index 1666f1c..fcc6f3a 100644 --- a/lib/darwin/find-syms.c +++ b/lib/darwin/find-syms.c @@ -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; @@ -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 */ @@ -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) @@ -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__ */ diff --git a/lib/darwin/inject.c b/lib/darwin/inject.c index 7e36e60..7095079 100644 --- a/lib/darwin/inject.c +++ b/lib/darwin/inject.c @@ -13,7 +13,7 @@ #include #include -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 @@ -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)) { @@ -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; diff --git a/lib/dis.h b/lib/dis.h index ba2a6c7..1944612 100644 --- a/lib/dis.h +++ b/lib/dis.h @@ -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; }