插件开发之360 DroidPlugin源码分析(五)Service预注册占坑
请尊重分享成果,转载请注明出处:
http://blog.csdn.net/hejjunlin/article/details/52264977
在了解系统的activity,service,broadcastReceiver的启动过程后,今天将分析下360 DroidPlugin是如何预注册占坑的?本篇文章主要分析Service预注册占坑,Service占了坑后又是什么时候开始瞒天过海欺骗AMS的?先看下Agenda:
- AndroidMainfest.xml中概览
- Service中关键方法被hook时机
- startService被hook
- 瞒天过海流程图
- 认识ServiceManager
AndroidMainfest.xml中概览
android:process=”:PluginP02” 表示自定义一个名为PluginP02的进程,该属性一旦设置, 那么App启动之后, Service肯定会以远程服务方式启动, —- 可通过adb shell ps 就可以看到有一个独立的进程启动了.
项目 Package为 com.morgoo.droidplugin , 并设置 android:process=”:PluginP02”, 那么App运行时, 通过 adb shell ps | grep com.morgoo.droidplugin , 可以看到有两个进程:
startService被hook
IActivityManagerHookHandle.startService方法
replaceFirstServiceIntentOfArgs()
接下来我们继续回到StartService类中,看下afterInvoke方法
stopService,bindService,unbindService,setServiceForeground都是类似逻辑,可从源码中证实。
在前一篇《插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑》,我们曾了解到,8个进程中的service在预注册占坑,在AndroidManifest.xml中只有一个,那如果插件要启动多个service怎么办?这是第一个问题,而我们知道所有和服务相关的都要在系统的systemServer进程中进行注册,难道DroidPlugin要逆天的本事?这是第二个问题
我们从代码中发现有一个ServceManager,这和android系统中大管家ServiceManager相差一个i,难道要改大管家的职责?又多了一个疑惑
仔细看了下ServceManager中的代码:
以上代码可总结为:(以虚线分上下两部分)
1.上部分主要是ServceManager单例及有一个handleXXX相关的方法,下部分主要是Service的一些生命周期方法。
2.我们基本可以确定之前问题2和问题3的答案了,没有那么逆天的本事来操作ServiceManager,也不能修改大管家ServiceManager的职责
3.那问题又来了,这个类到底是做啥的?还起一个叫ServceManager的名字,
以hanldeOnTaskRemoveOne方法为例看看:
接着再看下ServceManager中的onBind方法:
然后调到handleOnBindOne方法中,我们前面分析了一个handleOnTaskRemovedOne方法,下面1-7步骤套路都是一样,主要在return时,直接调用service自身的onBind了,这和我们平时在Activity中new Intent,然后把这个intent传到onBind中.
那么问题来了,还要这么一个类倒腾来干啥呢?还记得上面有一处逻辑service为null时,就调用了handleCreateServiceOne,好戏在这里:
看了上面的分析后,我们再去回想第一个问题,那如果插件要启动多个service怎么办?不知道不没有注意到mTokenServices,mNameService,mServiceTaskIds这些成员变量,它们都是Map,key不一样,value全是Service,如个有多个service在插件中启动了,mTokenServices,mNameService,mServiceTaskIds这些成员变量分别掌握了Service的Token,name,及任务id(通过token拿到的)。那岂不是已经在管理这些多个service了。至于附属于这个类起的名字,叫什么都无所谓。
以上可用如下流程图表示:
前面一直有个问题解释的不彻底,就是问题3,ServceManager是否担当了修改系统大管家ServiceManager的职责?接下来,我们就稍微了解下系统大管家ServiceManager是做什么的?(PS: ServiceManager和Binder机制一样,不是一天两个就能研究的清楚的)
认识ServiceManager
Android系统Binder机制的总管是ServiceManager,所有的Server(System Server)都需要向它注册,应用程序需要向其查询相应的服务。平时,我们在studio上的DDMS中调试程序时,下图这个就是ServiceManager
这里以Java层加入ServiceManager及getService为数据流分析一下。
复习一下典型的Binder模式,有利于后面的理解:
1、客户端通过某种方式得到服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差别。它可以像其他本地对象一样调用其方法,访问其变量。
2、客户端通过调用服务器代理对象的方法向服务器端发送请求。
3、代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。
4、服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。
5、客户端收到服务器端的返回结果。
JAVA层代码分析:
ServiceManager.java (frameworks\base\core\java\android\os)
对于xxxManager获取服务端service基本如此用法:
举例:
利用ContextImpl.java中的 public Object getSystemService(String name)
然后再调用:ServiceManager.getService(ServiceName);获取相应的服务端
知道了客户端获取一个Service的方法之后,我们回到ServiceManager的服务端:
BinderInternal.getContextObject() @ BinderInternal.java 是一个native 函数:
android_os_BinderInternal_getContextObject @ android_util_Binder.cpp
返回一个 BinderProxy对象保存到类成员mRemote(ServiceManagerProxy类成员)
public abstract class ServiceManagerNative extends Binder implements IServiceManager
ServiceManagerNative 继承自 Binder 并实现了 IServiceManager 接口,利用 asInterface()则提供一个 ServiceManagerProxy 代理对象使用
class ServiceManagerProxy implements IServiceManager
定义了类ServiceManagerProxy(代理),ServiceManagerProxy继承自IServiceManager,并实现了其声明的操作函数,只会被ServiceManagerNative创建,它实现了IServiceManager的接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。
上面代码总结如下:Java层先利用Parcel对象将数据进行序列化,然后利用transact将数据传给binder驱动,就是上面mRemote.transact,mRemote在JNI层是一个叫BpBinder的对象:
JNI层代码分析:
android_util_Binder.cpp
每当我们利用BpBinder的transact()函数发起一次跨进程事务时,其内部其实是调用IPCThreadState对象的transact()。BpBinder的transact()代码如下:
到此,不再向下深究,具体想了解可以看Binder机制及IPC相关内容。
所以,到这把第2个问题彻底弄明白了,ServceManager和ServiceManager根本不是一回事。到次,Service的瞒天过海得以实现,接着,就是介绍时候说的那样无需修改源码,多进程,多service等功能。另外ContentProvider及BroadCast原理是类似,不再进行分析。
下篇将开始分析包管理(宿主插件和插件包名有什么规则),APK解析(为什么可以免安装),进程管理(能确保隐藏起来,不会在process轻易被kill)
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
插件开发之360 DroidPlugin源码分析(五)Service预注册占坑的更多相关文章
- 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...
- 插件开发之360 DroidPlugin源码分析(一)初识
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52123450 DroidPlugin的是什么? 一种新的插件机制,一种免安装的运行机制 ...
- 插件开发之360 DroidPlugin源码分析(三)Binder代理
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52138483 Hook机制中Binder代理类关系图 Hook机制中Binder代理时 ...
- 插件开发之360 DroidPlugin源码分析(二)Hook机制
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52124397 前言:新插件的开发,可以说是为插件开发者带来了福音,虽然还很多坑要填补, ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- ABP源码分析五:ABP初始化全过程
ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...
- MPTCP 源码分析(五) 接收端窗口值
简述: 在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理. 接收端窗口值的初始化 ...
- Vue系列---理解Vue.nextTick使用及源码分析(五)
_ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...
- vuex 源码分析(五) action 详解
action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...
随机推荐
- [Luogu 1730]最小密度路径
Description 给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量). ...
- ●Codevs 4158 残缺的字符串
题链: http://codevs.cn/problem/4158/ 题解: FFT. 定义两个相同长度的字符串s1,s2的距离为 $$dis(s1,s2)=\sum_{i=0}^{len-1}(s1 ...
- 【线段树】【BZOJ1798】【AHOI2009】维护序列
还是那个学弟@lher出的丧题之一. 链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题意简析:就是题目啊... 解题思路:显然是线段树 ...
- 基于Android的高校饮水宝app
这是一个高校饮用水配送项目,是一个毕业设计,去年的,包括了服务端和客户端,是一个不错的项目,分享一下: 随着通讯行业的迅猛发展,我国的手机用户也在不断的增加.据信息部的统计数据显示,我国已有接近7. ...
- day5 liaoxuefeng---virtualenv、图形界面、网络编程、电子邮件
一.virtualenv 二.图形界面 三.网络编程 四.电子邮件
- 如何让Mac、Windows可以互相远程
您可以通过Mac来远程Windows桌面:也可通过Windows来远程Mac界面:甚至还可以通过iOS或Android来远程Mac或Windows. Windows的操作方法,以Windows XP ...
- C# 枚举在项目中使用心得
阅读目录 基本介绍 使用注意 使用方法 扩展用法 本文主要是我在项目中对C#枚举的使用心得,如有不足的地方欢迎您指出. 一.基本介绍 枚举是由一组特定常量构成的一组数据结构,是值类型的一种特 ...
- Maven集成dubbo时报错 Missing artifact com.alibaba:dubbo:jar:2.8.4
1.下载dubbo,地址:https://github.com/dangdangdotcom/dubbox . 2.将下载的压缩包解压. 3.命令行进入下载路径,执行mvn install -Dmav ...
- Quartz + Tablesaw 报表统计
场景 在12 月份做的报表功能中,直接从 ES 查询一个月的数据.当数据量特别大时,查询速度会非常缓慢甚至查询失败.解决方案是使用定时任务,在每天凌晨指定时间自动查询前一天的数据,然后写入 CSV 文 ...
- zabbix API基本使用方法介绍
前言: 以下内容根据zabbix 3.2官方文档总结:https://www.zabbix.com/documentation/3.2/manual/api 此文档只是简单的介绍API的基本使用,关于 ...