PMS 是系统服务,是没办法进行Hook的。只能修改它在Android App进程中的代理对象,它是PackageManager对象,很多类中都有这个代理对象的身影,比如 Activityhread中,字段sPackageManager; 以及ApplicationPackageManager中,mPM字段。
public class HookHandler implements InvocationHandler { private Object mBase; public HookHandler(Object base){ this.mBase = base; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Log.i("msg","method name="+method.getName()); return method.invoke(mBase,args); } }
public static void hookPackageManager(Context context){ try{ Object currentActivityThread = ReflectUtil.getStaticFieldObject("android.app.ActivityThread","sCurrentActivityThread"); Object sPackageManager = ReflectUtil.getFieldObject("android.app.ActivityThread",currentActivityThread,"sPackageManager"); Class> iPackageManagerInterface = Class.forName("android.content.pm.IPackageManager"); Object proxy = Proxy.newProxyInstance(iPackageManagerInterface.getClassLoader(),new Class>[]{iPackageManagerInterface}, new HookHandler(sPackageManager)); // 1. 替换掉ActivityThread里面的 sPackageManager 字段 ReflectUtil.setFileObject("android.app.ActivityThread",currentActivityThread, "sPackageManager", proxy); //替换 ApplicationPackageManager里面的 mPm对象 PackageManager pm = context.getPackageManager(); ReflectUtil.setFileObject("android.app.ApplicationPackageManager",pm,"mPM",proxy); }catch (Exception e){ e.printStackTrace(); } }
Android的四大组件和AMS通信都是通过ActivityManagerNative进行的。
比如App调用startActivity方法。
ActivityManagerNative.getDefault().startActivity().
再比如,发送消息使用sendBroadcast().
ActivityManagerNative.getDefault().broadcastIntent().
ActivityManagerNative.getDefault()其实调用了单例Singleton的get方法,获得了Singleton的mInstance字段,我们可以把mInstance字段替换成自己的逻辑。
public static void hookActivityManagerNative(){ try{ Object gDefault = ReflectUtil.getStaticFieldObject("android.app.ActivityManagerNative","gDefault"); Object activityManager = ReflectUtil.getFieldObject("android.util.Singleton",gDefault,"mInstance"); Class> activityManagerInterface = Class.forName("android.app.IActivityManager"); Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class>[] {activityManagerInterface}, new HookHandler(activityManager)); ReflectUtil.setFileObject("android.util.Singleton",gDefault,"mInstance",proxy); }catch (Exception e){ e.printStackTrace(); } }
该Hook 方式只能在Android sdk 为25及以下的版本上才能Hook.