1
votes

This program enumerate all handles and get their names.

For pID 4 OpenProcess gets error 5 with SeDebugPrivilege.

UAC off. Running from Admin.

Enable 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;
}

Enumerate handles

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;
}

On windows 7 x64 it's work fine. But on Windows 10 x64 OpenProcess returns error 5 with SeDebugPrivilege.

How open system process(pID 4) on windows 10.

1
The system prevents certain types of access to protected processes. See docs.microsoft.com/en-us/windows/desktop/procthread/…Jonathan Potter
I know it. This applies not only to Win10 but also to Win7 and Win8. This application gets a handle of the system process (PID 4) in the same way as my application and it works on Win10. How do i do it in my application?Instixe
That Codeproject app has a driver. What happens if you run it without the driver forcing it down its other codepath?Anders
you try open protected process. usually you can got only PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE accessRbMm
as separate note - code very not efficient, contain errors and leaksRbMm

1 Answers

0
votes

You can't open a handle for it as the documentation for OpenProcess specifically says it'll fail:

If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.

If you want to get system process names, you could try to use CreateToolhelp32Snapshot() to get the snapshot of the process, then use Process32First() and Process32Next() to enumerate the all process. Here is an example:

#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);
}

Hope it could help you!