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

内核模式移除PROCESS_SUSPEND_RESUME致进程永久挂起求助

问题:移除notepad.exe句柄权限后进程永久挂起的解决方法

问题背景

  • 内核与C++开发新手,正在测试句柄创建预操作例程,目标是移除notepad.exe句柄的PROCESS_TERMINATE(0x0001)和PROCESS_SUSPEND_RESUME(0x0800)权限,实现进程正常运行的同时阻止被终止或挂起。
  • 当前代码可成功移除权限,但notepad.exe启动后会永久挂起。
  • 开发环境:宿主Visual Studio 2019,宿主与目标物理机均运行Windows 10 1909。

当前代码:

if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) 
{
        OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~0x0001;
        OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~0x0800;
        KdPrint(("[OperationInformation->Operation]: OB_OPERATION_HANDLE_CREATE\r\n"));
}

原因分析与解决方法

1. 未过滤进程自身的句柄创建操作

你的代码会修改所有进程的句柄创建权限,包括notepad.exe自身创建的句柄。进程启动过程中,自身需要PROCESS_SUSPEND_RESUME权限完成线程初始化(比如启动时的线程挂起/恢复逻辑),如果自身句柄被移除该权限,会导致初始化失败,进程挂起。

修正代码:
添加进程判断,仅修改外部进程对notepad.exe创建的句柄权限,跳过notepad.exe自身的句柄操作:

#include <ntddk.h>

VOID PreHandleCreateCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) 
    {
        // 获取目标进程对象
        PEPROCESS targetProcess = (PEPROCESS)OperationInformation->Object;
        UNICODE_STRING targetProcessName;
        RtlInitUnicodeString(&targetProcessName, L"notepad.exe");

        // 获取当前操作对应的进程名
        UNICODE_STRING currentObjName;
        NTSTATUS status = PsGetProcessImageFileName(targetProcess, &currentObjName);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("[Failed to get process image name: 0x%X]\r\n", status));
            return;
        }

        // 仅当目标是notepad.exe,且操作发起者不是notepad自身时修改权限
        if (RtlCompareUnicodeString(&currentObjName, &targetProcessName, TRUE) == 0)
        {
            PEPROCESS currentProcess = PsGetCurrentProcess();
            if (currentProcess != targetProcess)
            {
                // 移除指定权限
                OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
                OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_SUSPEND_RESUME;
                KdPrint(("[Modified external handle access for notepad.exe]\r\n"));
            }
            else
            {
                // 允许自身保留权限,保证初始化正常
                KdPrint(("[Skipped notepad.exe self-handle creation]\r\n"));
            }
        }

        // 释放字符串内存
        RtlFreeUnicodeString(&currentObjName);
    }
}

2. 区分进程创建时的初始句柄

进程启动时,系统或父进程会创建一个初始句柄(带有OB_OPERATION_HANDLE_CREATE_FROM_CREATE_PROCESS标志),这类句柄的权限修改可能直接影响进程启动流程。可以通过OperationFlags判断并跳过:

在上述代码的权限修改判断中添加:

// 跳过进程创建时的初始句柄
if (OperationInformation->OperationFlags & OB_OPERATION_HANDLE_CREATE_FROM_CREATE_PROCESS)
{
    KdPrint(("[Skipped initial process creation handle]\r\n"));
    return;
}

3. 调试定位挂起原因

使用WinDbg附加到目标物理机,查看notepad.exe的挂起状态:

  • 执行 !process 0 0 notepad.exe 获取进程的EPROCESS地址
  • 执行 !process <EPROCESS地址> 7 查看线程调用栈,确认挂起的系统调用位置,是否因权限不足导致

内容的提问来源于stack exchange,提问作者David Figueras Tamame

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:48:29