最可靠方式是Windows调用CheckTokenMembership检查进程令牌是否含Administrators组SID,Linux/macOS用geteuid()==0判断root权限;需注意UAC令牌分离和WSL权限隔离等平台差异。

Windows下用 CheckTokenMembership 判断是否以管理员身份运行
直接调用 Windows API 是最可靠的方式,CheckTokenMembership 能准确识别当前进程是否属于 BUILTIN\Administrators 组(即 UAC 提升后的管理员权限),比简单检查用户名或 SID 前缀更健壮。
- 必须先用
OpenProcessToken获取当前进程的访问令牌,且TOKEN_QUERY权限不可少 - 需手动加载
SECURITY_BUILTIN_DOMAIN_RID和DOMAIN_ALIAS_RID_ADMINS构造管理员组 SID,不能硬编码字符串 - 返回
TRUE仅表示有管理员组成员资格,不代表已提权;若程序未触发 UAC,即使属于管理员组也仍在低完整性级别运行 - 示例关键片段:
BOOL is_admin = FALSE;<br>CheckTokenMembership(NULL, admin_sid, &is_admin);
Linux/macOS下用 geteuid() 和 getegid() 判断是否为 root
类 Unix 系统中,“管理员”等价于有效 UID/GID 为 0,geteuid() 比 getuid() 更准确——它反映的是当前实际执行权限,不受 setuid 程序降权影响。
- 仅检查
geteuid() == 0即可判断是否拥有 root 权限;getegid() == 0可作为辅助验证,但非必需 - 不要依赖
getpwuid(geteuid())查用户名,root 用户可能被重命名或隐藏,UID 才是唯一权威依据 - 注意:容器环境(如 Docker)中 UID 0 不一定对应宿主机 root,该判断只反映当前命名空间内的特权等级
跨平台封装时避免常见误判逻辑
很多开发者试图用“能否打开 /etc/shadow”或“能否绑定 1024 以下端口”来间接推断权限,这种做法在现代系统中极易失效——SELinux、Capabilities、user namespaces 都会拦截这些操作,但不改变 UID/GID 或令牌状态。
部署和使用军舰的 macOS Automator 自动化服务集合。包含 5 个实用工作流:PDF转JPG、PNG重命名并转JPG、图像拼接、解压RAR、顺序命名图像文件。一键安装所有服务到 ~/Library/Services/ 目录。使用场景:(1) "安装我的自动化服务",(2) "部署所有 Automato...
- Windows 下绕过 UAC 的“伪造管理员”进程(如通过服务启动)仍可能通过
CheckTokenMembership被识别为非管理员,因其令牌未包含提升后的组 - Linux 下启用
CAP_NET_BIND_SERVICE的普通用户进程能绑定 80 端口,但geteuid()仍是非零值 - 统一接口建议:封装函数返回枚举值(如
PRIVILEGE_USER/PRIVILEGE_ADMIN),内部按平台分支实现,不暴露底层 API 差异
权限检测结果不能替代最小权限设计
拿到“当前是管理员”这个结论后,直接执行高危操作(如修改系统文件、停用防火墙)仍是危险的。运行时权限状态和程序安全边界不是一回事。
立即学习“C++免费学习笔记(深入)”;
- 即使检测到管理员权限,敏感操作仍应加二次确认(如弹窗提示),尤其当程序由非交互式上下文(cron、systemd)启动时
- Windows 上建议后续操作使用
AdjustTokenPrivileges按需启用特定特权(如SE_BACKUP_NAME),而非依赖完整管理员令牌 - Linux 上优先用
cap_set_proc()启用必要 capabilities,比全程以 root 运行更可控

















