具有SeDebugPrivilege的OpenProcess()Access_Denied

时间:2018-11-29 21:48:41

标签: c++ winapi

该程序枚举所有句柄并获取其名称。

对于pID 4,OpenProcess出现SeDebugPrivilege错误5。

关闭UAC。从管理员运行。

启用SeDebugPrivilege

BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = nullptr;
LUID luid;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE;
TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return FALSE;
_tprintf(_T("Privileges error: %d\n", GetLastError()));
return TRUE;
}

枚举句柄

DWORD EnumerateFileHandles(ULONG pid)
{
    HINSTANCE hNtDll = LoadLibrary(_T("ntdll.dll"));
    assert(hNtDll != NULL);
    PFN_NTQUERYSYSTEMINFORMATION NtQuerySystemInformation =
        (PFN_NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll,
            "NtQuerySystemInformation");
    assert(NtQuerySystemInformation != NULL);
    PFN_NTQUERYINFORMATIONFILE NtQueryInformationFile =
        (PFN_NTQUERYINFORMATIONFILE)GetProcAddress(hNtDll,
            "NtQueryInformationFile");
    DWORD nSize = 4096, nReturn;
    PSYSTEM_HANDLE_INFORMATION pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)
        HeapAlloc(GetProcessHeap(), 0, nSize);
    while (NtQuerySystemInformation(SystemExtendedHandleInformation, pSysHandleInfo,
        nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH)
    {
        HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
        nSize += 4096;
        pSysHandleInfo = (SYSTEM_HANDLE_INFORMATION*)HeapAlloc(
            GetProcessHeap(), 0, nSize);
    }
    DWORD dwFiles = 0;
    _tprintf(_T("Handles Number: %d\n"), pSysHandleInfo->NumberOfHandles);
    for (ULONG i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
    {
        PSYSTEM_HANDLE pHandle = &(pSysHandleInfo->Handles[i]);
        if (pHandle->ProcessId == 4)
        {
            HANDLE hProcess = OpenProcess(
                PROCESS_DUP_HANDLE, FALSE, pHandle->ProcessId);
            if (hProcess == NULL)
            {
                _tprintf(_T("OpenProcess failed w/err 0x%08lx\n"), GetLastError());
                continue;
            }
            HANDLE hCopy;
            if (!DuplicateHandle(hProcess, (HANDLE)pHandle->Handle,
                GetCurrentProcess(), &hCopy, MAXIMUM_ALLOWED, FALSE, 0))
                continue;
            TCHAR buf[MAX_PATH];
            if (GetFinalPathNameByHandle(hCopy, buf, sizeof(buf), VOLUME_NAME_DOS))
                wprintf(L"p%d:h%d:t%d:\t%s\n", pHandle->ProcessId, pHandle->Handle, pHandle->ObjectTypeNumber, buf);
            CloseHandle(hProcess);
            CloseHandle(hCopy);
        }
    }
    HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
    return dwFiles;
}

在Windows 7 x64上运行正常。 但是在Windows 10 x64上,OpenProcess带有SeDebugPrivilege返回错误5。

如何在Windows 10上打开系统进程(pID 4)。

1 个答案:

答案 0 :(得分:0)

您无法打开它的句柄,因为OpenProcess的documentation明确指出它将失败:

  

如果指定的进程是空闲进程或CSRSS之一   进程,此函数失败,最后一个错误代码是   ERROR_ACCESS_DENIED,因为其访问限制阻止   打开用户级别的代码。

如果要获取系统进程名称,可以尝试使用CreateToolhelp32Snapshot()获取进程的快照,然后使用Process32First()Process32Next()枚举所有进程。 这是一个示例:

#include <iostream> 
#include <stdio.h>
#include <windows.h>
#include <string> 
#include <TlHelp32.h> 
using namespace std;
int main()
{
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(pe32);
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//get the snapshot 
    if (hProcessSnap == INVALID_HANDLE_VALUE) 
    {
        cout << "CreateToolhelp32Snapshot Error!" << endl;
        return false;
    }
    BOOL bResult = Process32First(hProcessSnap, &pe32);
    int num(0);
    while(bResult)
    {
        cout << "[" << ++num << "] : " << "Process Name:"<< pe32.szExeFile << "  " << "ProcessID:" << pe32.th32ProcessID << endl;
        bResult = Process32Next(hProcessSnap, &pe32);

    }
    CloseHandle(hProcessSnap);
}

希望它可以为您提供帮助!