Android:PMS学习笔记

news/2025/1/8 2:44:45/文章来源:https://www.cnblogs.com/liguo-wang/p/18656623
概述:https://mp.weixin.qq.com/s/i6LlSf8kHOBOk5iKoVVoxA
概述包含哪些部分:
权限管理模块负责apk权限相关的事情,比如请求某个权限,apk权限状态存储,收集所有apk声明的权限
共享库模块负责apk使用到的所有共享库
记录存储模块会把apk相关的很多信息记录并且存储到文件中,比如apk安装后关于apk安装的信息会存储下来,这样就可以供其他使用者检索
所有apk信息模块会收集所有已安装apk的AndroidManifest解析出来的信息,以供其他使用者检索
四大组件模块为了加快检索四大组件的速度,会把所有已安装apk的四大组件信息收集起来
apk管理模块主要负责apk的安装/卸载/更新,它是根基模块,因为它的某个功能会对其他模块产生影响。
快照管理模块主要目的为加快访问PackageManagerService中的各种数据。
 

模块的启动

共享库模块记录存储模块权限管理模块三个模块的启动为扫描所有apk做准备,而扫描所有apk又分为扫描所有系统apk和扫描所有普通apk,扫描所有apk最终的结果是所有apk信息最终存放在了所有apk信息模块四大组件模块,这样使用者就可以从PackageManagerService获取到某个apk的信息了,比如获取某个Activity的信息。
而扫描所有apk也会或多或少的影响共享库模块记录存储模块权限管理模块,比如扫描某个系统apk,该系统apk声明了新的权限、声明了新的共享库,则会把声明的共享库信息记录在共享库模块,而声明的权限则会通知权限管理模块增加此权限,同时记录存储模块也会把该权限存储到文件中。

APK的安装

该apk的安装信息 (apk包名、版本信息、apk文件路径、appid、声明和使用的权限等) 以PackageSetting对象添加到记录存储模块,记录存储模块会把所有的PackageSetting对象重新写入到文件中
该apk信息 (apk包名、声明的四大组件、版本信息、解析的权限等) 添加到所有apk信息模块
该apk信息中的声明的四大组件信息添加到四大组件模块
因为该apk使用了某个共享库,则会从共享库模块把该共享库信息查询出来交给PackageSetting对象
因为该apk声明和使用了权限,则声明和使用的权限会被添加到权限管理模块
 
 
https://mp.weixin.qq.com/s/GAgTBX60Zi9umRYzStF4Hw
管理APK,apk由哪些构成:
lib目录 该目录下面包含了使用到的so库
res、assets目录 这两个目录下面包含了各种资源比如图片、layout文件等
META-INF 该目录下面包含了和签名证书有关的文件
dex java/kotlin编译后的字节码文件
resources.arsc 文件可以视为一个资源表,它存储了所有资源的ID和这些资源在APK文件或其他位置中的引用
AndroidManifest.xml
 
PMS划分:
apk管理模块权限管理模块共享库模块记录存储模块所有apk信息模块四大组件模块
权限管理模块负责apk权限相关的事情,比如请求某个权限,apk权限状态存储,收集所有apk声明的权限
共享库模块负责apk使用到的所有共享库
记录存储模块会把apk相关的很多信息记录并且存储到文件中,比如apk安装后关于apk安装的信息会存储下来,这样就可以供其他使用者检索
所有apk信息模块会收集所有已安装apk的AndroidManifest解析出来的信息,以供其他使用者检索
四大组件模块为了加快检索四大组件的速度,会把所有已安装apk的四大组件信息收集起来
apk管理模块主要负责apk的安装/卸载/更新,它是根基模块,因为它的某个功能会对其他模块产生影响。

记录存储模块内容

https://mp.weixin.qq.com/s/ZeV0NpLU9jKx83lYuWwDIg
记录存储模块,服务于PackageManagerService服务,所有的工作都交给了Settings类,我的作用是记录apk的安装及附加信息并且把这些信息存储到文件中,记录存储的这些信息的主要目的是供使用者来查询,比如可以通过包名查询某个apk是否被安装
 
是什么:apk的包名版本号apk安装路径安装时间签名请求权限状态信息等信息记录下来
 
