You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows进程提权后调用OpenProcess访问System进程仍遭拒绝问题

问题描述

尝试使用OpenProcess()函数读取“System”进程的相关信息,但始终收到错误代码5(ERROR_ACCESS_DENIED)。已调用AdjustTokenPrivileges()函数获取调试权限,但问题仍未解决,不清楚代码存在何种问题。

相关代码
int GetInfo()
{
    PROCESSENTRY32 pe32{ sizeof(PROCESSENTRY32) };
    THREADENTRY32 th32{ sizeof(THREADENTRY32) };
    MODULEENTRY32 md32{ sizeof(MODULEENTRY32) };
    PWCHAR Name;
    DWORD id = 0;

    int err = 0;

    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return -1;
    }

    BOOL pResult = Process32First(hProcessSnap, &pe32);
    while (pResult)
    {
        Name = pe32.szExeFile;
        if (lstrcmpW(Name, L"System") == 0)
        {
            id = pe32.th32ProcessID;
            PrivilegeEscalation();
            HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pe32.th32ProcessID);
            err = GetLastError();
            cout << err << endl;
            cout << "The thread number of System is : " << pe32.cntThreads << endl;
            CloseHandle(ProcessHandle);
            break;
        }
        pResult = Process32Next(hProcessSnap, &pe32);
    }

    CloseHandle(hProcessSnap);
    return 0;
}

BOOL PrivilegeEscalation()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES Tp;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        return FALSE;
    }

    Tp.PrivilegeCount = 1;
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Tp.Privileges[0].Luid);
    Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &Tp, sizeof(Tp), NULL, NULL);

    //int err = GetLastError();
    CloseHandle(hToken);
    return TRUE;
}
问题分析与解决方案

核心原因:System进程的特殊性

System进程(通常PID为4)是内核模式进程,它没有用户模式地址空间,用户模式下的OpenProcess函数根本无法打开它——哪怕你拥有SE_DEBUG_NAME权限也不行,这是Windows系统的安全机制决定的。

代码中的其他问题

你的PrivilegeEscalation函数缺少关键的错误检查:

  • 没有检查LookupPrivilegeValue的返回值,如果该函数失败,后续权限调整完全无效。
  • AdjustTokenPrivileges返回TRUE不代表权限启用成功,必须通过GetLastError()判断是否为ERROR_SUCCESS才能确认。

解决建议

  1. 无需OpenProcess获取基础信息:你要的线程数已经在PROCESSENTRY32结构体的cntThreads字段里了,直接用这个值就行,完全不需要调用OpenProcess。
  2. 修复权限提升函数的错误处理:如果需要给其他进程提权,修改PrivilegeEscalation函数,确保每一步都做错误检查:
BOOL PrivilegeEscalation()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES Tp;
    DWORD dwError = 0;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        return FALSE;
    }

    Tp.PrivilegeCount = 1;
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Tp.Privileges[0].Luid))
    {
        CloseHandle(hToken);
        return FALSE;
    }

    Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!AdjustTokenPrivileges(hToken, FALSE, &Tp, sizeof(Tp), NULL, NULL))
    {
        dwError = GetLastError();
        CloseHandle(hToken);
        return FALSE;
    }
    else
    {
        dwError = GetLastError();
        if (dwError != ERROR_SUCCESS)
        {
            // 权限可能未启用(比如当前用户没有该权限)
            CloseHandle(hToken);
            return FALSE;
        }
    }

    CloseHandle(hToken);
    return TRUE;
}
  1. 若需访问System进程内核信息:用户模式API做不到,必须编写内核模式驱动程序才能与System进程交互。

内容的提问来源于stack exchange,提问作者Mr_Cl0ud9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:50:22