一、應用安裝相關的目錄 | 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@[email protected]@classes.art
---system@app@[email protected]@classes.dex
---system@app@[email protected]@classes.art
---system@app@[email protected]@classes.dex
---system@[email protected]@classes.dex
---system@[email protected]
---system@[email protected] -> /system/framework/arm/boot-WfdCommon.oat
--- ··· ···
--arm64
---system@app@[email protected]@classes.art
---system@app@[email protected]@classes.dex
---system@app@[email protected]@classes.art
---system@app@[email protected]@classes.dex
---system@app@[email protected]@classes.dex
---system@app@[email protected]@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的安裝過程可能比大家預想的要複雜。粗略來看,可以分成兩個階段:
- 拷貝APK到安裝目錄。譬如通過
指令安裝APK,APK檔案會先拷貝到手機的/data/local/tmp目錄,然後拷貝到手機的/data/app目錄。這個過程是由PMS消息驅動的,INIT_COPY這個消息會觸發PMS連接配接DefaultContainerService,MCS_BOUND這個消息表示已經連接配接上DefaultContainerService,實際的拷貝操作會在DefaultContainerService所在的程序中完成;adb install
- APK拷貝到安裝目錄後,便可以掃描APK檔案。這個過程同開機時的包掃描過程相似,不同的僅僅是掃描一個APK檔案,相同的是需要檢查APK的合法性,判斷APK的簽名是否比對,更新APK的權限,更新PMS的Settings等。
三、Android 中的 UID 和 PID
在 Android 中 PID 和 UID 都是用來識别應用程式的身份的,但是 UID 是為了不同的程式來使用共享的資料而使用的。
UID,在Android中,由于Android為單使用者系統,這時UID便被賦予了新的使命:資料共享。
四、Android包的檔案格式種類
apk包、jar包、so庫檔案
Android的包管理者很重要的一個職能就是識别不同的包,統一維護這些包的資訊。其面臨的第一個任務就是将這些靜态的檔案轉化成記憶體的資料結構,這樣才能将其管理起來。