为什么在以管理员身份运行时需要获取调试权限以使用具有最小权限的OpenProcess?

时间:2016-12-16 21:12:58

标签: c++ windows permissions openprocess

我的一个程序试图在我的另一个程序上调用OpenProcess,这是一项服务。第一个程序作为本地管理员帐户或Administrators组的另一个成员运行,并且该服务作为SYSTEM用户运行。

我发现在至少一个环境(但不是全部)中,对OpenProcess的调用因ERROR_ACCESS_DENIED而失败。此外,我发现如果我使用AdjustTokenPrivileges获取SE_DEBUG_NAME权限,那么OpenProcess会成功。我使用下面的程序重现了这种行为。它失败的环境是运行Windows 8.1,但是我不知道成功的系统正在运行什么。

程序请求的唯一权限是PROCESS_QUERY_LIMITED_INFORMATION(因为它最终会调用QueryFullProcessImageName)。我没有读到任何内容表明需要调试权限,仅用于PROCESS_VM_READPROCESS_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;
    }
}

0 个答案:

没有答案