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; |