插件化—Hook-代理

2018-12-08  本文已影响110人  烬日沉香

1.什么是Hook?

hook英文翻译为钩子。
简单来说,hook技术就是劫持应用程序本要执行的对象或者方法,将其替换成你想要执行的。
如何实现hook技术,主要是通过反射和代理。
关于反射,大家都很熟悉,今天主要讲一下代理。

2.代理模式

代理这个词相信大家很熟悉,联想一下代购。A想要买SKII的神仙水,委托B去免税店买,B买到后寄给A,A就买到了神仙水。
代理模式的定义:给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。


image.png

从编码角度,代理模式分为静态和动态两种方式。静态代理是在代码运行前就已经存在了代理类的class文件,而动态代理则是在代码运行期间,通过反射来动态生成代理类的对象,以及让它去代理谁。

2.1静态代理

interface Shop {
    fun  buySKII()
}
class A :Shop {
    override fun buySKII() {
        System.out.println("A 买到SKII")
    }
}

class B :Shop {
    var a:Shop
     constructor(a:Shop){
        this.a=a
    }
    override fun buySKII() {
        System.out.println("B 去免税店购买")
        a.buySKII()
    }
}
 private fun  mainStatic(){
        //创建A
        val a= A()
        //创建代理类
        val b= B(a)
        //购买
        b.buySKII()
    }

2.2动态代理

A.kt 和Shop.kt类可以保持不变,重写代理人B为动态代理方式

class DyB :InvocationHandler {
   private var any:Any
    constructor(any:Any){
        this.any=any
    }
    @Throws(Throwable::class)
    override fun invoke(proxy: Any?, method: Method?, args: Array<Any>?): Any? {
        if (method?.name.equals("buySKII")){
            System.out.println("B 去免税店购买")
        }
        val result=method?.invoke(any, *(args?: arrayOfNulls(0)))
        return result
    }
}
 fun  mainDynamic(){
        //创建A购买者
        val a=A()
        //创建B代理类,持有a的对象
        val dyB=Dy(a)
        //类加载器
        val  loader=a.javaClass.classLoader
        //动态加载代理类  shop的buy方法会调用byB的invoke方法,
        val  shop=Proxy.newProxyInstance(loader, arrayOf(Shop::class.java),dyB) as Shop
        shop.buySKII()

    }

小结

1.hook可以劫持对象,写一个代理对象,通过hook的方式来劫持,我们就可以在代理对象中做一些自己设计的内容。
(如同上文代购的例子,B去免税店可以买很多东西,神仙水只是一部分而已。)

上一篇下一篇

猜你喜欢

热点阅读