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;