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

ZwQuerySystemInformation查询结果延迟原因及实时进程枚举咨询

问题描述

我正尝试在Windows内核模式下通过进程镜像名称查找进程ID,现有代码可正常运行,但新创建的进程有时会延迟最长60秒才出现在查询结果中,无法被及时找到。我的代码如下:

void WaitForProcess()
{
    LARGE_INTEGER delay;
    HANDLE value = 0;

    delay.QuadPart = -20000000;

    while (!value)
    {
        fpDbgPrintEx(0, 0, "Search\n");

        fpKeDelayExecutionThread(KernelMode, FALSE, &delay); //Sleep for 2 seconds, then retry
        value = HkGetProcessId(675793765); //notepad.exe
    }
}

HANDLE GetProcessId(DWORD processHash)
{
    HANDLE retVal = 0;
    ULONG retLen = 0;
    PSYSTEM_PROCESS_INFORMATION processInfo;
    PVOID infoBuf = NULL;
    WCHAR processName[256];

    fpZwQuerySystemInformation(SystemProcessInformation, 0, 0, &retLen);

    if (!retLen)
        goto Done;

    if (!(infoBuf = fpExAllocatePool(NonPagedPool, retLen)))
        goto Done;

    processInfo = infoBuf;

    if (!NT_SUCCESS(fpZwQuerySystemInformation(SystemProcessInformation, processInfo, retLen, &retLen)))
        goto Done;

    while (processInfo->NextEntryOffset)
    {
        if (processInfo->ImageName.Buffer && (processInfo->ImageName.Length / sizeof(WCHAR)) < 256)
        {
            RtlZeroMemory(processName, 256 * sizeof(WCHAR));
            memcpy(processName, processInfo->ImageName.Buffer, processInfo->ImageName.Length);
            processName[(processInfo->ImageName.Length) / sizeof(WCHAR)] = '\0';

            fpDbgPrintEx(0, 0, "Process: %wZ\n", &processInfo->ImageName);

            if (HashString(processName) == processHash)
            {
                retVal = processInfo->UniqueProcessId;
                break;
            }
        }

        processInfo = (PSYSTEM_PROCESS_INFORMATION)((DWORD_PTR)processInfo + processInfo->NextEntryOffset);
    }

Done:

    if (infoBuf)
        fpExFreePool(infoBuf);

    return retVal;
}
延迟原因分析
  • 进程初始化阶段的ImageName未填充:新进程创建时,内核会先分配进程对象,再完成镜像加载并设置ImageName字段。在这个间隙内,ZwQuerySystemInformation返回的进程信息中ImageName可能为空或未完成初始化,导致你的枚举逻辑直接跳过该进程,直到进程完全初始化完成(最长可能到60秒,取决于系统调度和进程加载速度)。
  • ZwQuerySystemInformation的内部缓存机制:Windows内核对SystemProcessInformation类别的查询结果存在短期缓存,不会实时更新进程列表,导致新进程信息延迟出现在枚举结果中。
实时检测进程的解决方案

方法1:注册进程创建回调(推荐)

使用PsSetCreateProcessNotifyRoutineEx(或低版本系统的PsSetCreateProcessNotifyRoutine)注册回调函数,系统创建新进程时会立即通知驱动,无需轮询。示例代码框架:

NTSTATUS ProcessCreateCallback(
    _Inout_ PEPROCESS Process,
    _In_ HANDLE ProcessId,
    _Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo
)
{
    if (CreateInfo != NULL && CreateInfo->ImageName.Buffer != NULL)
    {
        WCHAR processName[256];
        RtlZeroMemory(processName, sizeof(processName));
        memcpy(processName, CreateInfo->ImageName.Buffer, min(CreateInfo->ImageName.Length, sizeof(processName)-sizeof(WCHAR)));
        processName[CreateInfo->ImageName.Length / sizeof(WCHAR)] = L'\0';

        if (HashString(processName) == 675793765) // 匹配notepad.exe的哈希
        {
            fpDbgPrintEx(0, 0, "Found target process: %wZ, PID: %d\n", &CreateInfo->ImageName, ProcessId);
            // 此处处理找到进程后的逻辑
        }
    }
    return STATUS_SUCCESS;
}

// 驱动初始化时注册回调
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(RegistryPath);
    NTSTATUS status = PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, FALSE);
    if (!NT_SUCCESS(status))
    {
        fpDbgPrintEx(0, 0, "Failed to register process callback: 0x%X\n", status);
        return status;
    }
    DriverObject->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

// 驱动卸载时注销回调
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    UNREFERENCED_PARAMETER(DriverObject);
    PsSetCreateProcessNotifyRoutineEx(ProcessCreateCallback, TRUE);
}

方法2:优化轮询枚举逻辑

如果必须使用轮询,可做以下优化:

  • 不要跳过ImageName为空的进程,记录其UniqueProcessId,后续轮询时单独针对这些PID调用ZwQueryInformationProcess查询进程名称,确认是否为目标进程。
  • 适当缩短轮询间隔(注意内核中频繁轮询会增加系统开销,需权衡)。
注意事项
  • 进程回调函数必须执行高效,避免阻塞系统线程,禁止在回调中执行耗时操作。
  • 驱动需确保具备足够权限,内核模式下通常默认满足,但需注意系统版本兼容性(PsSetCreateProcessNotifyRoutineEx从Windows Vista开始支持)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:54:18