apk安装的工作交给了PackageSetting类。不管是系统apk还是普通apk只要被安装在Android设备上,都会对应一个PackageSetting实例
PackageSetting类负责apk安装信息的记录Settings类负责apk安装信息的存储。特意将PackageSetting的属性划分为apk基础信息不可序列化信息apk的用户状态信息请求权限状态信息四部分
 
当一个apk被安装成功后,PackageSetting类会把apk安装的信息分为apk基础信息不可序列化信息apk的用户状态信息请求权限状态信息四部分来记录。
  1. apk基础信息包名apk版本信息appidapk文件路径等,而Settings类会把基础信息存储在 /data/system/package.xml 文件中。
  2. 不可序列化信息是不需要存储的,而是每次Android设备重新启动的时候需要重新收集。
  3. apk的用户状态信息记录了当前用户安装apk的状态信息 (状态比如是否安装),而Settings类会把这些信息存储在 /data/system/users/userid/package-restrictions.xml 文件 (路径中的userid指的是用户id,比如0,10)。
  4. 请求权限状态信息记录了当前用户下所有apk的所有申请的权限的状态 (权限的状态比如是否允许),而Settings类会把这些信息会存储在 /data/misc_de/userid/apexdata/com.android.permission/runtime-permissions.xml 文件 (路径中的userid指的是用户id,比如0,10)
Settings类中存在类型为WatchedArrayMap<String, PackageSetting>的属性mPackages,它就代表所有的已安装apk,它的key值为包名,如下代码:
final WatchedArrayMap<String, PackageSetting> mPackages;
当apk安装时,Settings类会为mPackages属性增加一个记录,并且把这些信息更新到相应的文件;当apk删除时,Settings类会从mPackages把相应的记录删除,并且更新相应的文件;当apk升级时,Settings类会从mPackages中找到对应记录,更新相应记录信息,并且更新相应文件。
 
 

声明权限信息

先来介绍下声明权限吧,权限分为声明权限使用权限,每个apk都可以声明权限,声明的权限是可以被其他apk来使用的。声明权限是在AndroidManifest中使用permission标签,记录所有声明权限的工作交给了LegacyPermissionSettings类
 

记录存储模块的初始化

所有的事情都交给了Settings类,在PackageManagerService类中会存在类型为Settings的属性mSettings (如下代码)
final Settings mSettings;
而我的初始化是从PackageManagerService的构造方法开始的,PackageManagerService会调用Settings对象的readLPw方法开始初始化工作,主要做了以下工作:
  1. 从 /data/system/package.xml 文件中把所有信息都读取出来,并把相应的数据填充给相应的记录类,比如遇到package标签,则会把数据填充给PackageSetting对象;比如遇到permissions标签会把每个声明的权限添加到LegacyPermissionSettings对象中。
  2. 从 /data/system/users/userid/package-restrictions.xml (路径中的userid指的是用户id,比如0,10) 文件中,把每个apk的用户状态信息读取出来
  3. 从/data/misc_de/userid/apexdata/com.android.permission/runtime-permissions.xml (userid同上) 文件中,把每个apk的请求权限状态信息读取出来。
一句话总结我的初始化工作就是从文件中把先前存储的信息读取出来,并且填充给相应的类,初始化工作完成后,我就可以为PackageManagerService提供服务了。
 

共享库

https://mp.weixin.qq.com/s/fETMe8RezB7tswoasqlrBg
在Android中共享库是指由系统提供的可以被多个程序使用的系统库,而共享库的使用是在AndroidManifest.xml文件中使用uses-library标签 (使用java库)或者uses-native-library标签,系统Apk是可以通过library标签声明共享库的,framework.jar是一个特殊的共享库。
总结下共享库被使用的过程:(以下基于某个Apk使用了某个共享库)
  1. 共享库模块会根据共享库名字版本信息等查询到对应的共享库信息,并且把共享库信息交给对应的Apk (其实保存在PackageSetting对象)
  2. 当App进程启动后,会从ActivityManagerService拿到对应的ApplicationInfo信息,而ApplicationInfo存储了apk路径包名apk版本号共享库信息等等非常关键的信息
  3. App进程会把ApplicationInfo中的apk路径native lib路径共享库文件路径等信息交给PathClassLoaderPathClassLoader的父类BaseDexClassLoader会持有关于共享库相关的ClassLoader
  4. 在查找某个类时,会先从共享库对应的ClassLoader查找,找到了返回;否则从BaseDexClassLoader中查找。
