Android hook实例
hook核心逻辑
hook的基本思路就是 拦截原调用逻辑,加入自己新增的逻辑,然后再执行原逻辑。
技术实现方案通常是 反射 + 动态代理。
怎么寻找hook点 ?
hook点的优先级为:
单例>静态类>public final
Android常用hook点
- Aidl传递的时候hook
- handler消息传递时hook
- 使用动态代理hook
使用场景:比如Android插件化,需要将代理Activity修改为Manifest中注册过的实际Activity。
代码示例
以下代码是模拟Android ActivityManager调用 startActivity方法的流程:
- 改动前,startActivity传递的参数为1
- 增加hook后,将入参1改为2
结果判断
通过判断 startActivity 的日志打印来判断 hook是否生效。
- 若打印 start:1 ,则hook无效,代码正常调用
- 若打印 start:2 ,则hook生效,参数被修改
- 其他情况均代码运行错误
public class HookTest {@Testpublic void test() throws Throwable {//保证单例创建ActivityManager.getService();//hook调用initHook();//调用startActivityActivityManager.getService().startActivity(1);}private void initHook() throws Throwable {Class<?> activityManager = Class.forName("com.iflytek.edu.apm.collector.hook.ActivityManager");Field IActivityManagerSingleton = activityManager.getDeclaredField("IActivityManagerSingleton");IActivityManagerSingleton.setAccessible(true);Object singleton = IActivityManagerSingleton.get(null);Class<?> singletonClass = Class.forName("com.iflytek.edu.apm.collector.hook.Singleton");Field instanceField = singletonClass.getDeclaredField("mInstance");instanceField.setAccessible(true);final Object rawActivityManager = instanceField.get(singleton);Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{IActivityManager.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("startActivity")) {args[0] = 2;}return method.invoke(rawActivityManager, args);}});instanceField.set(singleton, proxy);}
}
public abstract class Singleton<T> {private T mInstance;protected abstract T create();public final T get() {synchronized (this) {if (mInstance == null) {mInstance = create();}return mInstance;}}
}
interface IActivityManager {void startActivity(int a);
}
class ActivityManagerIpml implements IActivityManager {@Overridepublic void startActivity(int a) {System.out.println("start:" + a);}
}
class ActivityManager {public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IActivityManager am = new ActivityManagerIpml();return am;}};
}