4

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

我发现至少在一种环境(但不是全部)中,调用OpenProcess失败并显示ERROR_ACCESS_DENIED. 此外,我发现如果我使用AdjustTokenPrivileges获取SE_DEBUG_NAME权限,则OpenProcess成功。我已经使用下面的程序重现了该行为。它失败的环境是运行 Windows 8.1,但我不知道成功的系统正在运行什么。

程序请求的唯一权限是PROCESS_QUERY_LIMITED_INFORMATION(因为它最终会调用QueryFullProcessImageName)。我读过的任何内容都没有表明需要调试权限,仅用于更“侵入性”的访问,例如PROCESS_VM_READor 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;
    }
}
4

0 回答 0