用一句简单的话总结就是:共享库文件会被加载到App进程的PathClassLoader中,这样App进程就可以找到共享库的类了。从此也可以看出除framework.jar外的共享库是在每个App进程都占用自己的内存空间,没有共享内存。

APK信息

https://mp.weixin.qq.com/s/NiEV72mEMKg6ovcBIsRTbg
标签数据类的命名格式是ParsedXXXXImpl (如ParsedActivityImpl)
每个标签数据类都有自己对应的接口,接口命名格式为ParsedXXXX (如ParsedActivity),即使像ParsedUsesPermissionImpl这么简单的类它都有自己的接口ParsedUsesPermission
ParsedComponentImpl类收集了大部分标签共用的信息,而它的接口是ParsedComponent
ParsedMainComponentImpl类收集了四大组件标签共用的信息,而它的接口是ParsedMainComponent
 
 
  1. 四大组件对应的数据类分别是ParsedActivityImplParsedServiceImplParsedProviderImpl
  2. 权限相关的标签permissionuses-permission对应的数据类是ParsedPermissionImplParsedUsesPermissionImpl
  3. AndroidManifest会对应一个PackageImpl实例,而它的父类ParsingPackageImpl存放了所有的数据类。
标签数据类有一个规则:每个类的命名规则是ParsedXXXXImpl (XXXX 代表对应的标签),每个类都有对应的接口命名规则是ParsedXXXX
 

apk的安装流程

PackageManagerService、Settings、PackageInstallerSession、PackageInstallerService、InstallPackageHelper、Installer
apk的安装会经过前期准备安装后期收尾这三个阶段,前期准备成功后才会进入安装阶段,安装阶段成功后才会进入后期收尾阶段。除了后期收尾外,前两个阶段只要发生错误就会停止apk的安装。
前期准备的工作有拷贝、完整性校验、解析apk、提取native libs、版本号验证;
安装的工作有准备 (Prepare) 、扫描 (Scan) 、调和 (Reconcile) 、提交 (Commit) ;
后期收尾的工作有创建app data根目录、dex优化、移除已有apk、发送安装成功广播。
 
  1. 不管apk是通过adb安装的(apk存储于PC的磁盘)还是应用市场安装的(apk存储于设备),首先apk会被拷贝到 /data/app/xxx.tmp目录下面(xxx是一个随机生成的字符串)
  2. 在经过重重的验证、校验(签名、版本号),/data/app/xxx.tmp 目录会重命名为 /data/app/[randomStrA]/[packageName]-[randomStrB] 目录,也就是被拷贝的apk最终路径是 /data/app/[randomStrA]/[packageName]-[randomStrB]/base.apk 。同时会为apk生成一个唯一的id又称appid
  3. 解析apk的AndroidManifest中的内容为ParsedPackageParsedPackage中的权限等信息经过验证通过后,ParsedPackage传递给PMS这样其他使用者比如ActivityManagerService就可以从PMS获取刚安装apk的信息了。
  4. 刚安装的apk的安装信息比如包名、版本、签名证书、安装时间等会存储到PackageSettingPackageSetting会传递给SettingsSettings会把它持久化到packages.xml文件。
  5. 创建app data根目录,app data根目录是apk运行期间数据存储的根目录,并且app data根目录只有当前apk程序有读写执行权,其他不用没有任何权限。
  6. 对apk的dex进行优化,优化即使不成功也不影响apk的安装,dex优化可以保证app运行性能上的提升。
  7. 发送安装成功广播。
      apk越大包含的so越多,安装apk的时间越长。主要时长体现在拷贝、提取native libs、dex优化这几项工作。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865153.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 权限管理系统学习笔记

权限管理系统(PackageManagerService) 权限管理系统所做的事情大体可以分为管理声明的权限、管理App使用的权限、权限的授予/撤销、资源使用记录这四类。权限管理系统大体分为权限控制器App、管理类、服务类三大模块权限控制器App它的“英文名”是PermissionController,它是…

