在插件中,需要禁止插件调用系统原生接口持有WakeLock,Hook技术是不错的解决方案。
通过阅读系统源码,可以了解到PowerManager持有WakeLock操作最后都通过Binder跨进程调到系统服务中,我们只要拦截这个Binder的所有调用即可。
思路是先通过反射拿到这个IPowerManager的Binder,然后动态生成该Binder的代理对象,再覆盖原有的Binder即可。
public class PowerManagerHook {
public static void hook(Context context) throws Throwable {
PowerManager manager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
Field field = FieldUtils.getField(PowerManager.class, "mService", true);
BinderHook hook = new BinderHook(field.get(manager), new BinderHook.BinderHookInvoker() {
@Override
public Object onInvoke(Object original, Method method, Object[] args) throws Throwable {
return method.invoke(original, args);
}
});
field.set(manager, hook.proxyInterface);
}
}
以下BinderHook是一个关于Binder Hook的通用类,可用于各类Android系统服务的Binder的Hook。
接下来介绍一下Binder Hook的核心原理,我们拿到Binder对象之后,首先要将其转成业务接口类,通常是通过Stub.asInterface,而Binder对象可能是Binder实体,也可能是Binder Proxy&#