Hook匹配过程----之一

来源:互联网 发布:谷歌人工智能 开源 编辑:程序博客网 时间:2024/06/10 15:01

8 Hook匹配过程

1, activity

IpackageManagerHookHandle中Hook了resolveIntent和queryIntentActivities方法,也就是activity 的匹配过程只需要看这2个方法,

resolveIntent的beforeInvoke方法有关代码如下,

ResolveInfo info = PluginManager.getInstance().resolveIntent(intent, resolvedType, flags);

queryIntentActivities的afterInvoke方法有关代码如下,

List<ResolveInfo> infos = PluginManager.getInstance().queryIntentActivities(intent, resolvedType, flags);

2,Service

IpackageManagerHookHandle中虽然也Hook了resolveService和queryIntentServices方法, 但是启动的还是注册的代理Service,

然后在代理Service中匹配原来的service。

还是看一下,

resolveService的beforeInvoke方法有关代码如下,

ResolveInfo info = PluginManager.getInstance().resolveService(intent, resolvedType, flags);

queryIntentServices的afterInvoke方法有关代码如下,

List<ResolveInfo> infos = PluginManager.getInstance().queryIntentServices(intent, resolvedType, flags);

在前面论述的恢复Service过程中,是利用ServcesManager的方法。

首先在ServcesManager的onStart方法中,

Intent targetIntent = intent.getParcelableExtra(Env.EXTRA_TARGET_INTENT);if (targetIntent != null) {    ServiceInfo targetInfo = PluginManager.getInstance().resolveServiceInfo(targetIntent, 0);

调用resolveServiceInfo的相关信息。

然后在handleCreateServiceOne方法中,

ResolveInfo resolveInfo = hostContext.getPackageManager().resolveService(stubIntent, 0);

和resolveService的beforeInvoke方法完全一样。

3, BroadcastReceiver

对于广播来说,主要将广播注册上去了,就和真正的广播没有什么区别。IpackageManagerHookHandle中Hook了queryIntentReceivers方法。

queryIntentReceivers的afterInvoke方法如下,

List<ResolveInfo> infos = PluginManager.getInstance().queryIntentReceivers(intent, resolvedType, flags);

4,ContentProvider

IpackageManagerHookHandle中Hook了resolveContentProvider方法。但是启动的还是注册的代理ContentProvider,

然后在代理ContentProvider中匹配原来的ContentProvider。

resolveContentProvider的afterInvoke方法如下,

ProviderInfo info = PluginManager.getInstance().resolveContentProvider(name, flags);

在AbstractContentProviderStub的query/insert/delete/update等方法中都会利用targetAuthority调用getContentProviderClient

获取真实的ContentProviderClient对象,

String targetAuthority = uri.getQueryParameter(Env.EXTRA_TARGET_AUTHORITY);if (!TextUtils.isEmpty(targetAuthority) && !TextUtils.equals(targetAuthority, uri.getAuthority())) {    ContentProviderClient client = getContentProviderClient(targetAuthority);

getContentProviderClient方法主要逻辑如下,

targetInfo = PluginManager.getInstance().resolveContentProvider(targetAuthority, 0);

和resolveContentProvider的afterInvoke方法逻辑完全相同。

8.1 Activity 匹配

PluginManager的resolveIntent方法调用流程图如下,


PluginManager是一个单例模式,并且只是客户端,类似于android系统的API接口,真正实现方法是在服务端IpluginManagerImpl中, 

IpluginManagerImpl的resolveIntent方法如下,

List<ResolveInfo> infos = IntentMatcher.resolveIntent(mContext, mPluginCache, intent, resolvedType, flags);if (infos != null && infos.size() > 0) {     return IntentMatcher.findBest(infos);}

首先调用IntentMatcher的resolveIntent方法查询匹配的intent,然后调用findBest方法返回最匹配的结果, findBest直接返回infos中的第一个元素。

主要看IntentMatcher的resolveIntent方法。resolveIntent主要逻辑如下,

1,对于有包名的intent,直接查找插件对应的包名的PluginPackageParser。

PluginPackageParser parser = pluginPackages.get(comp.getPackageName());if (parser != null) {   queryIntentActivityForPackage(context, parser, intent, flags, list);

2,否则,对于每一个插件都得去匹配一下intent,展开地毯式搜索。

for (PluginPackageParser parser : pluginPackages.values()) {   queryIntentActivityForPackage(context, parser, intent, flags, list);    queryIntentServiceForPackage(context, parser, intent, flags, list);    queryIntentProviderForPackage(context, parser, intent, flags, list);    queryIntentReceiverForPackage(context, parser, intent, flags, list);}

queryIntentActivityForPackage主要逻辑如下,

1,获取插件中的所有Activity

List<ActivityInfo> activityInfos = packageParser.getActivities();

2,获取每个Activity的所有IntentFilter,

if (activityInfos != null && activityInfos.size() >= 0) {   for (ActivityInfo activityInfo : activityInfos) {        ComponentName className = new ComponentName(activityInfo.packageName, activityInfo.name);        List<IntentFilter> intentFilters = packageParser.getActivityIntentFilter(className);

都是利用packageParser中的变量,这些变量在解析完成时赋值的。

3,对IntentFilter匹配

if (intentFilters != null && intentFilters.size() > 0) {    for (IntentFilter intentFilter : intentFilters) {         int match = intentFilter.match(context.getContentResolver(), intent, true, "");         if (match >= 0) {             ActivityInfo flagInfo = packageParser.getActivityInfo(new ComponentName(activityInfo.packageName, activityInfo.name), flags);             if ((flags & PackageManager.MATCH_DEFAULT_ONLY) != 0) {                  if (intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) {                      ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter);                      resolveInfo.match = match;                      resolveInfo.isDefault = true;                      outList.add(resolveInfo);                   } else {                   //只是匹配默认。这里也算匹配不上。               }           } else {           ResolveInfo resolveInfo = newResolveInfo(flagInfo, intentFilter);           resolveInfo.match = match;           resolveInfo.isDefault = false;           outList.add(resolveInfo);           }     }}
原创粉丝点击