更多干货,欢迎关注微信公众号: tmac_lover
今天给大家介绍一下Android系统中保存app信息的两个配置文件,packages.xml和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 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使用的.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,它们具有一样的权限。