我的一个程序试图在我的另一个程序上调用OpenProcess
,这是一项服务。第一个程序作为本地管理员帐户或Administrators组的另一个成员运行,并且该服务作为SYSTEM用户运行。
我发现在至少一个环境(但不是全部)中,对OpenProcess
的调用因ERROR_ACCESS_DENIED
而失败。此外,我发现如果我使用AdjustTokenPrivileges
获取SE_DEBUG_NAME
权限,那么OpenProcess
会成功。我使用下面的程序重现了这种行为。它失败的环境是运行Windows 8.1,但是我不知道成功的系统正在运行什么。
程序请求的唯一权限是PROCESS_QUERY_LIMITED_INFORMATION
(因为它最终会调用QueryFullProcessImageName
)。我没有读到任何内容表明需要调试权限,仅用于PROCESS_VM_READ
或PROCESS_ALL_ACCESS
这样的“侵入式”访问,我对此并不感兴趣。
我已经阅读了受保护进程,即使我定位的服务未被指定为受保护进程,documentation也表示PROCESS_QUERY_LIMITED_INFORMATION
isn'无论如何,禁止为受保护进程授予的权限。
为什么对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;
}
}