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

调用NtCompareTokens函数出现STATUS_ACCESS_VIOLATION的原因及替代方案

NtCompareTokens返回STATUS_ACCESS_VIOLATION的原因及替代方案

错误原因

你代码里的核心问题是输出参数传了NULL:NtCompareTokens的第三个参数是用来接收比较结果的输出参数,需要传入一个有效的BOOLEAN变量地址。但你定义的res是NULL,函数尝试往空地址写入数据,直接触发了访问违例(STATUS_ACCESS_VIOLATION)。

另外还要注意,调用NtCompareTokens要求两个令牌句柄都具备TOKEN_QUERY权限,如果句柄权限不足,也可能引发错误,但这次的访问违例明显是输出参数的问题导致的。

修复后的代码示例

把res换成栈上的有效变量,让函数能正常写入结果:

BOOLEAN compare(PHANDLE token_handle, PHANDLE duplicatetoken_handle) {
    HMODULE hModule = GetModuleHandle(TEXT("ntdll.dll"));
    BOOLEAN result = FALSE;
    if (hModule != NULL) {
        typedef NTSTATUS(NTAPI* NtCompareTokens_t)(HANDLE Token1, HANDLE Token2, PBOOLEAN Equal);
        NtCompareTokens_t pNtCompareTokens = (NtCompareTokens_t)GetProcAddress(hModule, "NtCompareTokens");
        if (pNtCompareTokens != NULL) {
            NTSTATUS status = pNtCompareTokens(*token_handle, *duplicatetoken_handle, &result);
            // 可选:检查调用是否成功,失败则返回默认值
            if (!NT_SUCCESS(status)) {
                result = FALSE;
            }
        }
    }
    return result;
}

替代比较方法

如果不想用NtCompareTokens,可以试试这些方式:

  • 对比令牌的核心信息:用GetTokenInformation分别获取两个令牌的用户SID、组SID、权限列表,逐一对比这些内容是否完全一致。
  • 结合登录会话ID判断:获取令牌的登录会话ID,再结合用户SID,能大概率判断是否为同一令牌(同一用户同一登录会话的令牌通常一致)。
  • 不推荐直接对比令牌内存:令牌内部结构依赖系统版本,兼容性差,容易出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:52:45