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/darwin/find-syms.c b/lib/darwin/find-syms.c index 1666f1c..496680d 100644 --- a/lib/darwin/find-syms.c +++ b/lib/darwin/find-syms.c @@ -11,12 +11,27 @@ #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(); + } +} +extern const struct dyld_all_image_infos *_dyld_get_all_image_infos() __attribute__((weak_import)); +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 +295,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 +326,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 +365,14 @@ int substitute_find_private_syms(struct substitute_image *im, return SUBSTITUTE_OK; } + +__attribute__((constructor)) +void init(void) { + if (_dyld_get_all_image_infos != NULL) { + fprintf(stderr, "_dyld_get_all_image_infos present\n"); + dyld_get_all_image_infos = _dyld_get_all_image_infos; + } else { + dyld_get_all_image_infos = __dyld_get_all_image_infos; + } +} #endif /* __APPLE__ */