【安全工具+蜜罐】企业安全建设之蜜罐搭建与使用

一、基本介绍 HFish是一款基于Golang开发的跨平台多功能主动诱导型开源国产蜜罐框架系统,它从内网失陷检测、外网威胁感知、威胁情报生产三个场景出发,为用户提供可独立操作且实用的功能,通过安全、敏捷、可靠的中低交互蜜罐增加用户在失陷感知和威胁情报领域的能力,目前HF…

全局变量(PHP)

引子:从本章开始,正式进入Web开发篇,当然文章所写内容并非如何从零开始成为一名合格的开发者,而是站在安全的角度学开发。再说白点,就是开发者在开发业务系统时,哪处容易出现安全问题就学哪处。本章则从PHP基础之全局变量开始。免责声明:本文章仅用于交流学习,因文章内…

.NET 响应式编程 System.Reactive 系列文章(一):基础概念

在.NET中,响应式编程的核心库是System.Reactive,通常简称为Rx。本篇文章将介绍响应式编程的基础概念以及System.Reactive的核心组件,为后续深入学习奠定基础。.NET 响应式编程 System.Reactive 系列文章(一):基础概念 引言 在现代软件开发中,处理异步事件和数据流已经成…

【神兵利器】绕过EDR防病毒软件

免责声明 仅限用于技术研究和获得正式授权的攻防项目,请使用者遵守《中华人民共和国网络安全法》,切勿用于任何非法活动,若将工具做其他用途,由使用者承担全部法律及连带责任,作者及发布者不承担任何法律连带责任项目介绍 项目演示了使用Windows API函数(例如:VirtualAllo…

RAG项目推荐:bRAG-langchain-构建自己的 RAG 应用程序所需了解的一切

检索增强生成 (RAG) 项目项目链接:https://github.com/bRAGAI/bRAG-langchain/tree/mainbRAGAI 的官方平台即将上线。加入等待列表,成为早期使用者之一! 本仓库包含了对检索增强生成 (RAG) 在各种应用中的全面探索。 每个笔记本都提供了从入门级到高级实现的详细实践指南,包…

五上数学LK情况反馈203班

五上数学LK情况反馈203班 上周五进行了LK,使用答题卡,电子阅卷,答题卡放在中学部,我们只有拿着学生没有写答案的试卷讲评,需要知道具体错误的,由周老师告知学生,今天晚上有半数以上学生,周老师已经告知学生错误题目了,分数已经公布。 本次考试难度较大,带有XB的性质,…

【金融行业】2024中国网络安全产业势能榜优能企业 金融行业典型案例展示

金融行业一直是信息安全的重点领域,随着金融科技的快速发展和数字货币的崛起,金融机构面临着前所未有的挑战。数据泄露、网络攻击等安全事件的频发,促使金融企业加强安全保障。然而,信息安全的提高不仅仅是防止外部威胁的关键,更重要的是确保业务在突发事件或安全事件发生…

Timer、Ticker使用及其注意事项

在 Golang 中,Timer 和 Ticker 是常用的定时器工具,但它们的使用易出错,尤其是初学者。本文将深入探讨定时器的正确使用方式、常见误区,并通过源码解读帮助你更好地理解它们的工作原理。Timer、Ticker使用及其注意事项 在刚开始学习golang语言的时候就听说Timer、Ticker的使…

entire vs whole; coca

entire 868 whole 466left 4WORD 1: ENTIRE WORD W1 W2 AN 15134 932 VIRTUALLY 354 71 Virtually the entire sample几乎所有样本 Virtually the entire Israeli governing class几乎整个以色列统治阶级 DEVOTED 216 71 devoted his entire care…

第22章 高级线程处理

第22章 高级线程处理 22.1 同步概述 多线程我们常需要一些同步结构进行线程间通讯。同步结构可以分为三类:互斥锁一次只允许一个线程执行特定的活动或一段代码。主要目的是令线程访问共享的写状态而不互相影响。互斥锁包括 lock​、Mutex​ 和 SpinLock​。 2. 非互斥锁 实现…