Android 系統中的UID、GID、GIDS與PID

        在 Android 上,一個使用者 UID 標示一個應用程式。應用程式在安裝時被分配使用者 UID,應用程式在裝置上的存續期間內,使用者 UID 保持不變。對於普通的應用程式,GID即等於UID。

        GIDS 是由框架在 Application 安裝過程中生成,與 Application 申請的具體許可權相關。 如果 Application 申請的相應的 permission 被 granted ,而且有對應的GIDS, 那麼 這個Application 的 gids 中將 包含這個 gids。記住許可權(GIDS)是關於允許或限制應用程式(而不是使用者)訪問裝置資源。

        Android 使用沙箱的概念來實現應用程式之間的分離和許可權,以允許或拒絕一個應用程式訪問裝置的資源,比如說檔案和目錄、網路、感測器和 API。為此,Android 使用一些 Linux 實用工具(比如說程序級別的安全性、與應用程式相關的使用者和組 ID,以及許可權),來實現應用程式被允許執行的操作。

圖 1. 兩個 Android 應用程式,各自在其自己的基本沙箱或程序上

圖:兩個 Android 應用程式,各自在其自己的基本沙箱或程序上(具有不同的使用者 ID)

        Android 應用程式執行在它們自己的 Linux 程序上,並被分配一個惟一的使用者 ID。預設情況下,執行在基本沙箱程序中的應用程式沒有被分配許可權,因而此類應用程式訪問系統或資源受到限制,Android 應用程式只能通過應用程式的 manifest 檔案請求許可權。

        不同的應用程式可以執行在相同的程序中。對於此方法,首先必須使用相同的私鑰簽署這些應用程式,然後必須使用 manifest 檔案給它們分配相同的 Linux 使用者 ID,這通過用相同的值/名定義 manifest 屬性 android:sharedUserId 來做到,從而共享對其資料和程式碼的訪問,如圖2所示

圖 2. 兩個 Android 應用程式,執行在同一程序上

圖:兩個 Android 應用程式,執行在同一程序上(具有相同的數字簽名和相同的 Linux 使用者 ID)

總結

在 Android 上,一個應用程式只有一個UID,當然多個應用程式也可以共享一個UID。

對 於普通應用程式來說, gid 等於 uid 。由於每個應用程式的 uid 和 gid 都不相同, 因此不管是 native 層還是 java 層都能夠達到保護私有資料的作用 。

一個GIDS相當於一個許可權的集合,一個UID可以關聯GIDS,表明該UID擁有多種許可權

一個程序就是host應用程式的沙箱,裡面一般有一個UID和多個GIDS,每個程序只能訪問UID的許可權範圍內的檔案和GIDs所允許訪問的介面,構成了Android最基本的安全基礎。

獲取APP的UID 

PackageManager pm = context.getPackageManager();
List<PackageInfo> packinfos = pm
        .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES
| PackageManager.GET_PERMISSIONS);
for (PackageInfo info : packinfos) {

    int uid = info.applicationInfo.uid;
Log.i("test", "uid = " + uid);
String packageName = pm.getNameForUid(uid);
Log.i("test", "package name = " + packageName);
String name = pm.getApplicationLabel(info.applicationInfo).toString();
Log.i("test", "name = " + name);
}