// 摘抄自github + (void)load { _dyld_register_func_for_add_image(&image_added); _dyld_register_func_for_remove_image(&image_removed); } #pragma mark - Callbacks static void image_added(const struct mach_header *mh, intptr_t slide) { _print_image(mh, true); } static void image_removed(const struct mach_header *mh, intptr_t slide) { _print_image(mh, false); } #pragma mark - Logger static void _print_image(const struct mach_header *mh, bool added) { Dl_info image_info; int result = dladdr(mh, &image_info); if (result == 0) { printf("Could not print info for mach_header: %p\n\n", mh); return; } const char *image_name = image_info.dli_fname; const intptr_t image_base_address = (intptr_t)image_info.dli_fbase; const uint64_t image_text_size = _image_text_segment_size(mh); char image_uuid[37]; const uuid_t *image_uuid_bytes = _image_retrieve_uuid(mh); uuid_unparse(*image_uuid_bytes, image_uuid); const char *log = added ? "Added" : "Removed"; printf("%s: 0x%02lx (0x%02llx) %s <%s>\n\n", log, image_base_address, image_text_size, image_name, image_uuid); /* if (strstr(image_name, "MobileSubstrate.dylib")) { // 自由发挥 exit(); } */ } #pragma mark - Private static uint32_t _image_header_size(const struct mach_header *mh) { bool is_header_64_bit = (mh->magic == MH_MAGIC_64 || mh->magic == MH_CIGAM_64); return (is_header_64_bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header)); } static void _image_visit_load_commands(const struct mach_header *mh, void (^visitor)(struct load_command *lc, bool *stop)) { assert(visitor != NULL); uintptr_t lc_cursor = (uintptr_t)mh + _image_header_size(mh); for (uint32_t idx = 0; idx < mh->ncmds; idx++) { struct load_command *lc = (struct load_command *)lc_cursor; bool stop = false; visitor(lc, &stop); if (stop) { return; } lc_cursor += lc->cmdsize; } } static uint64_t _image_text_segment_size(const struct mach_header *mh) { static const char *text_segment_name = "__TEXT"; __block uint64_t text_size = 0; _image_visit_load_commands(mh, ^ (struct load_command *lc, bool *stop) { if (lc->cmdsize == 0) { return; } if (lc->cmd == LC_SEGMENT) { struct segment_command *seg_cmd = (struct segment_command *)lc; if (strcmp(seg_cmd->segname, text_segment_name) == 0) { text_size = seg_cmd->vmsize; *stop = true; return; } } if (lc->cmd == LC_SEGMENT_64) { struct segment_command_64 *seg_cmd = (struct segment_command_64 *)lc; if (strcmp(seg_cmd->segname, text_segment_name) == 0) { text_size = seg_cmd->vmsize; *stop = true; return; } } }); return text_size; } static const uuid_t *_image_retrieve_uuid(const struct mach_header *mh) { __block const struct uuid_command *uuid_cmd = NULL; _image_visit_load_commands(mh, ^ (struct load_command *lc, bool *stop) { if (lc->cmdsize == 0) { return; } if (lc->cmd == LC_UUID) { uuid_cmd = (const struct uuid_command *)lc; *stop = true; } }); if (uuid_cmd == NULL) { return NULL; } return &uuid_cmd->uuid; }
发表评论