6,BroadcastReceiver Hook
BroadcastReceiver过程在插件加载时论述过,并且在插件加载的过程中完成。
LoadedPlugin的构造方法中有关BroadcastReceiver方法如下,
Map<ComponentName, ActivityInfo> receivers = new HashMap<ComponentName, ActivityInfo>();
for (PackageParser.Activity receiver : this.mPackage.receivers) {
receivers.put(receiver.getComponentName(), receiver.info);
try {
BroadcastReceiver br = BroadcastReceiver.class.cast(getClassLoader().loadClass(receiver.getComponentName().getClassName()).newInstance());
for (PackageParser.ActivityIntentInfo aii : receiver.intents) {
this.mHostContext.registerReceiver(br, aii);
}
} catch (Exception e) {
e.printStackTrace();
}
}
this.mReceiverInfos = Collections.unmodifiableMap(receivers);
this.mPackageInfo.receivers = receivers.values().toArray(new ActivityInfo[receivers.size()]);
广播好像和其他三大组件有些不同,中间多了一个注册过程。
this.mHostContext.registerReceiver(br, aii);
就是将插件中的所有静态广播全部注册成动态广播。
为什么其他三个组件不行,因为其他三个组件必须在必须在AndroidManifest.xml中显式声明要启动的Activity。
所以说,广播的Hook最容易,但是有一个限制,因为静态广播当做动态处理,所以插件未启动时是无法接收对应的静态广播的。
7,四大组件小结
VritualApk框架Hook 四大组件方案如下,
Activity:在宿主apk中提前占几个坑,然后通过“欺上瞒下”的方式,启动插件apk的Activity;因为要支持
不同的launchMode以及一些特殊的属性,需要占多个坑。
主要是通过VAInstrumentation完成。
Service:通过代理Service的方式去分发;主进程和其他进程,VirtualAPK使用了两个代理Service,有周期管理。
主要是通过ActivityManagerProxy完成。
BroadcastReceiver:静态转动态。
ContentProvider:通过一个代理Provider进行分发,无周期管理。主要是通过PluginContentResolver完成。