继续胡乱分析
接下来看下下面的这段代码:
这里要注意,静态代码块 和 静态变量 的初始化都发生在类装载 的时候,级别是相同的,会按照代码顺序进行初始化。
这段代码是检验手机是否安装了xposed的一个套路之一,逻辑是:
当 XposedDetectionUtil 类被调用时,加载,然后显式抛出一个异常, 然后catch这个异常,通过e.getStackTrace获得一个异常调用的堆栈信息, 然后遍历这个堆栈,如果出现了包含XposedBridge的类名或者方法,就说明 用户的手机安装了xposed。
这里其实有个小疑问,为何if里没有代码,是因为反编译没有获得完整代码, 还是这样做就可以了,有知道的看官可以告知下!!!
看到这里,应该基本会想到一个套路:Hook掉getStackTrace()方法 点进去看下这个方法的具体详情:
看完之后,很容易Get到几个点:
- 1.Hook的完整类名是:java.lang.Throwable
- 2.Hook的方法是:getStackTrace,该方法返回的是StackTraceElement[]
- 3.只需要过滤一波返回值,去掉包含XposedBridge的类名或者方法然后重置下即可。
思路又有了,写一波代码~
Hook getStackTrace方法
这里要吐槽一波Kotlin,getStackTrace方法返回的是数组嘛,需要用as Array<StackTraceElement>
强转一波,然后呢,Array类里只有 几个寒碜的方法:
2333,对的,没有移除元素的方法,So,需要借用另一个可变的容器来装, 于是要创建一个可变列表,mutableListOf<StackTraceElement>()
, 然后遍历这个数组,把不包含XposedBridge的类和方法装到里面, 遍历完以后,还需要把这个可变集合再强转一波:toArray<StackTraceElement>()
然后重置下返回的结果。
所以有了这样的一串代码:
运行下重启手机,打开下厨房,检验下效果:
同时看下Logcat打印的日志信息:
到此就Hook完成了,抱歉,Xposed真的可以为所欲为。
小结
因为下厨房一直弹安装了Xposed的警告,所以有了这篇文章。 检测是否安装了Xposed可以不止这种套路,更多的可以翻阅:Android Java 层的anti-Hook 技巧.md
附:Hook部分代码(都可以在:github.com/coder-pig/C… 找到):
object XiaChuFangHook{ fun hook(lpparam: XC_LoadPackage.LoadPackageParam) { findAndHookMethod("java.lang.Throwable", lpparam.classLoader, "getStackTrace", object : XC_MethodHook() { override fun afterHookedMethod(param: MethodHookParam) { val result = mutableListOf<StackTraceElement>() for (stackTraceElement in (param.result as Array<StackTraceElement>)) { val className = stackTraceElement.className val methodName = stackTraceElement.methodName if(className != null && methodName != null) { if(!className.contains("XposedBridge") && !methodName.contains("XposedBridge")) { result.add(stackTraceElement) } } } param.result = toArray<StackTraceElement>(result) super.afterHookedMethod(param) } }) } }