我的一个程序试图调用OpenProcess
我的另一个程序,这是一项服务。第一个程序以本地管理员帐户或管理员组的另一个成员身份运行,并且该服务以 SYSTEM 用户身份运行。
我发现至少在一种环境(但不是全部)中,调用OpenProcess
失败并显示ERROR_ACCESS_DENIED
. 此外,我发现如果我使用AdjustTokenPrivileges
获取SE_DEBUG_NAME
权限,则OpenProcess
成功。我已经使用下面的程序重现了该行为。它失败的环境是运行 Windows 8.1,但我不知道成功的系统正在运行什么。
程序请求的唯一权限是PROCESS_QUERY_LIMITED_INFORMATION
(因为它最终会调用QueryFullProcessImageName
)。我读过的任何内容都没有表明需要调试权限,仅用于更“侵入性”的访问,例如PROCESS_VM_READ
or PROCESS_ALL_ACCESS
,我不感兴趣。
我已经阅读了有关受保护进程的信息,即使我所针对的服务没有被指定为受保护进程,但文档说这PROCESS_QUERY_LIMITED_INFORMATION
不在被禁止授予受保护进程的权限之列。
为什么最初的调用会OpenProcess
失败,为什么调试权限会有所不同?
#include <Windows.h>
#include <iostream>
#include <sstream>
#include <string>
int main(int argc, char* argv[])
{
std::istringstream pid_s(argv[1]);
DWORD pid;
pid_s >> pid;
bool debug = !!argv[2];
if (debug) {
TOKEN_PRIVILEGES NewState;
NewState.PrivilegeCount = 1;
if (!LookupPrivilegeValue(nullptr, SE_DEBUG_NAME, &NewState.Privileges[0].Luid)) {
std::clog << "Could not acquire debug-privilege name: " << GetLastError() << "\n";
return EXIT_FAILURE;
}
HANDLE token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) {
std::clog << "Could not acquire process token: " << GetLastError() << "\n";
return EXIT_FAILURE;
}
NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(token, FALSE, &NewState, sizeof(NewState), nullptr, nullptr)) {
std::clog << "Could not enable debug privilege: " << GetLastError() << "\n";
return EXIT_FAILURE;
}
std::clog << "Acquired debug privilege\n";
} else {
std::clog << "Not acquiring debug privilege\n";
}
HANDLE proc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid);
if (proc) {
std::clog << "Acquired process handle\n";
CloseHandle(proc);
return EXIT_SUCCESS;
} else {
std::clog << "Failed to acquire process handle: " << GetLastError();
return EXIT_FAILURE;
}
}