且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

PKMS总结

更新时间:2022-08-13 22:34:22

一、应用安装相关的目录 | PKMS相关目录

系统App安装目录:
1、/system/app,Android系统自带的应用的APP目录
2、/vendor/app,odm或者oem厂商预制系统App目录
3、/data/app/包名, 普通App安装目录

riva:/data/app # cd com.tencent.mm-1/
riva:/data/app/com.tencent.mm-1 # ls -l
total 363816
-rw-r--r-- 1 system system  186262860 2021-02-15 15:19 base.apk
drwxr-xr-x 3 system system       4096 2021-02-15 15:20 lib
drwxrwx--x 3 system install      4096 2021-02-15 15:20 oat

其整体的目录结构如下:

-/data/app/com.tencent.mm-1
    --base.apk
    --lib
        ---arm
            ----libDownloadProxy.so
            ----libEVadEmbed.so
            ---- ··· ···
    --oat
        ---arm
            ----base.odex

4、/data/dalvik-cache,dex、odex保存目录

-/data/dalvik-cache
    --arm
        ---system@app@Bluetooth@Bluetooth.apk@classes.art
        ---system@app@Bluetooth@Bluetooth.apk@classes.dex
        ---system@app@HybridPlatform@HybridPlatform.apk@classes.art
        ---system@app@HybridPlatform@HybridPlatform.apk@classes.dex
        ---system@framework@ConnectivityExt.jar@classes.dex
        ---system@framework@boot-WfdCommon.art
        ---system@framework@boot-WfdCommon.oat -> /system/framework/arm/boot-WfdCommon.oat
        --- ··· ···
    --arm64
        ---system@app@AntiSpam@AntiSpam.apk@classes.art
        ---system@app@AntiSpam@AntiSpam.apk@classes.dex
        ---system@app@BugReport@BugReport.apk@classes.art
        ---system@app@BugReport@BugReport.apk@classes.dex
        ---system@app@CatcherPatch@CatcherPatch.apk@classes.dex
        ---system@app@CertInstaller@CertInstaller.apk@classes.art
        --- ··· ···

5、/data/data,用户数据目录,存放应用程序的数据
6、/data/system,App注册表目录
6.1、/data/system/packages.xml, 此文件在PKMS的启动过程中会被映射成为PKMS中的Setting数据结构,并且在后续的PKMS启动中会围绕着该数据结构进行频繁操作;记录了一个应用的基本信息、签名和声明的权限,从而将一个安装应用的信息进行了持久化的存储。

packages.xml文件中按层级主要分为以下几个模块标签:

  • permission:系统中所有定义的权限的信息;其中每个item块代表一个权限;item块对应的数据结构为 BasePermission 类,表示系统中已有的权限。
  • package:系统中所有安装的应用的详细信息;其中 ①name,表示已安装应用的包名;②codePath,表示已安装应用apk文件存放的路径,其值为 “/data/app/com.guding.vssq-1”;③nativeLibraryPath,表示应用的native库的存储路径,其值为“/data/app/com.guding.vssq-1/lib”;④primaryCpuAbi,表示当前应用以哪种abi架构运行;⑤publicFlags 和 privateFlags,指的是应用的属性;⑥ft、it、ut,分别表示 apk 文件上次被更改的时间、app第一次安装的时间、app上次被更新的时间;⑦version,是app的版本号信息,即为在AndroidManifest.xml 里配置的android:versioncode; ⑧sharedUserId, 表示为app分配的 user id;⑨ sigs,表示已安装应用的签名信息;⑩ perms,表示应用声明使用的权限,其中的 item 表示当前应用所拥有的的权限,perms 对应的是 PermissionState 类,可以将 ==BasePermission 理解为 权限持有者==,而 ==PermissionState 记录的是权限申请者的相关信息==,比如有无被授权等授权状态。
  • updated-package:被覆盖升级的系统应用的相关信息
  • shared-user:所有系统定义的shareuser信息,对应的类是 ==SharedUserSetting类==,SharedUserSetting 中存储的应用安装信息,最终会被添加到 Settings 中的 mSharedUsers 列表中统一进行管理。
  • keyset-settings:已安装app签名的public key信息
