Android上如何使用UID获取用户名?

2024-04-21

我有几个这样的UID:
10022、10011、1000

其实我知道他们的用户名是u0_a22, u0_a11, system.

但问题是,如何使用UID获取用户名呢?没有/etc/passwd根本没有文件。


我编写了一个实用程序类,通过硬编码值来获取 UID/GID 名称android_filesystem_config.h https://android.googlesource.com/platform/system/core/+/master/include/private/android_filesystem_config.h.

Usage:

String uid = AndroidFilesystemConfig.getNameForId(1000);

AndroidFilesystemConfig.java

import android.os.Build;
import android.util.SparseArray;

import java.util.Locale;

/**
 * <p>System Users and Groups for the Android platform as specified in
 * <a href="https://android.googlesource.com/platform/system/core/+/master/include/private/android_filesystem_config.h">android_filesystem_config.h</a>.</p>
 *
 * <p>Last updated: April 20th, 2016</p>
 *
 * <p><b>Note:</b> Some OEMs may have specific UIDs for other system users not in this class.</p>
 */
public class AndroidFilesystemConfig {

  /* first app user */
  private static final int AID_APP = 10000;

  /* offset for uid ranges for each user */
  private static final int AID_USER = 100000;

  /* start of gids for apps in each user to share */
  private static final int AID_SHARED_GID_START = 50000;

  /* end of gids for apps in each user to share */
  private static final int AID_SHARED_GID_END = 59999;

  private static final SparseArray<String> SYSTEM_IDS = new SparseArray<>();

