You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取运行explorer.exe的用户Token时遇“无效模拟令牌无法复制”错误求助

问题:获取explorer.exe进程用户Token时遇"无法复制无效模拟令牌"错误

尝试获取运行explorer.exe的用户Token时遇到错误,错误信息如下:

New-Object : 调用".ctor"时使用"1"个参数发生异常: "无效的模拟令牌 - 无法复制。"
位于第13行:26字符

  • ... essToken = (New-Object System.Security.Principal.WindowsIdentity -Arg ...
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
    FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

使用的PowerShell代码:

# 指定目标用户名
$targetUsername = "$env:username"

# 获取目标用户运行的进程
$processes = Get-WmiObject -Class Win32_Process -Filter "Name = 'explorer.exe'" | Where-Object { $_.GetOwner().User -eq $targetUsername }

if ($processes.Count -eq 0) {
    Write-Host "未找到用户 $targetUsername 的进程"
} else {
    foreach ($process in $processes) {
        # 获取进程的安全令牌
        $processHandle = [System.Diagnostics.Process]::GetProcessById($process.ProcessId).Handle
        $processToken = (New-Object System.Security.Principal.WindowsIdentity -ArgumentList $processHandle).Token

        Write-Host "$targetUsername 的Token: $processToken"
    }
}

错误原因及解决办法

原因

直接用进程句柄构造WindowsIdentity时,默认会尝试复制令牌用于模拟操作,但当前进程要么权限不足,要么原令牌不允许被复制或用于模拟。此外,GetProcessById获取的进程句柄默认没有足够权限访问进程令牌的敏感信息。

修复方案

  1. 必须以管理员身份运行PowerShell:没有管理员权限,无法获取操作进程令牌的必要权限。
  2. 调用Windows API正确复制令牌:通过OpenProcessToken和DuplicateTokenExAPI获取可使用的令牌,替代直接用进程句柄构造WindowsIdentity的方式。

修改后的完整代码:

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class TokenHelper {
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, IntPtr lpTokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr DuplicateTokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool CloseHandle(IntPtr hObject);

    public const uint TOKEN_QUERY = 0x0008;
    public const uint TOKEN_DUPLICATE = 0x0002;
    public const int SecurityImpersonation = 2;
    public const int TokenPrimary = 1;
}
"@

# 指定目标用户名
$targetUsername = "$env:username"

# 获取目标用户运行的explorer.exe进程
$processes = Get-WmiObject -Class Win32_Process -Filter "Name = 'explorer.exe'" | Where-Object { $_.GetOwner().User -eq $targetUsername }

if (-not $processes) {
    Write-Host "未找到用户 $targetUsername 的explorer.exe进程"
    exit
}

foreach ($process in $processes) {
    try {
        $proc = [System.Diagnostics.Process]::GetProcessById($process.ProcessId)
        # 打开进程令牌,需TOKEN_QUERY和TOKEN_DUPLICATE权限
        $tokenHandle = [IntPtr]::Zero
        if (-not [TokenHelper]::OpenProcessToken($proc.Handle, [TokenHelper]::TOKEN_QUERY -bor [TokenHelper]::TOKEN_DUPLICATE, [ref]$tokenHandle)) {
            Write-Host "打开进程令牌失败,错误码: $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())"
            continue
        }

        # 复制令牌为Primary类型,用于创建WindowsIdentity
        $duplicateToken = [IntPtr]::Zero
        if (-not [TokenHelper]::DuplicateTokenEx($tokenHandle, [TokenHelper]::TOKEN_QUERY, [IntPtr]::Zero, [TokenHelper]::SecurityImpersonation, [TokenHelper]::TokenPrimary, [ref]$duplicateToken)) {
            Write-Host "复制令牌失败,错误码: $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())"
            [TokenHelper]::CloseHandle($tokenHandle)
            continue
        }

        # 通过复制后的令牌创建WindowsIdentity并获取Token值
        $identity = New-Object System.Security.Principal.WindowsIdentity($duplicateToken)
        Write-Host "$targetUsername 的Token: $($identity.Token)"

        # 关闭句柄释放系统资源
        [TokenHelper]::CloseHandle($tokenHandle)
        [TokenHelper]::CloseHandle($duplicateToken)
    } catch {
        Write-Host "处理进程 $($process.ProcessId) 时出错: $_"
    }
}

关键注意点

  • 管理员权限是硬性要求,否则所有令牌操作都会因权限不足失败。
  • 手动调用API复制令牌,确保获取到的令牌具备合法的使用权限,避免原代码中的模拟令牌错误。
  • 操作完成后必须关闭令牌句柄,防止系统资源泄漏。

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:52:03