1. Android UID 的本质与作用当你安装一个安卓应用时系统会默默给它分配一个身份证号码——这就是UIDUser ID。它不像进程IDPID那样随时变化只要应用不卸载重装这个数字就会一直跟随它。想象一下公寓楼的门禁系统UID就是每户人家的门卡权限决定了你能进哪些区域、用哪些设施。内核层通过UID实现沙盒隔离机制的核心原理文件权限控制应用数据目录如/data/data/pkgname的归属权限设置为u0_a123格式进程隔离Binder通信时会校验调用方UIDSELinux策略seapp_contexts中基于UID配置安全上下文通过adb shell ps看到的UID格式解析示例u0_a123 4567 789 /com.example.appu0主用户User 0a123应用ID123真实UID10000123101232. UID的生成规则揭秘在android_filesystem_config.h中定义了系统预留UID#define AID_SYSTEM 1000 // 系统服务 #define AID_SHELL 2000 // adb shell #define AID_APP 10000 // 普通应用起始UID应用安装时的UID分配流程解析APK读取AndroidManifest.xml中的sharedUserId声明查询数据库检查/data/system/packages.xml是否已存在相同共享UID计算最终UID普通应用10000 appId多用户环境userId * 100000 (10000 appId)关键源码路径PackageManagerService.java处理安装逻辑Settings.java维护packages.xml数据库UserHandle.javaUID计算工具类3. 系统文件中的UID踪迹通过以下文件可以追踪UID绑定关系文件路径作用示例内容/data/system/packages.xml记录所有包的UID和权限package namecom.test uid10123/data/system/packages.list简化版的包列表com.test 10123 0 /data/data/com.test/proc/[pid]/status查看运行中进程的UIDUid: 10123 10123 10123 10123查看某个应用UID的三种方法# 通过包名查询 adb shell dumpsys package com.example.app | grep userId # 通过进程ID反查 adb shell cat /proc/1234/status | grep Uid # 列出所有应用UID映射 adb shell pm list packages -U4. 开发中的UID实战技巧获取当前应用UID的代码示例// 通过ApplicationInfo获取 int uid getApplicationInfo().uid; // 通过进程API获取 int uid android.os.Process.myUid(); // Binder调用方UID检测 int callingUid Binder.getCallingUid(); if (callingUid ! Process.SYSTEM_UID) { throw new SecurityException(Only system can call this); }多用户环境下的特殊处理fun getRealUid(context: Context): Int { val userId UserHandle.getUserId(Process.myUid()) val appId UserHandle.getAppId(Process.myUid()) return if (userId ! UserHandle.USER_SYSTEM) { userId * 100000 appId } else { appId } }调试时常用的ADB命令# 查看指定包名的UID adb shell pm dump com.example.app | grep userId # 监控Binder调用UID adb shell su root cat /sys/kernel/debug/tracing/trace_pipe | grep uid5. UID与权限系统的联动权限检查的核心链路checkPermission()调用PackageManager.checkUidPermission()查询/data/system/packages.xml中的perms节点对比item nameandroid.permission.CAMERA grantedtrue/特殊场景处理共享UID应用需要相同签名和sharedUserId声明隔离服务使用android:isolatedProcesstrue会分配9xxxx范围的UIDWebView沙盒固定使用1053作为WebView zygote的UID一个典型的权限拒绝日志分析W/PackageManager: Permission denied: uid10123 requires android.permission.READ_CONTACTS6. 内核层的UID映射Linux内核通过以下机制实现UID控制进程凭证struct cred中的uid/gid字段文件系统stat()返回的inode属性包含UIDBinder驱动在binder_transaction()中校验sender_euid关键内核代码路径kernel/cred.c处理凭证管理drivers/android/binder.c实现跨进程通信校验fs/proc/base.c生成/proc/[pid]/status信息通过strace观察权限检查过程strace -f -e open,access,stat adb shell am start-activity com.example.app7. 疑难问题排查指南常见问题现象与解决方案问题现象可能原因解决方案文件权限拒绝应用目录归属错误chown u0_a123:u0_a123 /data/data/pkgBinder调用失败服务端未校验调用方UID添加Binder.getCallingUid()检查SELinux拒绝访问安全上下文不匹配调整seapp_contexts配置多用户环境下功能异常未处理跨用户UID转换使用UserHandle.getUid()转换我在调试跨进程文件共享时踩过的坑当两个应用声明相同sharedUserId时它们的/data/data/目录会合并。有次忘记在Manifest中声明android:sharedUserId导致权限配置全部失效最终通过分析packages.xml才发现配置遗漏。
Android UID 深度解析:从系统分配到应用进程的标识追踪
发布时间:2026/7/14 11:21:03
1. Android UID 的本质与作用当你安装一个安卓应用时系统会默默给它分配一个身份证号码——这就是UIDUser ID。它不像进程IDPID那样随时变化只要应用不卸载重装这个数字就会一直跟随它。想象一下公寓楼的门禁系统UID就是每户人家的门卡权限决定了你能进哪些区域、用哪些设施。内核层通过UID实现沙盒隔离机制的核心原理文件权限控制应用数据目录如/data/data/pkgname的归属权限设置为u0_a123格式进程隔离Binder通信时会校验调用方UIDSELinux策略seapp_contexts中基于UID配置安全上下文通过adb shell ps看到的UID格式解析示例u0_a123 4567 789 /com.example.appu0主用户User 0a123应用ID123真实UID10000123101232. UID的生成规则揭秘在android_filesystem_config.h中定义了系统预留UID#define AID_SYSTEM 1000 // 系统服务 #define AID_SHELL 2000 // adb shell #define AID_APP 10000 // 普通应用起始UID应用安装时的UID分配流程解析APK读取AndroidManifest.xml中的sharedUserId声明查询数据库检查/data/system/packages.xml是否已存在相同共享UID计算最终UID普通应用10000 appId多用户环境userId * 100000 (10000 appId)关键源码路径PackageManagerService.java处理安装逻辑Settings.java维护packages.xml数据库UserHandle.javaUID计算工具类3. 系统文件中的UID踪迹通过以下文件可以追踪UID绑定关系文件路径作用示例内容/data/system/packages.xml记录所有包的UID和权限package namecom.test uid10123/data/system/packages.list简化版的包列表com.test 10123 0 /data/data/com.test/proc/[pid]/status查看运行中进程的UIDUid: 10123 10123 10123 10123查看某个应用UID的三种方法# 通过包名查询 adb shell dumpsys package com.example.app | grep userId # 通过进程ID反查 adb shell cat /proc/1234/status | grep Uid # 列出所有应用UID映射 adb shell pm list packages -U4. 开发中的UID实战技巧获取当前应用UID的代码示例// 通过ApplicationInfo获取 int uid getApplicationInfo().uid; // 通过进程API获取 int uid android.os.Process.myUid(); // Binder调用方UID检测 int callingUid Binder.getCallingUid(); if (callingUid ! Process.SYSTEM_UID) { throw new SecurityException(Only system can call this); }多用户环境下的特殊处理fun getRealUid(context: Context): Int { val userId UserHandle.getUserId(Process.myUid()) val appId UserHandle.getAppId(Process.myUid()) return if (userId ! UserHandle.USER_SYSTEM) { userId * 100000 appId } else { appId } }调试时常用的ADB命令# 查看指定包名的UID adb shell pm dump com.example.app | grep userId # 监控Binder调用UID adb shell su root cat /sys/kernel/debug/tracing/trace_pipe | grep uid5. UID与权限系统的联动权限检查的核心链路checkPermission()调用PackageManager.checkUidPermission()查询/data/system/packages.xml中的perms节点对比item nameandroid.permission.CAMERA grantedtrue/特殊场景处理共享UID应用需要相同签名和sharedUserId声明隔离服务使用android:isolatedProcesstrue会分配9xxxx范围的UIDWebView沙盒固定使用1053作为WebView zygote的UID一个典型的权限拒绝日志分析W/PackageManager: Permission denied: uid10123 requires android.permission.READ_CONTACTS6. 内核层的UID映射Linux内核通过以下机制实现UID控制进程凭证struct cred中的uid/gid字段文件系统stat()返回的inode属性包含UIDBinder驱动在binder_transaction()中校验sender_euid关键内核代码路径kernel/cred.c处理凭证管理drivers/android/binder.c实现跨进程通信校验fs/proc/base.c生成/proc/[pid]/status信息通过strace观察权限检查过程strace -f -e open,access,stat adb shell am start-activity com.example.app7. 疑难问题排查指南常见问题现象与解决方案问题现象可能原因解决方案文件权限拒绝应用目录归属错误chown u0_a123:u0_a123 /data/data/pkgBinder调用失败服务端未校验调用方UID添加Binder.getCallingUid()检查SELinux拒绝访问安全上下文不匹配调整seapp_contexts配置多用户环境下功能异常未处理跨用户UID转换使用UserHandle.getUid()转换我在调试跨进程文件共享时踩过的坑当两个应用声明相同sharedUserId时它们的/data/data/目录会合并。有次忘记在Manifest中声明android:sharedUserId导致权限配置全部失效最终通过分析packages.xml才发现配置遗漏。