Android UID

Android 中的 uid 是分配给各个进程使用,用来做权限管理的。10000 < uid < 19999 这个整数范围中的 id 号代表用户 app 的 uid,同时 gid 是和 uid 对齐。

android 中 uid 用于标识一个应用程序,uid 在应用安装时被分配,并且在应用存在于手机上期间,都不会改变。一个应用程序只能有一个 uid,多个应用可以使用 sharedUserId 方式共享同一个 uid,前提是这些应用的签名要相同。

pid gid gids 的含义:

  • pid : 进程 ID,可变的
  • gid: 对应于 linux 中用户组的概念,android 中 gid 等于 uid
  • gids: 个 GIDS 相当于一个权限的集合,一个 UID 可以关联 GIDS,表明该 UID 拥有多种权限

一个进程就是 host 应用程序的沙箱,里面一般有一个 UID 和多个 GIDS,每个进程只能访问 UID 的权限范围内的文件和 GIDs 所允许访问的接口,构成了 Android 最基本的安全基础。

UID 的分配

源码基于 Android 11.0/R/sdk-30

App 的 UID 是在安装的时候确认的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// PackageManagerService.java

private AndroidPackage addForInitLI(ParsedPackage parsedPackage,...){
final ScanRequest request = new ScanRequest(parsedPackage, ...);
final ScanResult scanResult = scanPackageOnlyLI(request, ...);
if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
}
}

static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request, ...){
if (createNewPackage) {
pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),...);
} else {
pkgSetting = new PackageSetting(pkgSetting);
pkgSetting.pkg = parsedPackage;
Settings.updatePackageSetting(pkgSetting, ...);
}
}
1
2
3
4
// 根据 uid 获取包名
public String getPackagesForUid(int uid){
return mContext.getPackageManager().getPackagesForUid(uid)[0];
}

PackageManagerService#getPackagesForUid(uid) 返回 String[],因为多个包名可以复用同一个 uid。

查看 UID

uid 的值定义在 Process.java 类中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* An invalid UID value.
*/
public static final int INVALID_UID = -1;

/**
* Defines the root UID.
*/
public static final int ROOT_UID = 0;

/**
* Defines the UID/GID under which system code runs.
*/
public static final int SYSTEM_UID = 1000;

/**
* Defines the start of a range of UIDs (and GIDs), going from this
* number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
* to applications.
*/
public static final int FIRST_APPLICATION_UID = 10000;

/**
* Last of application-specific UIDs starting at
* {@link #FIRST_APPLICATION_UID}.
*/
public static final int LAST_APPLICATION_UID = 19999;

通过 adb 查看:

1
2
3
4
5
6
7
8
9
C:\Users\Administrator>adb shell ps -A
USER PID PPID VSZ RSS WCHAN ADDR S NAME
root 1 0 10782796 7940 0 0 S init
root 277 1 13490100 174656 0 0 S zygote64
root 278 1 1833480 163260 0 0 S zygote
system 520 277 14016032 351988 0 0 S system_server
u0_a121 727 277 13059552 231184 0 0 S com.android.systemui
u0_a117 988 277 13011692 173944 0 0 S com.android.launcher3
u0_a67 2177 277 12938684 163444 0 0 S com.android.packageinstaller

u0_a67 表示该应用是 user 0(主用户)下面的应用,id 是 67。普通应用程序的 UID 都是从 10000 开始的,所以 packageinstaller 的 uid = 10067。

如果手机有 root 权限的话,可以查看 /data/system/packages.list/data/system/packages.xml 文件。

参考

[1] 关于 android UID u0_axx 是怎么来的
[2] Android UID 问题 uid 改变进行了覆盖安装