WinAPI:当主机进程启用SeDebugPrivilege时,OpenProcess()返回错误5

3
我有一个程序,我会处理每个进程的HANDLE,当我沿着列表顺序“遍历”时,这个程序运行得很好。但是问题出在当我执行:HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID),其中 PROCESS_ALL_ACCESS 是访问令牌,句柄继承设置为FALSE,并且pe32是一个PROCESSENTRY32。此时GetLastError()返回错误代码5,并且所有创建的句柄都是不对应Spy++32/64中任何适当的进程的地址(我已经尝试在两个平台目标下构建应用程序,但正如您所期望的那样,结果是相同的)。
我使用的设置主机进程SeDebugPrivilege的代码如下:
BOOL EnableDebugPrivilege(BOOL bEnable)
{
    HANDLE hToken = nullptr;
    LUID luid;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;

    TOKEN_PRIVILEGES tokenPriv;
    tokenPriv.PrivilegeCount = 1;
    tokenPriv.Privileges[0].Luid = luid;
    tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;

    return TRUE;
}

以下是一些有用的问题:

  1. 我正在运行Windows 7 x64专业版。
  2. 是的,devenv.exe以“管理员身份运行”权限启动,这意味着调试器和应用程序本身在相同的亲和力下启动。
  3. 我已经尝试切换UAC或完全关闭UAC运行应用程序。仍然出现错误代码5。
  4. 我刚刚尝试使用PROCESS_QUERY_LIMITED_INFORMATION,结果收到错误代码6或ERROR_INVALID_HANDLE。还尝试了PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,结果再次出现错误5。
  5. SeDebugPrivilege已启用,并通过SysInternals的Process Explorer进行了验证。此外,从devenv/调试器生成的所有进程都继承了SeDebugPrivilege,因此...这很奇怪。

非常感谢大家抽出时间阅读,我对这个问题感到无助 :S


可能是重复的问题,参考链接:https://dev59.com/RUXRa4cB1Zd3GeqPrWjh - Xearinox
@Xearinox:我看到了那个问题,并应用了答案中提到的SeDebugPrivilege。 - David S.
我现在没有WIN 7机器,所以只能猜测。也许尝试PROCESS_QUERY_INFORMATION | PROCESS_VM_READ。也许EnableDebugPrivilege失败了。也许你在其他地方出错了。我没有看到任何错误检查。 :-) - Xearinox
@RaymondChen:我非常确定错误是十进制6,而不是十六进制6。我会在几分钟内再试一次。 - David S.
3
你现在陷入了一个征求比你实际需要更多许可的陷阱。实际上,你只需要其中一个过程的许可,所以不要请求所有过程的许可。这就好比说:“各位请把你们的银行账号号码都给我”,尽管你只对你兄弟的银行账号感兴趣。 - Raymond Chen
显示剩余13条评论
1个回答

2
您确定没有将0作为进程ID值传递吗? ID为0的系统空闲进程在快照中包含在名为[System Process]的名称下,但是您无法打开它的句柄,因为OpenProcess的文档明确指出它会失败。它说得更多一些:
如果指定的进程是系统进程(0x00000000),则该函数失败,最后一个错误代码为ERROR_INVALID_PARAMETER。如果指定的进程是空闲进程或其中一个CSRSS进程,则此函数失败,并且最后一个错误代码为ERROR_ACCESS_DENIED,因为它们的访问限制阻止用户级代码打开它们。
嗯,这并不完全正确,因为我能够打开对CSRSS的句柄(当然,它实际上没有所请求的权限)。但是对于某些受保护的进程(如audiodg),它可能会失败,因此您不应该这样做。相反,检查进程的名称是否是您想要的名称。

我最终采纳了@RaymondChen的建议,只打开我需要打开句柄的应用程序。看起来这是一个更好的方法,谢谢! :) - David S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接