Hook技术的知识点非常多,本章只涉及到插件化相关的部分,说到Hook技术就得先提到逆向工程,它主要的目的是在不能轻易的获取必要的生产信息的情况下,直接从成品分析,推导出产品的设计原理。逆向分析分为静态分析和动态分析,其中静态分析是一种在不执行程序的情况下对程序的行为进行分析的技术;动态分析是在程序运行时进行调试的技术。Hook技术就是属于动态分析。
Hook技术概述:
我们知道Android系统的代码调用和回调都是按照一定的顺序执行的,例如:对象A调用对象B,对象B处理之后将数据回调给对象A。而采用Hook技术之后为:
我们可以看到Hook可以是一个方法或者是一个对象,它就像是一个钩子一样挂在对象A和对象B之间(也可以说劫持),当对象A调用对象B之前做一些处理(比如修改方法的参数和返回值),起到了欺上瞒下的作用。 我们知道应用程序进程之间是相互独立的,应用程序进程和系统进程之间也是如此,Hook技术还可以在进程之间进行某些更改:
可以看到Hook可以将自己融入到它所劫持的对象所在的进程中,成为系统进程的一部分,这样我们就可以通过Hook来更改对象B的行为。被劫持的对象B也叫做Hook点,为了保证Hook的稳定性,Hook点一般选择容易找到而且不容易变化的对象,例如:静态变量和单例。
Hook技术分类:
Hook技术的知识点比较多,因此 Hook技术根据不同的角度会有很多种分类,这里介绍其中的三种分类:
- 根据Hook的API语言划分,分为Hook Java和Hook Native。Hook Java主要通过反射和代理来实现,应用于在SDK开发环境中修改Java代码· Hook Native 则应用于在NDK开发环境和系统开发中修改Native代码。
- 根据Hook的进程划分,分为应用程序进程Hook和全局Hook。应用程序进程Hook只能Hook 当前所在的应用程序进程。应用程序进程是Zygote 进程fock 出来的,如果对 Zygote进行Hook,就可以Hook系统所有的应用程序进程,这就是全局Hook。
- 根据Hook的实现方式划分,分为如下两种:通过反射和代理实现,只能Hook当前的应用程序进程。通过Hook框架来实现,比如Xposed,可以实现全局Hook,但是需要root。
Hook Native、全局 Hook和通过Hook框架实现这些分类和插件化技术关联不大,本章主要需要学习的是Hook Java,想要更好地学习Hook Java,首先要了解代理模式。
代理模式:
代理模式也叫委托模式,是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多,比如代购、代理上网、打官司等。定义:为其他对象提供一种代理以控制对这个对象的访问称为代理模式。
Hook startActivity方法:
我们知道Hook可以用来劫持对象,被劫持的对象叫做Hook点,用代理对象来替代Hook点,我们就可以在代理上实现自己想要做的操作。举例startActivity方法,其中startActivity方法分为两个,一个是Activity的startActivity方法,另一个是Context的startActivity方法。
我们从startActivity方法快进到Instrumentation类型的mInstrumentation对象的execStartActivity方法,其中Instrumentation类主要是用来监控应用程序和系统交互的,而execStartActivity方法主要调用了ActivityManager的getService方法来获取AMS的代理对象,接着调用AMS代理对象的startActivity方法。其中mInstrumentation是Activity的成员变量。我们就可以写出代理的Instrumentation来替代原始的Instrumentation来完成Hook。Context的startActivity方法也类似。
1.Hook startActivity总结:
Hook Context的startActivity方法和Hook Activity的startActivity方法的最大区别是替换的Instrumentation不同,一个是Activity的Instrumentation,一个是Activity Thread的Instrumentation。另外这些替换方法的调用都是在onCreate方法中调用的,这里未必是最佳的替换时间点,也可以尝试在Activity的attachBaseContext方法中进行Instrumentation替换,这个方法是比onCreate方法更快的被调用。简单来说就是,找到Hook点,再使用代理对象来替换Hook点。