openprocesstoken

openprocesstoken

openprocesstoken是微软Windows操作系统中Win32应用编程接口的一个函数,用于打开与指定进程相关联的访问令牌(access token),并返回该令牌的句柄。访问令牌描述进程或线程的安全上下文,包含用户账户标识与特权信息,系统据此判断进程能否访问受保护对象[1]。该函数是进程权限查询、特权调整与令牌复制等安全操作的入口之一,自Windows XP起可用。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

openprocesstoken是Windows Win32 API中processthreadsapi.h头文件声明的函数,作用为获取某个进程主访问令牌的句柄[1]。其函数原型返回布尔值,接收进程句柄、期望访问掩码和用于接收令牌句柄的指针3个参数。函数以BOOL型返回值表示成败:非零表示成功,零表示失败,进一步错误信息需调用GetLastError取得。

被打开的访问令牌本身是描述进程或线程安全上下文的内核对象,其中记录着关联用户账户的身份与特权,系统在线程与安全对象交互时据此识别用户身份,或判断能否执行需要特权的系统任务[1]。调用openprocesstoken返回的令牌句柄在不再使用时须通过CloseHandle关闭,以免句柄泄漏。

原理

函数调用需要一个有效的进程句柄,且目标进程须具备PROCESS_QUERY_LIMITED_INFORMATION访问权限;该句柄通常由OpenProcess取得。第二个参数DesiredAccess为访问掩码,声明调用方希望获得哪些令牌访问类型,例如TOKEN_QUERY用于读取令牌信息、TOKEN_ADJUST_PRIVILEGES用于调整特权、TOKEN_DUPLICATE用于复制令牌;这些请求会与令牌的自由访问控制列表(DACL)比较,以决定授予或拒绝。

成功打开令牌后,常见的后续操作包括用GetTokenInformation读取令牌所属用户、特权列表等信息,以及用AdjustTokenPrivileges启用或禁用某项特权。以关机特权为例,程序可先取得当前进程令牌,查得SE_SHUTDOWN_NAME对应的本地唯一标识符(LUID),再把该特权置为启用状态,随后执行需要特权的操作。特权比较依赖LUID而非字符串名称,因此需借助LookupPrivilegeValue完成名称到标识符的转换。

跨账户场景存在额外要求:若检查方与被检查的进程分属不同账户,检查方进程需启用SE_DEBUG_NAME特权;若要从非提升进程取得提升进程的句柄,两个进程须由同一账户启动。与进程令牌相对,线程在模拟客户端时拥有模拟令牌,可通过OpenThreadToken获取对应句柄。

发展历程

openprocesstoken随Windows NT的访问控制模型一同出现,其文档标明最低支持客户端为Windows XP、最低支持服务器为Windows Server 2003。函数实现位于Advapi32.dll,链接时使用Advapi32.lib,调用方需包含Windows.h或processthreadsapi.h。

Windows 8起,系统为当前进程与当前线程的令牌提供了伪句柄,数值分别为-4和-5,可由GetCurrentProcessToken与GetCurrentThreadToken这两个内联函数取得,无需显式打开和关闭[2]。这些伪句柄仅具备TOKEN_QUERY与TOKEN_QUERY_SOURCE权限,适用于只读的令牌查询,也使部分读取身份信息的代码可以省去openprocesstoken调用[3]。

应用

该函数主要用于需要以程序方式检查或调整进程权限的场合,例如软件安装、服务管理、系统关机重启等需要特定特权的操作,在动手前先打开自身令牌并启用相应特权。诊断工具也常借它读取进程令牌中的用户身份与完整性信息,用于判断某进程以哪个账户运行[1]。

在开发语言层面,该函数已被多种绑定封装,供非C/C++环境调用。例如Go语言的wintoken库提供同名方法,按进程标识符打开主令牌或模拟令牌[4]。Python的pywin32以win32security.OpenProcessToken形式暴露该接口,Java原生访问库JNA也在Advapi32接口中声明了它[2]。跨平台的Wine实现同样提供了同名函数,以兼容依赖该接口的Windows程序[5]。

令牌复制是另一类常见用法:取得令牌句柄后,可通过DuplicateTokenEx生成新的主令牌或模拟令牌,再配合CreateProcessAsUser等接口以其他安全上下文运行代码[6]。此类能力既服务于合法的系统管理与测试工具,也要求调用方妥善控制权限边界。

局限

openprocesstoken本身只完成打开与授权检查,不提供读取内容或修改配置的能力;实际的信息读取、特权调整与令牌替换需分别由GetTokenInformation、AdjustTokenPrivileges、DuplicateTokenEx等函数完成。若DesiredAccess请求的权限超出令牌DACL允许的范围,调用直接失败,调用方无法绕过该检查。

获取其他账户进程的令牌受到更多限制:来自不同账户的进程需要SE_DEBUG_NAME特权,而该特权通常处于禁用状态,需先启用才能生效。对非提升进程而言,即使同账户的提升进程也无法直接取得句柄,两个进程必须由同一账户启动,这一约束使其不能用作跨完整性级别的通用权限通道。

此外,句柄生命周期需由调用方自行管理,遗漏CloseHandle会造成句柄资源占用。Windows 8引入的伪句柄虽然免去打开与关闭步骤,但权限被限定为TOKEN_QUERY与TOKEN_QUERY_SOURCE,且不能被DuplicateHandle或DuplicateToken复制,因此无法替代需要更宽权限的场景[3]。

参见

  • 访问令牌 —— 描述进程或线程安全上下文的对象,是本函数所打开的目标。

  • OpenThreadToken —— 打开线程模拟令牌的同类函数。

  • GetTokenInformation —— 读取令牌中用户、特权等信息。

  • AdjustTokenPrivileges —— 启用或禁用令牌中持有的特权。

  • Wine —— 提供同名接口实现的开源兼容层。

参考资料

  1. 访问令牌 [引用日期2026-10-19]
  2. 消息 [378785] [引用日期2026-10-19]
  3. GetCurrentProcessToken function (processthreadsapi.h) [引用日期2026-10-19]
  4. wintoken [引用日期2026-10-19]
  5. b0f02b28b9bebd2b2c3dbd8aa78c5a25613bcc88 [引用日期2026-10-19]
  6. Invoke-TokenManipulation [引用日期2026-10-19]
词条评价
词条统计

浏览次数:5 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-19T13:31:03Z

历史版本

本条目引用的词条
Wine 访问令牌 OpenThreadToken GetTokenInformation AdjustTokenPrivileges