One of my programs attempts to call OpenProcess
on another of my programs, which is a service. The first program is running either as the local Administrator account or as another member of the Administrators group, and the service is running as the SYSTEM user.
I've found that in at least one environment (but not all) the call to OpenProcess
fails with ERROR_ACCESS_DENIED
. Furthermore, I've found that if I use AdjustTokenPrivileges
to acquire the SE_DEBUG_NAME
privilege, then OpenProcess
succeeds. I've reproduced the behavior using the program below. The environment where it fails is running Windows 8.1, but off hand I don't know what the successful systems are running.
The only permission the program requests is PROCESS_QUERY_LIMITED_INFORMATION
(because it eventually calls QueryFullProcessImageName
). Nothing I've read suggests that debug privileges are required for that, only for more "intrusive" access like PROCESS_VM_READ
or PROCESS_ALL_ACCESS
, which I'm not interested in.
I've read about protected processes, and even though the service I'm targeting isn't designated as a protected process, documentation says that PROCESS_QUERY_LIMITED_INFORMATION
isn't among the permissions that are forbidden from being granted for protected processes anyway.
Why would the original call to OpenProcess
fail, and why does the debugging privilege make a difference?
#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;
}
}