本来这篇文章应该在年前发布了,但碍于原神和星铁的更新就拖到了现在(xxx,你害人不浅啊),其次便是近几日在站内也看到了saidyou大佬对梆梆企业版的分析,想着快过年了也不着急,然后就拖到现在,所以就当是一个DLC补充包吧!
除去用于修复已加载到内存中的libDexHelper.so的ELF文件格式的init_proc函数和init_array函数中通过调用_cxa_atexit函数注册一些位于libDexHelper.so被卸载时调用的回调函数外,其重心就位于Jni_OnLoad中。
libDexHelper.so的分析如下:
其一先是对libc.so中函数进行hook,被hookd的函数和在分析样本中hook回调的偏移如下:
open、open_2、openat64、openat_2、mmap64、_close、read、write、pwrite64
0x51768、0x517D4、0x51840、0x518AC、0x5191C、0x51EDC、0x52060、0x52580、0x52B24
虽说也有看到其他的如针对于日志的Z11do_hook_logi
函数,但显得便没那么重要了。
其二便是我们最关心的检测分析,如下:
有针对于环境的检测,位于偏移0x33E6C的函数处(该函数因无法再ida中反汇编,所以只能通过文字的方式),具体检测下方所示:
调用 openat 中断访问/proc/self/attr/prev文件获取数值与字符串u:r:zygote:s0比对
调用 access 访问 /sbin/.core/mirror 是否存在
调用 access 访问 /data/local/su 是否存在
调用 access 访问 /data/local/bin/su 是否存在
调用 access 访问 /data/local/xbin/su 是否存在
调用 access 访问 /sbin/su 是否存在
调用 access 访问 /su/bin/su 是否存在
调用 access 访问 /system/bin/su 是否存在
调用 access 访问 /system/bin/.ext/su 是否存在
调用 access 访问 /system/bin/fail/safe/su 是否存在
调用 access 访问 /system/sd/xbin/su 是否存在
调用 access 访问 /system/usr/we-need-root/su 是否存在
调用 access 访问 /system/xbin/su 是否存在
调用 _system_property_get("ro.build.tags", resultAddr) 返回release-keys与test-kes比较

也有针对面具的检测如下所示:
偏移0x34870处调用 fork 创建子进程,访问 /proc/self/maps通过_memmove_chk拷贝maps每个内存段的信息,检测每一个带有tls标志的内存段的首地址,范围:内存段大小,如果发现存在"/.magisk/"或者是".MAGISK"字样的字符串,检测maps中所有的内存段之后,调用getpid获取当前子进程的pid并通过kill结束。
偏移 0x348F4 调用 fork 创建子进程,访问 /proc/self/maps通过_memmove_chk拷贝maps每个内存段的信息,检查带有[stack]标志、/memfd:标志、/system/bin/app_process标志、的内存段的首地址中是否存在字符串"/.magisk/"或者是".MAGISK",检测maps中所有的内存段之后,调用getpid获取当前子进程的pid并通过kill结束。
当然so中这么热闹怎么可能少了java端的检测呢,位于偏移0x453F8处调用fork创建子进程,通过execl 启动 /system/bin/app_process(zygote方式启动), 进程为com.secneo.apkwrapper.H,参数一是:"--write-fd",参数二是:"68",姑且粗略的看了下这个main函数中也有检测/proc/self/status文件


位于偏移0x3539C函数的函数检测CLASSPATH、hook框架、libart.so中的函数是否被修改,下方所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
if ( *v0 ){
v1 = 0LL;
do {
v2 = (unsigned __int8 )v0[v1 + 1];
v3 = ++v1;
}
while ( v2 );
if ( v3 >= 6 )
return inCaseForSaveEnvFileOrKill(128LL, 0xB6A287DELL, 4013LL); 直接br x12程序崩溃
}
|
_system_property_get("dalvik.vm.dex2oat-flags", resultAddr)返回的值与 --inline-max-code-units=0比对
偏移:4595C的函数(重命名为isExportFunctionExist)对目标so以绝对路径的方式通过mmap进行映射到maps中与原来已经在maps的so在内存中的导出函数进行比对前16个字节,如果比对不一致则返回1,否则返回0,如果maps没有这个so则返回0,如果maps中有这个so但没有这个要搜索的导出函数则返回-1
isExportFunctionExist(0x21, "libart.so", "_ZN3art6mirror9ArtMethod14RegisterNativeEPNS_6ThreadEPKvb")
isExportFunctionExist(0x21, "libart.so", "_ZN3art6mirror9ArtMethod16UnregisterNativeEPNS_6ThreadE")
isExportFunctionExist(0x21, "libart.so", "_ZN3art9ArtMethod14RegisterNativeEPKvb")
isExportFunctionExist(0x21, "libart.so", "_ZN3art9ArtMethod16UnregisterNativeEv")
isExportFunctionExist(0x21, "libart.so", "_ZN3art9ArtMethod14RegisterNativeEPKv")
isExportFunctionExist(0x21, "libart.so", "_ZN3art11ClassLinker14RegisterNativeEPNS_6ThreadEPNS_9ArtMethodEPKv")
isExportFunctionExist(0x21, "libart.so", "_ZN3art11ClassLinker16UnregisterNativeEPNS_6ThreadEPNS_9ArtMethodE")
isExportFunctionExist(0x21, "libart.so", "_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE")
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!