Hook匹配过程----之一

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);
           }
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值