<packages>
     <permissions>
        <item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
        ...
    </permissions>   
     <package name="com.android.emergency" codePath="/system/priv-app/EmergencyInfo" nativeLibraryPath="/system/priv-app/EmergencyInfo/lib" publicFlags="944291397" privateFlags="8" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="25" sharedUserId="10013" isOrphaned="true">
        <sigs count="1">
            <cert index="0" />
        </sigs>
        <perms>
            <item name="android.permission.MANAGE_USERS" granted="true" flags="0" />
        </perms>
        <proper-signing-keyset identifier="1" />
    </package>
    ··· ···
     <updated-package name="com.miui.video" codePath="/system/priv-app/MiuiVideo" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="2018092190" nativeLibraryPath="/system/priv-app/MiuiVideo/lib" primaryCpuAbi="armeabi-v7a" userId="10030">
        <perms>
            <item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" granted="true" flags="0" />
             ··· ···
        </perms>
    </updated-package>
    <shared-user name="com.android.emergency.uid" userId="10013">
        <sigs count="1">
            <cert index="0" />
        </sigs>
        <perms>
            <item name="android.permission.MANAGE_USERS" granted="true" flags="0" />
        </perms>
    </shared-user>
     <shared-user name="com.guding.vssq" userId="10126">
        <sigs count="1">
            <cert index="2" />
        </sigs>
        <perms>
            <item name="android.permission.RESTART_PACKAGES" granted="true" flags="0" />
            ··· ···
        </perms>
    </shared-user>
    ··· ···
    <keyset-settings version="1">
        <keys>
            <public-key identifier="1" value="MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAx4ZWipr/JTrXTF0+b7/6Ev7UTNMkTxiWDsVRG7VR5BMRUZcjSEURLMPfm7rNPg9LNSjNh+05fVd9yQCOnLxqJfwGZNOj9EAkN4bbiyUNQPbxSMmjzW+8LdjSQDm9aolyob3uKMMIeYv6m7O1SYd7EPmOJl8RjAXyZFN9leKTORV7nSoxSF4MgjUhzKbQtyGoQyYAB21mniCsQ6pYi1LBHCpR8ExrsxrWroVzmRr+jklX1UlZH8uD7GLR2jWxcn3GtjABpe84e1pxhsHmjaEyV3K1MHsbxznvI2ue/gbVLcrx4ydo40A+VePsVgKM9WgM+zOXHM94cFcrxH0+Ov+jhQIBAw==">
            <public-key identifier="2" value="XXX">
            <public-key identifier="3" value="XXX">
            ··· ···    
        </keys>
        <keysets>
            <keyset identifier="1">
                <key-id identifier="1" />
            </keyset>
            ··· ···
        </keysets>
    </keyset-settings>
</packages>

二、APK的安装过程概述

APK的安装过程可能比大家预想的要复杂。粗略来看,可以分成两个阶段:

  1. 拷贝APK到安装目录。譬如通过adb install命令安装APK,APK文件会先拷贝到手机的/data/local/tmp目录,然后拷贝到手机的/data/app目录。这个过程是由PMS消息驱动的,INIT_COPY这个消息会触发PMS连接DefaultContainerService,MCS_BOUND这个消息表示已经连接上DefaultContainerService,实际的拷贝操作会在DefaultContainerService所在的进程中完成;
  2. APK拷贝到安装目录后,便可以扫描APK文件。这个过程同开机时的包扫描过程相似,不同的仅仅是扫描一个APK文件,相同的是需要检查APK的合法性,判断APK的签名是否匹配,更新APK的权限,更新PMS的Settings等。

三、Android 中的 UID 和 PID

在 Android 中 PID 和 UID 都是用来识别应用程序的身份的,但是 UID 是为了不同的程序来使用共享的数据而使用的。

UID,在Android中,由于Android为单用户系统,这时UID便被赋予了新的使命:数据共享。

四、Android包的文件格式种类

apk包、jar包、so库文件

Android的包管理者很重要的一个职能就是识别不同的包,统一维护这些包的信息。其面临的第一个任务就是将这些静态的文件转化成内存的数据结构,这样才能将其管理起来。

五、包解析器PackageParser