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

x86环境下PsLookupProcessByProcessId崩溃求助:Hook NtOpenProcess触发BSOD

问题排查与解决方案

核心原因分析

x86进程触发STATUS_ACCESS_DENIED蓝屏,核心问题集中在跨架构参数解析错误和内核权限上下文处理不当:

  1. CLIENT_ID结构体的跨架构对齐差异:x86环境下HANDLE为4字节,x64环境下为8字节。HookNtOpenProcess时若直接按x64结构解析32位进程传入的CLIENT_ID,会错误读取UniqueProcess值,导致PsLookupProcessByProcessId传入无效PID,触发权限校验失败或内存访问错误。
  2. 内核调用的权限上下文问题:32位进程的线程上下文在64位内核中会被封装,Hook时若未切换到调用者的权限上下文,直接调用PsLookupProcessByProcessId会因权限不足触发STATUS_ACCESS_DENIED。
  3. PsSetCreateProcessNotifyRoutine的局限性:该回调仅能监控进程创建销毁,无法干预NtOpenProcess的权限校验与参数解析流程,因此无法解决跨架构Hook的核心问题。

具体修复步骤

  • 正确解析跨架构CLIENT_ID:在Hook函数中先通过PsGetProcessWow64Process判断调用者是32位还是64位进程,再对应解析UniqueProcess:
    PCLIENT_ID ClientId = ...; // 从NtOpenProcess参数中获取
    HANDLE ProcessId;
    if (PsGetProcessWow64Process(PsGetCurrentProcess()) != NULL) {
        // 32位进程,按4字节宽度解析UniqueProcess
        ProcessId = (HANDLE)*(ULONG*)&ClientId->UniqueProcess;
    } else {
        // 64位进程,直接读取
        ProcessId = ClientId->UniqueProcess;
    }
    NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &pEprocess);
    
  • 切换到调用者权限上下文:调用PsLookupProcessByProcessId前,使用KeStackAttachProcess切换到目标进程上下文,完成后用KeUnstackDetachProcess恢复,确保权限校验基于调用者的上下文执行。
  • 校验PID有效性:在调用PsLookupProcessByProcessId前,先检查ProcessId是否为有效PID(大于0且非系统特殊PID),避免传入无效值引发内存访问错误。
  • 过滤系统级32位进程:部分系统级32位进程(如32位svchost.exe实例)拥有特殊权限,Hook时处理不当易触发蓝屏,建议先过滤这类进程的调用。

额外注意事项

  • 内核Hook必须严格遵循Windows跨架构兼容性规范,所有参数解析需兼顾32位与64位的差异。
  • 测试时优先在非关键进程上验证,避免影响系统稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:18:37