美文网首页Android收藏集Android开发之PackageManager基础
Android 开发之系统 packages 文件解析

Android 开发之系统 packages 文件解析

作者: 迷你小猪 | 来源:发表于2018-07-13 09:11 被阅读96次

    packages.xml && packages.list 全解析

    这里给大家介绍一下 Android 系统中保存app信息的两个配置文件, packages.xml 和 packages.list, 此两个文件的初始路径为: /data/system/packages.xml 和 /data/system/packages.list。系统中所有安装的app的基本信息在这里都能体现出来。这里以Android 6.0为基础来分析, 不同的Android版本, 可能内容会稍有出入, 但是基本上是相同的。

    1. packages.list

    packages.list 文件内容相对简单, 打开 packages.list 文件后, 会发现对系统中所有安装的app都有类似这样的内容:

    com.android.packageinstaller 10025 0 /data/data/com.android.packageinstaller platform 1028,3003,2001
    

    这里用空格符分了6列, 分别包含了6个 app 相关的信息:

    • 第一列是 app 的包名, 也就是 AndroidManifest.xml 文件中的 package="xxx.xxx.xxx" 设置的内容

    • 第二列是 app 的使用的 userid, 如果没有在 AndroidManifext.xml 里使用 android:sharedUserId 属性指定 UID, 在app安装的时候, 系统会给这个app自动分配一uid, 以后app运行时, 就用这个UID运行

    • 第三列是 app 是否处于调试模式, 由 AndroidManifext.xml 里 android:debuggable 指定

    • 第四列是 app 的数据存放路径, 一般是 "/data/data/${package_name}" 这样的文件夹

    • 第五列是 app 的 seinfo 信息, 这个应该和 SEAndroid 机制有关, 具体不是太清楚, 它的值好像有 platform, default 之分

    • 第六列是 app 所属的user group, 如果一个app不属于任何group, 这里的值是None

    2. packages.xml

    打开 packages.xml 文件,会发现这个文件非常的长,所以先列出这个文件的框架,以便对它有个整体的认知。

    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <packages>
        <version ... />
        <version ... />
    
        <permissions>
            <item name="xxxS" package="xxx" protection="xx" />
            ... ...
        </permissions>
    
        <package xxx>
            ...
        </package>
        ...
    
        <shared-user xxx>
            ...
        </shared-user>
        ...
    
        <keyset-settings version="1">
            ...
        </keyset-settings>
    </packages>
    

    packages.xml 文件中主要的信息分为下面几个部分:

    • permission块: 里面包含了系统中所有定义的权限的信息
    • package块:里面包含了系统中所有安装的app的详细信息
    • shared-user块:里面包含了所有系统定义的shareuser的信息
    • keyset-settings块:里面包含了已安装app签名的public key信息

    下面详细看下每块中的具体类容。

    2.1 permissions

    permissions块的类容如下:

    <permissions>
        <item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
        <item name="android.permission.REMOTE_AUDIO_PLAYBACK" package="android" protection="2" />
        ...
    </permissions>
    

    它里面定义了系统中所有的申明的权限信息, 每个 item 块代表一个权限。name 表示权限的名字, package 表示申明权限的package, protection表示权限的级别, 如normal, dangerous之类的

    2.2 keyset-settings

    先看看keyset-settings块的内容:

    <keyset-settings version="1">
        <keys>
            <public-key identifier="1" value="MIIBIjANBgkqhki..." />
            ...
        </keys>
        <keysets>
            <keyset identifier="1">
                <key-id identifier="1" />
            </keyset>
            ...
        </keysets>
        <lastIssuedKeyId value="9" />
        <lastIssuedKeySetId value="9" />
    </keyset-settings>
    

    另:

    • keyset-settings 块里收集了所有 app 签名的公钥信息, 和后面介绍的 package 块中的信息有关联。

    • keysets 块中包含了很多 keyset, 每个 keyset 都有一个编号用 identifier 表示, keyset 里包含的 key-id 里的 identifier 和上面 keys 中 public-key 的 identifier 的值相对应。

    • keys 块中 public-key 里的 value 值就是从 apk 包里的签名文件里提取出来的的公钥的值。

    • lastIssuedKeyId 和 lastIssuedKeySetId 表示的是最近一次取出来的公钥所属的 set 编号。

    2.3 package

    package 块内容如下:

    <package name="com.tencent.qqmusictv" codePath="/data/app/qqmusictv" nativeLibraryPath="/data/app/qqmusictv/lib" primaryCpuAbi="armeabi" publicFlags="941112933" privateFlags="0" ft="15f00a383c8" it="15f00a383c8" ut="15f00a383c8" version="134" userId="10044">
        <sigs count="1">
            <cert index="6" key="30820247308201b0a003020..." />
        </sigs>
        <perms>
            <item name="android.permission.WRITE_SETTINGS" granted="true" flags="0" />
            ...
        </perms>
        <proper-signing-keyset identifier="7" />
    </package>
    

    package 块里包含了每个 app 的详细信息, 具体说明如下:

    • name 表示 app 的包名

    • codePath 表示这个 apk 文件存放的位置, 如果是系统app, 存在system分区, 如果是第三方app, 存在 data 分区

    • nativeLibraryPath 表示 app 使用的 xxx.so 库存放的位置, primaryCpuAbi 表示 app 以哪种 abi 架构运行

    • publicFlags 和 privateFlags 是根据 AndroidManifest.xml 里的设置生成的, 例如: android:multiarch

    • ft 表示 apk 文件上次被更改的时间, it 表示 app 第一次安装的时间, ut 表示 app 上次被更新时间, 它的值好像一直和 ft 相同, ota 或 app 重装之后, 这里的ft和ut可能会改变。

    • version 是 app 的版本号信息, 也就是在 AndroidManifest.xml 里配置的 android:versioncode

    • userId 是为 app 分配的 user id, 如果有使用 shareUserId, 这里出现的就是 SharedUserId。

    • sigs 块里的 count 表示这个 app 有多少个签名信息, 有的 app 可能会被多个证书签名。cert 里的 index 表示这个 app 使用的证书的序号, 当系统发现一个新的证书, 这个号就会加1, key 是 app 使用的证书内容的 ascii 码值。PKMS 在扫 apk 文件过程中, 如果发现它和之前扫描到的 apk 使用的是相同的签名证书, 这里就只会有个 index 的值, 并没有 key 的值。拥有相同的 index 的 package, 表明它们使用的是相同的签名

    • perms 块里是这个 app 拥有的权限, 对于一般的 app, 这些权限是在 AndroidManifest.xml 里写明的; 那些使用了相同 UID 的 app, 这里的权限就是所有使用相同 UID 的 app 申请的权限的总和。 granted表示这个权限是不是已经被允许。

    • proper-signing-keyset 里的 identifier 就是上面说的 keysets 里 identifier 的值。它是用来标明这个 app 使用的是哪个公钥。

    2.4 shared-user

    以 android.uid.system 为例。

    <shared-user name="android.uid.system" userId="1000">
        <sigs count="1">
            <cert index="1" />
        </sigs>
        <perms>
            <item name="android.permission.REAL_GET_TASKS" granted="true" flags="0" />
            <item name="android.permission.ACCESS_CACHE_FILESYSTEM" granted="true" flags="0" />
            ... ...
            <item name="android.permission.DELETE_PACKAGES" granted="true" flags="0" />
        </perms>
    </shared-user>
    
    • name 表示这个 shared-user 的名字, userId表示这个user在系统中的编号, 具体可以查看 Process.java

    • sigs 和 package 块里的意思相同

    • perms 表示这个user所具有的权限。在开机扫描 apk 文件时, 它会将所有使用了相同 uid 的 app 的权限收集到一起, 然后放在这里。并且最后还会把这些权限再下发给那些使用了相同 uid 的 app。最后的结果就是, 系统中使用相同 uid 的 app, 它们具有一样的权限。

    相关文章

      网友评论

      本文标题:Android 开发之系统 packages 文件解析

      本文链接:https://www.haomeiwen.com/subject/wladpftx.html