隐私合规之MIUI自启动的监控原理分析

admin 2023年11月30日16:55:13评论88 views字数 4371阅读14分34秒阅读模式

结论

MIUI对于自启动的记录是通过修改系统中的关键函数并使用App Ops机制实现的,但是对于某些关键函数的定位可能是不准确的,会出现onDestroy函数这种并没有自启动行为却被记录的情况存在

背景

近些年,随着科技的不断发展和普及,无论是国家还是普通用户,都越来越重视保护自己的隐私。国家已经出台了一系列法律法规来保护公民的隐私权,同时也加强了对隐私保护的监管力度。普通用户也开始采取各种措施来保护自己的隐私。

用户隐私中有一个很重要的议题:自启动。工信部26号文明确要求APP在非服务所必需或无合理场景下,不得自启动和关联启动其它APP,或进行唤醒、调用、更新等行为。国内厂商也有照明弹等隐私工具,普通用户可以清晰的查看应用的自启动行为。

很多App应用都进行了自启动的相关整改。但是整改的过程中发现,APP已无相关自启动的行为也会被厂商的隐私工具记录为自启动,在用户中造成了不良影响以及不必要的解释成本。厂商的隐私工具的记录方法并不清晰,本文首先对记录方法进行了技术分析,并通过一个例子展示了方法的局限性。

MIUI自启动监控原理

隐私合规之MIUI自启动的监控原理分析

MIUI自启动监控的整体原理如上图。自启动控制模块是对Java API 框架中的关键函数进行修改,达到控制应用自启动的目的并产生自启动记录。用户能看到的自启动记录由照明弹APP提供。除了展示信息给用户,照明弹APP所做的事情就是初始化一些content provider用于存储和读取应用的自启动记录。各个应用设置里有自启动开关,可以控制系统是否允许应用的自启动并产生自启动记录。

自启动控制模块

关键函数修改

不同于其它隐私记录对应用开放的函数(api),自启动控制模块中要修改的关键函数往往处于更底层,并通常位于系统服务中。由于自启动的技术实现方式有很多种,所以需要修改多个关键函数才能完成完整的自启动的记录。

但应用的行为只需触发其中一个函数的调用就会被认为存在自启动。

定位到这些关键函数后,MIUI会插入一些代码。这些代码判断当前应用的自启动开关状态。若不允许自启动则不执行当前函数并直接退出,应用就无法完成自启动。若允许则通过App Ops机制进行自启动的记录并继续执行代码,应用会完成自启动并产生相应记录。

App Ops

Android AppOps 机制是一种用于控制应用程序权限的机制。具体而言:权限模型由传统 permission App Ops 共同组成,一些权限会额外关联 op,例如 android.permission.ACCESS_FINE_LOCATION permission 就关联了 OPSTR_FINE_LOCATION 这个 App Ops,但并非所有 permission 都有对应的 op

App Ops 功能的核心实现由系统服务中的 AppOpsService 服务提供。AppOpsService 内包含有两个主要的方法 noteOp checkOp,用于检查&记录应用的 Op。从方法名看,由于会「记录」(note),因此后面读代码会发现这两个方法都有相应的调用认证鉴权机制。

原生 Android 系统使用 appops 来追踪权限使用,appops 也部分被用于权限控制。每个应用都有自己的 "appops" 设置,当应用需要执行某些操作时,系统在检查权限的同时也会检查 "appops" 设置。

由于原生Android系统的AppOps并没有覆盖自启动,MIUI为了实现自启动的管控会自定义op并关联一些关键函数。当应用的某些行为触发到关键函数时,系统可以通过App Ops机制进行记录和管控。

自启动控制开关

MIUI在自定义了op后,可以像其它权限一样给用户提供一个控制开关,这个开关会记录应用的自启动状态,后续系统会根据这个状态完成自启动的记录和管控。示例如下:

隐私合规之MIUI自启动的监控原理分析

照明弹展示

照明弹APP通过读取App Ops产生的记录,将应用的隐私行为展示给用户。示例如下:

隐私合规之MIUI自启动的监控原理分析

局限性示例-onDestroy

上文分析了MIUI记录自启动的方法,但是这个方法存在一定的局限性,一个典型的例子就是只要service重写了onDestroy方法,上滑关闭应用时就会被记录会自启动,而不论这个函数里有没有进行自启动操作。

onDestroy

Android 中,当一个 Service 被系统销毁时,会调用它的 onDestroy() 方法。这个方法是一个很好的机会来清理资源和释放任何占用的内存。
当一个 Service 被系统销毁时,它可能会有一些残留的线程或其他资源没有被正确释放。这些残留的资源可能会导致内存泄漏或其他问题。因此,在 onDestroy() 方法中,您应该确保释放所有占用的资源,例如关闭数据库连接、释放内存、停止线程等。

