| Dl_info checkDlinfo; if(!dladdr((const void *)checkAddress, &checkDlinfo)){ return false; } const char * checkfname = checkDlinfo.dli_fname; struct mach_header_64 * checkMachHeader = (struct mach_header_64 *) checkDlinfo.dli_fbase; if (checkMachHeader->magic != MH_MAGIC_64) return false; if(checkMachHeader->ncmds == 0) return false; struct segment_command_64 * checkCommand = (struct segment_command_64 *) ((char *)checkMachHeader + sizeof(struct mach_header_64)); struct segment_command_64 * checkTextCommand = NULL; for (int i =0; i< checkMachHeader->ncmds; i++) { if ((checkCommand->cmd == LC_SEGMENT_64) && (strcmp(checkCommand->segname, "__TEXT") == 0)) { checkTextCommand = checkCommand; break; } checkCommand =(struct segment_command_64 *) ((uint64_t)checkCommand + checkCommand->cmdsize); } if (!checkTextCommand) return false; uint64_t checkTextVmSize = checkTextCommand->vmsize; kern_return_t kernReturn = KERN_SUCCESS; const char *sharedCachePaths[] = { "/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64", "/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e", "/System/Library/dyld/dyld_shared_cache_arm64e", }; int fd = -1; for (int i = 0;i < sizeof(sharedCachePaths) / sizeof(char *);i++) { fd = open(sharedCachePaths[i], O_RDONLY); if (fd != -1) { break; } } if (fd == -1) return false; vm_size_t vmPageSize = vm_page_size; unsigned char* p_map =( unsigned char*) mmap(0, vmPageSize, PROT_READ,MAP_NOCACHE|MAP_PRIVATE, fd, 0); if (p_map == MAP_FAILED) { //映射失败 close(fd); return false; } struct dyld_cache_header * cacheHeader = ( struct dyld_cache_header *)p_map; if(strcmp(cacheHeader->magic, "dyld_v1 arm64") != 0){ munmap(p_map, vmPageSize); close(fd); return false; } struct dyld_cache_mapping_info* mappings = (struct dyld_cache_mapping_info*)(cacheHeader->mappingOffset + (uintptr_t)cacheHeader); uintptr_t length = mappings[0].size; munmap(p_map, vmPageSize); vmPageSize = length; p_map =( unsigned char *) mmap(0, vmPageSize, PROT_READ, MAP_NOCACHE|MAP_PRIVATE|MAP_NORESERVE, fd, 0); if (p_map == MAP_FAILED) { //映射失败 printf("error:%s\n", strerror(errno)); close(fd); return false; } cacheHeader = ( struct dyld_cache_header *)p_map; mappings = (struct dyld_cache_mapping_info*)(cacheHeader->mappingOffset + (uintptr_t)cacheHeader); //非越狱系统 imagesCount = 0 越狱系统 imagesCount > 0 uint32_t imagesCount = cacheHeader->imagesCount; if (imagesCount == 0) { munmap(p_map, vmPageSize); close(fd); return false; } struct dyld_cache_image_info* dylibs = (struct dyld_cache_image_info*)((uintptr_t)cacheHeader + cacheHeader->imagesOffset); struct dyld_cache_image_info * matchDylib = NULL; for (uint32_t i=0; i < imagesCount; i++) { const char* dylibPath = (char*)cacheHeader + dylibs[i].pathFileOffset; if (strcmp(checkfname, dylibPath) == 0) { matchDylib = (struct dyld_cache_image_info*)&dylibs[i]; //NSLog(@"IsRiskModule 函数,匹配到 filename =%s",dylibPath); break; } } if (!matchDylib) { NSLog(@"IsRiskModule 函数,找不到 filename =%s",checkfname); munmap(p_map, vmPageSize); close(fd); return false; } uint64_t offset = 0; bool bMatch = false; for (int i = 0 ; i< cacheHeader->mappingCount; i++) { uint64_t StartAddress =mappings[i].address; if (matchDylib->address >= StartAddress){ uint64_t EndAddress = mappings[i].address +mappings[i].size; if (matchDylib->address <= EndAddress) { offset = matchDylib->address - mappings[i].address + mappings[i].fileOffset ; bMatch = true; break;; } } } if (!bMatch) { munmap(p_map, vmPageSize); close(fd); return false; } struct mach_header_64* matchHeader = (struct mach_header_64*)((uintptr_t)cacheHeader + offset); if(matchHeader->ncmds == 0) return false; struct segment_command_64 * matchCommand = (struct segment_command_64 *) ((char *)matchHeader + sizeof(struct mach_header_64)); struct segment_command_64 * matchTextCommand = NULL; for (int i =0; i< matchHeader->ncmds; i++) { if ((matchCommand->cmd == LC_SEGMENT_64) && (strcmp(matchCommand->segname, "__TEXT") == 0)) { matchTextCommand = matchCommand; break; } matchCommand =(struct segment_command_64 *) ((uint64_t)matchCommand + matchCommand->cmdsize); } if (!matchTextCommand) { munmap(p_map, vmPageSize); close(fd); return false; } if (matchTextCommand->vmsize != checkTextVmSize ) { munmap(p_map, vmPageSize); close(fd); return true; } bool bIsRisk = false; for (int i = 0; i< checkTextVmSize ; i++) { unsigned char Byte1 = *(unsigned char*) ((uint64_t)matchHeader+i); unsigned char Byte2 = *(unsigned char*) ((uint64_t)checkMachHeader+i); if (Byte1 != Byte2) { bIsRisk = true; NSLog(@"IsRiskModule 被污染的库,filename =%s,基地址 = 0x%llX,函数地址=0x%llX",checkfname,((uint64_t)checkMachHeader),(uint64_t)i); break; } } munmap(p_map, vmPageSize); close(fd); return bIsRisk; |