大部分对hook的检测还是比较依赖系统 api 或者改动hook框架很容易就失效。
比如检测libxxx.so,命名空间,指定类等等。
我在这里提出一种检测思路:
对比内存中的.text段和文件中的.text的crc是否相等。
大致流程:
1.解析/proc/self/maps。
2.匹配到你需要检测的so文件,获取其的加载基地址和文件路径。
3.通过mmap将文件映射到内存,然后把内容传给ELF解析工具,获取其.text段的偏移和大小 。
4.通过偏移+加载基地址 和 偏移+mmap返回值 以及.text段大小来计算crc,并比对。
这种方式最好放到线程里面去做,缺陷是app自身不能使用inline hook,否则也会被检测到。
针对xposed hook、frida hook的检测话,还有一种方法,就是被xposed hook的Java方法修饰符都会变成native,
以getPackageInfo的检测代码示例:
void check_native_modifier_task(__int64 addr){
int check_time = 10;
while (1) {
if((~*(_DWORD *)(addr + 4) & 0x80000) !=0){
// find xposed, frida hook.
break;
}else if(check_time < 0){
break;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
check_time = check_time - 1;
}
}
JNICALL void check_native_modifier(JNIEnv *env){
jclass packageManagerClass = env->FindClass("android/content/pm/PackageManager");
jmethodID getPackageInfoMethodID = env->GetMethodID(packageManagerClass,"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
thread checkThread = std::thread(check_native_modifier_task, getPackageInfoMethodID);
checkThread.detach();
env->DeleteLocalRef(packageManagerClass);
}