【问题标题】:OpenProcess() Access_Denied with SeDebugPrivilegeOpenProcess() Access_Denied 与 SeDebugPrivilege
【发布时间】:2018-11-29 21:48:40
【问题描述】:

此程序枚举所有句柄并获取它们的名称。

对于 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)。

【问题讨论】:

  • 系统阻止某些类型的对受保护进程的访问。见docs.microsoft.com/en-us/windows/desktop/procthread/…
  • 我知道。这不仅适用于 Win10,也适用于 Win7 和 Win8。 This application 以与我的应用程序相同的方式获取系统进程(PID 4)的句柄,并且可以在 Win10 上运行。我如何在我的应用程序中做到这一点?
  • 那个 Codeproject 应用程序有一个驱动程序。如果您在没有驱动程序强制它进入其他代码路径的情况下运行它会发生什么?
  • 你尝试打开protected process。通常你只能获得PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE 访问权限
  • 作为单独的注释 - 代码效率很低,包含错误和泄漏

标签: c++ winapi


【解决方案1】:

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

如果指定进程是Idle进程或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);
}

希望对你有帮助!

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多