  static {
    putSystemId(0, "root"); /* traditional unix root user */
    putSystemId(1000, "system"); /* system server */
    putSystemId(1001, "radio"); /* telephony subsystem, RIL */
    putSystemId(1002, "bluetooth"); /* bluetooth subsystem */
    putSystemId(1003, "graphics"); /* graphics devices */
    putSystemId(1004, "input"); /* input devices */
    putSystemId(1005, "audio"); /* audio devices */
    putSystemId(1006, "camera"); /* camera devices */
    putSystemId(1007, "log"); /* log devices */
    putSystemId(1008, "compass"); /* compass device */
    putSystemId(1009, "mount"); /* mountd socket */
    putSystemId(1010, "wifi"); /* wifi subsystem */
    putSystemId(1011, "adb"); /* android debug bridge (adbd) */
    putSystemId(1012, "install"); /* group for installing packages */
    putSystemId(1013, "media"); /* mediaserver process */
    putSystemId(1014, "dhcp"); /* dhcp client */
    putSystemId(1015, "sdcard_rw"); /* external storage write access */
    putSystemId(1016, "vpn"); /* vpn system */
    putSystemId(1017, "keystore"); /* keystore subsystem */
    putSystemId(1018, "usb"); /* USB devices */
    putSystemId(1019, "drm"); /* DRM server */
    putSystemId(1020, "mdnsr"); /* MulticastDNSResponder (service discovery) */
    putSystemId(1021, "gps"); /* GPS daemon */
    // 1022 is deprecated and not used.
    putSystemId(1023, "media_rw"); /* internal media storage write access */
    putSystemId(1024, "mtp"); /* MTP USB driver access */
    // 1025 is deprecated and not used.
    putSystemId(1026, "drmrpc"); /* group for drm rpc */
    putSystemId(1027, "nfc"); /* nfc subsystem */
    putSystemId(1028, "sdcard_r"); /* external storage read access */
    putSystemId(1029, "clat"); /* clat part of nat464 */
    putSystemId(1030, "loop_radio"); /* loop radio devices */
    putSystemId(1031, "mediadrm"); /* MediaDrm plugins */
    putSystemId(1032, "package_info"); /* access to installed package details */
    putSystemId(1033, "sdcard_pics"); /* external storage photos access */
    putSystemId(1034, "sdcard_av"); /* external storage audio/video access */
    putSystemId(1035, "sdcard_all"); /* access all users external storage */
    putSystemId(1036, "logd"); /* log daemon */
    putSystemId(1037, "shared_relro"); /* creator of shared GNU RELRO files */
    putSystemId(1038, "dbus"); /* dbus-daemon IPC broker process */
    putSystemId(1039, "tlsdate"); /* tlsdate unprivileged user */
    putSystemId(1040, "mediaex"); /* mediaextractor process */
    putSystemId(1041, "audioserver"); /* audioserver process */
    putSystemId(1042, "metrics_coll"); /* metrics_collector process */
    putSystemId(1043, "metricsd"); /* metricsd process */
    putSystemId(1044, "webserv"); /* webservd process */
    putSystemId(1045, "debuggerd"); /* debuggerd unprivileged user */
    putSystemId(1046, "mediacodec"); /* mediacodec process */
    putSystemId(1047, "cameraserver"); /* cameraserver process */
    putSystemId(1048, "firewall"); /* firewalld process */
    putSystemId(1049, "trunks"); /* trunksd process (TPM daemon) */
    putSystemId(1050, "nvram"); /* Access-controlled NVRAM */
    putSystemId(1051, "dns"); /* DNS resolution daemon (system: netd) */
    putSystemId(1052, "dns_tether"); /* DNS resolution daemon (tether: dnsmasq) */
    putSystemId(1053, "webview_zygote"); /* WebView zygote process */
    putSystemId(1054, "vehicle_network"); /* Vehicle network service */
    putSystemId(1055, "media_audio"); /* GID for audio files on internal media storage */
    putSystemId(1056, "media_video"); /* GID for video files on internal media storage */
    putSystemId(1057, "media_image"); /* GID for image files on internal media storage */

    putSystemId(2000, "shell"); /* adb and debug shell user */
    putSystemId(2001, "cache"); /* cache access */
    putSystemId(2002, "diag"); /* access to diagnostic resources */

    /* The range 2900-2999 is reserved for OEMs */

    // The 3000 series are intended for use as supplemental group id's only. They indicate
    // special Android capabilities that the kernel is aware of.
    putSystemId(3001, "net_bt_admin"); /* bluetooth: get any socket */
    putSystemId(3002, "net_bt"); /* bluetooth: get sco, rfcomm or l2cap sockets */
    putSystemId(3003, "inet"); /* can get AF_INET and AF_INET6 sockets */
    putSystemId(3004, "net_raw"); /* can get raw INET sockets */
    putSystemId(3005, "net_admin"); /* can configure interfaces and routing tables. */
    putSystemId(3006, "net_bw_stats"); /* read bandwidth statistics */
    putSystemId(3007, "net_bw_acct"); /* change bandwidth statistics accounting */
    putSystemId(3008, "net_bt_stack"); /* bluetooth: access config files */
    putSystemId(3009, "readproc"); /* Allow /proc read access */
    putSystemId(3010, "wakelock"); /* Allow system wakelock read/write access */

    /* The range 5000-5999 is also reserved for OEMs. */

    putSystemId(9997, "everybody"); /* shared between all apps in the same profile */
    putSystemId(9998, "misc"); /* access to misc storage */
    putSystemId(9999, "nobody");
  }

  private static void putSystemId(int id, String name) {
    // Check if the uid exists before adding it so we don't add unsupported ids.
    if (android.os.Process.getUidForName(name) != id) {
      // Not valid on this system. Most likely due to a lower API.
      return;
    }
    SYSTEM_IDS.put(id, name);
  }

  /**
   * @return An array of system UIDs
   */
  public static SparseArray<String> getSystemIds() {
    return SYSTEM_IDS;
  }