上滑杀死进程时,也会杀死进程的service ,此时系统就会调用serviceonDestroy函数。如果onDestroy函数里重新拉起进程,那就实现了自启动的效果。示例代码:

Java@Overridepublic void onDestroy() {      Intent intent=new Intent(getBaseContext(), MainActivity.class);    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    startActivity(intent);}

但是如果不在onDestroy函数里进行拉起进程的行为,应用就不会自启动,但是MIUI却会记录自启动。

MIUI自启动记录现象

1.关闭自启动开关,onDestroy函数(并无实际重新拉起进程操作)不被执行,且照明弹无记录。

2.打开自启动开关,onDestroy函数(并无实际重新拉起进程操作)被执行,且照明弹有记录。

技术分析

上文分析过照明弹的记录其实是App Ops产生的记录,直接查看App Ops的记录,并对比记录产生前后的差异,可以确认MIUIOP(10008)为自启动记录。

隐私合规之MIUI自启动的监控原理分析

为了确认是系统中的哪个一个关键函数产生了自启动的记录,对AppOpsService 内的方法 noteOp 进行hook,并打印函数堆栈,堆栈如下:

Java[*] 隐私记录ops。方法:noteOp。ops is:10008 packagename is: com.applemock.secondtime backtrace:java.lang.Exceptionat android.app.AppOpsManager.noteOpNoThrow(Native Method)at com.android.server.am.AutoStartManagerService.canRestartServiceLocked(AutoStartManagerService.java:135)at com.android.server.am.ActiveServiceManagementImpl.canRestartServiceLocked(ActiveServiceManagementImpl.java:30)at com.android.server.am.ActiveServices.scheduleServiceRestartLocked(ActiveServices.java:3847)at com.android.server.am.ActiveServices.killServicesLocked(ActiveServices.java:5842)at com.android.server.am.ActivityManagerService.cleanUpApplicationRecordLocked(ActivityManagerService.java:12811)at com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java:3362)at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:3498)at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1523)at android.os.IBinder$DeathRecipient.binderDied(IBinder.java:317)at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:768)

关键函数为scheduleServiceRestartLocked,这个函数的功能是重启登记,有可能登记不成功,而performServiceRestartLocked才是真正的重启操作。对比scheduleServiceRestartLocked函数在MIUI和原生系统的区别,可以发现MIUI中增加了以下代码:

隐私合规之MIUI自启动的监控原理分析

插入了检验逻辑,具体实现如下:

隐私合规之MIUI自启动的监控原理分析

其中对于自启动控制开关进行了校验,并对允许自启动的产生自启动记录。

综上所述,MIUI对于scheduleServiceRestartLocked函数进行了修改,只要执行到这一函数的应用均会被记录为自启动,而不论是否有自启动行为,这是不准确的

总结

MIUI对于自启动的记录是通过修改系统中的关键函数并使用App Ops机制实现的,但是对于某些关键函数的定位可能是不准确的,会出现onDestroy函数这种并没有自启动行为却被记录的情况存在。

关于馗安社

欢迎大家关注馗安社,我们的成员简介(按姓氏拼音):

成员

简介

戴中印

目前在美团从事业务安全对抗、情报分析、黑灰产打击等(之前做过SDL+移动安全)

js0huang

安全研究员,研究方向为二进制漏洞自动化挖掘和利用以及工业控制系统安全研究,多次获得SiemensSchneiderSAP等安全致谢

刘新

兰州大学信息科学与工程学院副教授、硕士生导师,主要从事代码安全和 AI 对抗研究

于长奇

字节跳动隐私合规专家,专注移动端合规技术和解决方案,如违规收集个人信息,自启动等。曾从事过内核安全、java安全和Api安全

杨坤

御林安全负责人,蚂蚁金服和美团SRC年度TOP白帽子,专注自动化漏洞挖掘和web3领域

赵永福

网商银行办公安全负责人,主要研究方向为可信纵深防御、信创安全研究、数据安全与合规

作者

本期分享作者:于长奇,感兴趣可以交个朋友(加好友请附加备注)

隐私合规之MIUI自启动的监控原理分析

也希望大家多关注、转发来支持我们的公众号

隐私合规之MIUI自启动的监控原理分析

原文始发于微信公众号(馗安社):隐私合规之MIUI自启动的监控原理分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年11月30日16:55:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   隐私合规之MIUI自启动的监控原理分析https://cn-sec.com/archives/2255540.html

发表评论

匿名网友 填写信息