想在app里面做一个hook检测的功能,发现网上很多方法都抛出异常,判断是否包含已知xposed框架的包名来判断是否被hook,例如
private static boolean findHookStack() {
try {
throw new Exception("findhook");
} catch (Exception e) {
int zygoteInitCallCount = 0;
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
if (stackTraceElement.getClassName().equals("com.android.internal.os.ZygoteInit")) {
zygoteInitCallCount++;
if (zygoteInitCallCount == 2) {
Log.wtf("HookDetection", "Substrate is active on the device.");
return true;
}
}
if (stackTraceElement.getClassName().equals("com.saurik.substrate.MS$2")
&& stackTraceElement.getMethodName().equals("invoked")) {
Log.wtf("HookDetection", "A method on the stack trace has been hooked using Substrate.");
return true;
}
if (stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge")
&& stackTraceElement.getMethodName().equals("main")) {
Log.wtf("HookDetection", "Xposed is active on the device.");
return true;
}
if (stackTraceElement.getClassName().equals("de.robv.android.xposed.XposedBridge")
&& stackTraceElement.getMethodName().equals("handleHookedMethod")) {
Log.wtf("HookDetection", "A method on the stack trace has been hooked using Xposed.");
return true;
}
}
}
return false;
}
但这种方式有一个明显的缺陷:如果用的不是黑名单里面的xposed就无法检测。比如VirtualXposed或者自己写的xposed框架。
我的做法是白名单机制
在正常情况下,抛出一个异常在堆里面的包名只能是以下几种
- com.android.*
- java.lang.*
- android.*
- 你自己的包名.*
例如
Screenshot_2021-10-26-17-42-55-08_95aa516323de415b9f5b6de6e6c2f409.jpg
如果出现别的情况就说明可能被hook了,作出对应的处理即可
Screenshot_2021-10-26-17-42-50-53_1e02f244140d35208d88f4227e59c786.jpg
代码如下
class HookUtil {
companion object{
/**
* 是否被hook了
*/
fun isHook(context: Context): Boolean {
val whiteList = listOf(
"com.android",
"java.lang",
"android",
context.packageName
)
try {
throw Exception("gg")
} catch (e: Exception) {
e.stackTrace.forEach { element ->
if (!whiteList.map {
element.className.startsWith(it)
}.contains(true)) {
return true
}
}
}
return false
}
}
}
网友评论