  /**
   * Returns the UID/GID name assigned to a particular id, or {@code null} if there is none.
   *
   * @param id
   *     The UID/GID of a process or file
   * @return the name of the UID/GID or {@code null} if the id is unrecognized.
   */
  public static String getNameForId(int id) {
    String name = SYSTEM_IDS.get(id);
    if (name == null) {
      if (id >= AID_SHARED_GID_START && id <= AID_SHARED_GID_END) {
        name = String.format(Locale.ENGLISH, "all_a%d", id - AID_SHARED_GID_START);
      } else {
        int appId = id - AID_APP;
        int userId = 0;
        // loop until we get the correct user id.
        // 100000 is the offset for each user.
        while (appId > AID_USER) {
          appId -= AID_USER;
          userId++;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
          // u{user_id}_a{app_id} is used on API 17+ for multiple user account support.
          name = String.format(Locale.ENGLISH, "u%d_a%d", userId, appId);
        } else {
          // app_{app_id} is used below API 17.
          name = String.format(Locale.ENGLISH, "app_%d", appId);
        }
      }
    }
    return name;
  }

  private AndroidFilesystemConfig() {
    throw new AssertionError("no instances");
  }

}

使用反射:

受 odexide's 答案的启发,这里有一些非常丑陋的反射,我不建议使用它来获取 UID/GID 名称获取pwuid(uid_t) http://androidxref.com/5.0.0_r2/xref/bionic/libc/bionic/stubs.cpp#347:

public static String getNameForUid(int id) {
  try {
    Class<?> clazz = Class.forName("libcore.io.Libcore");
    Field field = clazz.getDeclaredField("os");
    if (!field.isAccessible()) {
      field.setAccessible(true);
    }
    Object os = field.get(null);
    if (os != null) {
      Method getpwuid = os.getClass().getMethod("getpwuid", int.class);
      if (getpwuid != null) {
        if (!getpwuid.isAccessible()) {
          getpwuid.setAccessible(true);
        }
        Object passwd = getpwuid.invoke(os, id);
        if (passwd != null) {
          Field pw_name = passwd.getClass().getDeclaredField("pw_name");
          if (!pw_name.isAccessible()) {
            pw_name.setAccessible(true);
          }
          return (String) pw_name.get(passwd);
        }
      }
    }
  } catch (Exception ignored) {
  }
  return null;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android上如何使用UID获取用户名? 的相关文章

随机推荐

  • 区分大小写 Directory.Exists / File.Exists

    有没有办法区分大小写Directory Exists File Existssince Directory Exists folderPath and Directory Exists folderPath ToLower 都返回true
  • Angular js 2 'node_modules/rxjs/Observable"' 没有导出成员 'Observable'。 import Observable

    我在 Node Modules 包中的 Auth d ts 文件中遇到以下错误 ts 模块 node modules rxjs Observable 没有导出成员 Observable 导入可观察的 找到 Auth d ts 文件的以下代码
  • 如何删除具有特定类名的所有 div?

    使用jquery 删除具有特定类名的所有div的最佳方法是什么 我不想只是隐藏 div 而是完全删除它 所以如果我有这个代码 div class Test div class ABC div class Test 在我调用这个方法 其中 c
  • 如何在 Pygame 表面中实现洪水填充

    我想知道填充 Pygame 表面部分的好方法 我想要的最好的例子是 MS Paint 中油漆桶的工作方式 例如 如果在白色表面上用黑色绘制一个圆圈 我想填充圆圈内的白色 或任何形状 为了让您了解我正在做什么 我正在制作一个像素艺术工具 并且
  • 如何在flutter中重新加载网络图像?

    在flutter中使用网络图像时有时会出现错误Connection closed before full header was received 下面的代码允许我输出错误 但是如何强制小部件重新加载图像 Image network p th
  • 阻止 Visual Studio 在启动时连接到 Team Foundation Server

    Visual Studio 在启动时自动尝试连接到 Team Foundation Server 但有时当您频繁更改 TFS 服务器时 Visual Studio 会在尝试连接到上次使用的 TFS 时花费很长时间超时 如何禁用此功能 您可以
  • 从移动网站中的链接打开电报应用程序

    有什么方法可以从手机中的网站打开电报应用程序吗 我知道如果您使用 telegram 您可以打开 telegram 应用程序 但如何打开 telegram 并使用给定号码创建新对话 我知道可以通过 Whatsapp 之类的方式实现this h
  • 如何创建dll文件

    使用 Visual Studio 2005 我有类文件列表 当我尝试运行类文件时 它显示错误为 输出类型为类库的项目无法直接启动 如何运行类文件 如何创建 dll 文件 我是 Visual Studio 2005 的新手 需要帮忙 A Cl
  • 在 React Native 渲染文本组件中显示动画值

    我无法在渲染器上显示动画的值并返回此错误 不变违规 对象作为 React 子对象无效 发现 带有键 value 的对象 如果您打算渲染子集合 请改用数组 当然 我看到了其中的价值console constructor props super
  • C# 计算两个日期之间的工作日数

    如何获取两个给定日期之间的工作日数 而无需迭代之间的日期并计算工作日 看起来相当简单 但我似乎找不到符合以下条件的结论性正确答案 总数应包含在内 因此 GetNumberOfWeekdays new DateTime 2009 11 30
  • vue 组件中的 Csrf 令牌

    我有集成了 Vue js 的 Laravel 5 3 项目 我想使用CSRF TOKEN以我的形式 表单html代码在Vue组件文件中 resources assets js bootstrap js 我有这个 Vue http inter
  • 如何在不向服务器发送数据的情况下显示选定的图像?

    我试图向客户展示他选择的图像
  • 检查 Ruby 中是否存在 URL

    我如何使用 Ruby 检查 URL 是否存在 例如 对于 URL https google com 结果应该是truthy 但是对于 URL https no such domain or https stackoverflow com n
  • C中的副作用是什么?

    维基百科说 在计算机科学中 一个操作 函数或表达式被认为具有副作用如果它在其本地环境之外修改某些状态变量值 也就是说 除了向操作的调用者返回一个值 主要效果 之外 还具有可观察到的效果 但是我们如何访问本地环境之外的变量 任何人都可以解释这
  • 使用 H2 数据库在 JDBC 中将年份从负 -509 更改为正 510

    509 vs 510 我在使用 JDBC 时看到某种已更改或错误的数据 所以我观察使用H2数据库 http h2database com Java 8 更新 151 上的版本 1 4 196 这是一个完整的例子 请注意我们如何检索日期值三次
  • 如果不刷新页面,Vuex 状态不会更新

    我正在构建一个单页面应用程序 用户可以根据他们是否登录来看到不同的页面 登录调用工作正常 授权令牌保存在本地存储中 设置 我已经设置了一个名为的吸气剂loggedIn返回true如果在状态上设置了令牌 这是我的确切代码auth js商店模块
  • 将十六进制字符串转换为无符号整数 (VBA)

    在 MS ACCESS VBA 中 我通过在字符串前加上 前缀将十六进制字符串转换为十进制 CLng h1234 4660 CLng h80000000 2147483648 我应该怎么做才能将其转换为无符号整数 使用 CDbl 也不起作用
  • 在均匀网格上查找到点云中最近点的距离

    我有一个大小为 AxBxC 的 3D 网格 网格中的点之间的距离 d 相等 给定多个点 考虑到以下假设 找到每个网格点到最近点的距离 每个网格点应包含到点云中最近点的距离 的最佳方法是什么 假设 A B 和 C 相对于 d 来说相当大 给出
  • Python正则表达式查找大括号的所有大小写,包括括号

    我想查找并替换双大括号内的字符串 包括括号本身 例如 a href hello a 理想情况下应该返回 hello 我发现了这个表达 here https stackoverflow com questions 10643553 pytho
  • Android上如何使用UID获取用户名?

    我有几个这样的UID 10022 10011 1000 其实我知道他们的用户名是u0 a22 u0 a11 system 但问题是 如何使用UID获取用户名呢 没有 etc passwd根本没有文件 我编写了一个实用程序类 通过硬编码值来获