1. 自启动管控 需求来源
自启动、关联启动、交叉启动、推送启动等现象的泛滥除了对个人信息保护带来隐患外,还会导致占用过多的系统CPU和内存资源,造成系统卡顿、发热、电池消耗过快;还可能引入一些包含"恶意代码"的进程在后台隐蔽启动,避开了杀毒软件等的查杀,威胁到用户通信秘密、财产安全。
2. 关联启动现象
2.1 常见的问题
1.【全家桶启动现象 】原生机器中,打开一个百度地图,放置一段时间后发现百度助手、百度新闻、去哪儿、美团等 APP后台自启动甚至弹出消息提醒?
·除此之外腾讯系、阿里系应用也会有。因为日活率是一款App的核心绩效指标,日活量不仅反应了应用的受欢迎程度,同时反应了产品的变现能力,进而直接影响盈利能力和企业估值。App会利用保活技术 尽量可能自启动本身和家族内其他应用。
2.为什么应用可以在用户不知情的情况后台自动运行?
·因为Android的理念是开放的, 应用拥有太多自主权限:前台保活、系统唤醒、推送服务。下文会介绍。
2.2 关联启动的树形图
App启动基础 :Android 四大组件Activity\BroadCast\Service\ContentProvid是App启动的基本单元,大部分APP会直接或间接地依赖于这四种方式进行启动。
启动分为用户知情和用户不知情2种情况:
·用户知情:
1.用户主动在Launcher界面打开APP
2.APP1 点击分享网页到 APP2
3.Android-语音助手打开 APP2
4.Android GCM 推送弹出 APP2 通知
5.等等 对于用户知情的场景,我们不需要进行管控。
·用户不知情:
1.APP1 利用1x1像素点创建很难被看见界面使用startActivity形式来启动 APP-X
2.APP1 利用开机、亮灭屏、解锁、push sdk、网络变化、USB插拔、时区变化、电量变化等广播事件使用sendBroadCast形式启动 APP-X
3.APP1 利用push sdk、同步服务、JobScheduler服务、服务重启等事件使用bindService/startService 启动 APP-X
4.APP1 利用push sdk、账号服务等事件使用contentProvider 启动 APP-X
即1个应用可以在不同事件以多种启动形式关联启动多个应用,像传染病 一样在我们不知情的情况下在后台大量启动一些可能没必要启动的应用。这种滥用自启动的行为,危害系统性能,功耗和安全。
3. 自启动管控方案
3.1 方案集成形式
少量framework 插桩事件的patch +策略 jar包+apk 集成到项目
3.2 自启动工作流
自启动管控在AMS中Activity、BroadCast、ConcentProvider、Service等涉及应用启动相关的函数进行事件插桩(目前18处),且每个事件插桩对应一个拦截相关策略,汇合并构成自启动的拦截与放行方案。
拦截的思想:用户可见或可感知或进程优先级高的进程不管控。重点管控不可见且重要度低后台启动或关联启动其他应用的行为。
一些拦截日志
// 拦截 com.chaozh.iReaderFree 利用 JobSchedulerService 后台自启动
04-24 03:22:42.560 1329 1329 D Smart_Restrictor: restrict:true t=20 t={u:10216 pkg:com.chaozh.iReaderFree com.chaozh.iReaderFree/com.umeng.message.UmengMessageCallbackHandlerService label:job } c=null r=Malicious!
// 拦截 APP1 关联启动 APP2
04-24 03:22:46.844 1329 6418 D Smart_Restrictor: restrict:true t=21 t={u:10203 pkg:com.baidu.BaiduMap com.baidu.BaiduMap/com.baidu.android.pushservice.PushService } c={pkg:com.baidu.netdisk p:27975 u:10202 newj:800 oldj:800 jt:started-services s:false name:com.baidu.netdisk acts:false sers:true sui:false ic:false} r=Malicious!
05-27 20:42:59.511 25315 3864 D Smart_Restrictor: restrict:true t=1 t={com.tencent.karaoke.maindex.legend.Phosphene} c=com.anjuke.android.app r=null
05-27 20:43:00.122 25315 3847 D Smart_Restrictor: restrict:true t=1 t={com.cleanmaster.getui.InvokeActivity} c=com.anjuke.android.app r=null
// 拦截推送服务后台自启动
04-24 03:31:07.379 1337 1337 D Smart_Restrictor: restrict:true t=20 t={u:10208 pkg:com.autohome.usedcar com.autohome.usedcar/io.rong.push.rongpush.PushService label:job } c=null r=Malicious!
// 拦截空进程启动
05-27 20:41:30.443 25315 25377 D Smart_Restrictor: restrict:true start application t={com.anjuke.android.app} c=null r=Start empty app
3.3 例子-广播拦截机制
在广播拦截中我们分为应用未启动和应用运行时2种策略
·应用未启动时若存在以下情况会被拦截
1.一些系统发出的广播进行拉起,例如开机关播、网络和硬设变化相关广播、亮灭屏广播、锁屏广播、应用安装卸载等,会被拦截;其实谷歌每次大版本升级其实加强安全的优化,也包含广播使用权限的加强,例如从最开始从不限制任何广播,到限制部分静态广播,到限制部分动态广播。可能是借鉴了中国手机厂商自启动拦截的思路。
2.第三方应用后台关联拉起的行为,会被拦截。
3.白名单的应用不受限制;
·应用已启动且正在运行
1.应用处于不可感知状态,系统的一些广播拉起,会被拦截
2.应用使用自己的广播或stricky类型不受限制;