当年感觉魔趣的列表动画挺有意思,后来发现xuimod这个
xposed
模块,玩过一阵,现在已经这么些年没更新了,既然没人,那我就自己尝试写写吧。
少废话,先看成品
还有个京东APP的图传不上,CSDN不允许外链,强制上传到他们的服务器。
代码:github
基础方法
注意点
ClassCastException
尝试将一个变量强转为想要的类型时,例如我强转hook来的obj
类型的变量为RecyclerView
,这个obj虽然是这个类型,但是它是由宿主APP进程加载完成的,classLoader假设称为com.a.b.c.loader
,而这个强转代码是写在我们插件APP中的,classLoader可能为com.d.f.e.loader
,而不同loader是不能强转的。
一篇好文供参考Tips for writing Xposed Module to Hook Android App’s Methods
但是Java基础类型和String类以及Android基础类能豁免(至少View
没问题)。
XposedBridge
的一些常用方法
[图片上传失败…(image-211888-1609148847130)]
XposedHelper
的主要方法
[图片上传失败…(image-d6a56e-1609148847130)]
示例
// 注入到TextView的setTextColor方法
XposedHelpers.findAndHookMethod(textViewClass, "setTextColor", Int::class.java, object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam?) {
// 会在第一行代码执行前调用
}
override fun afterHookedMethod(param: MethodHookParam?) {
// 会在最后一行代码执行前调用
}
})
class的获取
有两种方法(以TextView为例)
-
直接
TextView::class.java
这种可能会遇到ClassLoader问题,见注意点1
-
使用 辅助方法
[图片上传失败…(image-7e9d9d-1609148847130)]
当然,传个那么长的
className
也太累了,可以直接传入TextView::class.java.name
classLoader
就是handleLoadPackage
这个方法的参数,每个APP,不对,应该说每个进程启动都会回调这个方法,因为发现有些比如:pushservice
启动它也会回调。
方法的Hook
示例中是理想情况,因为这个方法的参数恰好是基础类型,假如不是呢?
-
想办法获取到对应类型的对象,再用其class作为参数调用这个方法
-
使用
XposedBridge
的hookAllMethods
XposedBridge.hookAllMethods(recyclerViewClass, "setAdapter", object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam?) { // WRITE YOUR CODE HERE } })
类或者方法被混淆
Android四大组件和View相关的类不会被混淆,所以我们发挥的空间其实很大,但是谷歌的代码越来越封闭,一发现能往View
外抽,就独立成一个内部类,然后这个内部类就被混淆了。
获取混淆类
- 通过
View
相关的类的全局变量实例获取
尝试过程
尝试1 将APP原有的Adapter
塞入自定义的AnimationAdapter中
由于ClassLoader
的问题告终。但正是这里学到了ClassLoader
的相关知识。
尝试2 在setAdapter
内 Hook
onBindViewHolder
val adapterClazz = XposedHelpers.findClass(RecyclerView.Adapter::class.java.name,lpparam)
// hook setAdapter方法
XposedHelpers.findAndHookMethod(recyclerViewClazz, "setAdapter",adapterClazz, object : XC_MethodHook() {
overr