Почему мне нужно приобрести привилегию отладки, чтобы использовать OpenProcess с минимальными разрешениями при работе от имени администратора?
Одна из моих программ пытается позвонить OpenProcess
на другой из моих программ, которая является службой. Первая программа работает как локальная учетная запись администратора или как другой член группы администраторов, а служба работает как пользователь SYSTEM.
Я обнаружил, что по крайней мере в одной среде (но не во всех) OpenProcess
не удается с ERROR_ACCESS_DENIED
, Кроме того, я обнаружил, что если я использую AdjustTokenPrivileges
приобрести SE_DEBUG_NAME
привилегия, то OpenProcess
преуспевает. Я воспроизвел поведение, используя программу ниже. Среда, в которой происходит сбой, работает под управлением Windows 8.1, но я не знаю, какие успешные системы работают.
Единственное разрешение, которое запрашивает программа PROCESS_QUERY_LIMITED_INFORMATION
(потому что это в конечном итоге вызывает QueryFullProcessImageName
). Ничто из того, что я прочитал, не говорит о том, что для этого требуются привилегии отладки, только для более "навязчивого" доступа, такого как PROCESS_VM_READ
или же 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;
}
}