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

NtQuerySystemInformation获取SystemHandleInformation返回大小异常问询

NtQuerySystemInformation返回缓冲区大小异常问题解答

问题背景

执行以下代码时,首次调用NtQuerySystemInformation(对应SystemHandleInformation类,即0x10)无法返回正确的缓冲区大小,导致后续调用失败:

PSYSTEM_HANDLE_INFORMATION HandleInfo = NULL;
ULONG HandleInfoLength = 0;

...

result = NTQSI((SYSTEM_INFORMATION_CLASS)0x10, NULL, 0, &HandleInfoLength);
if (result != 0xC0000004) {
    printf("OmmeSearchProcessHandle - NTQSI output is unexpected! Expexted : 0xC0000004 Result : 0x%x\n", result);
    return NULL;
}

printf("system handle info length : %i\n", HandleInfoLength);
SIZE_T HandleInfoRegionSize = HandleInfoLength;
result = NTAVM((HANDLE)(-1), (PVOID*)&HandleInfo, 0, &HandleInfoRegionSize, MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(result)) {
    printf("OmmeSearchProcessHandle - NTAVM failed with result : %x\n", result);
    return NULL;
}

result = NTQSI((SYSTEM_INFORMATION_CLASS)0x10, (PVOID)HandleInfo, HandleInfoLength, &HandleInfoLength);
if (!NT_SUCCESS(result)) {
    printf("OmmeSearchProcessHandle - NTQSI failed with result : %x\n", result);
    printf("system handle info length : %i\n", HandleInfoLength);
    return NULL;
}

疑问解答

1. 首次调用返回大小不正确的原因

  • 系统状态动态变化:SystemHandleInformation对应系统内所有进程的句柄列表,从首次查询大小到分配内存、发起二次调用的间隙,系统可能已创建新进程、打开新资源,实际需要的缓冲区会比之前返回的HandleInfoLength更大。
  • API设计特性:针对部分系统信息类,NtQuerySystemInformation返回的大小只是近似值,并非严格精确的所需字节数,设计上存在模糊性,无法保证完全匹配后续调用的实际需求。

2. 是否属于业内共识

这确实是Windows内核开发领域的普遍共识:

  • 针对SystemHandleInformation这类动态性极强的信息类,成熟工具(比如Sysinternals的Handle工具)都不会依赖单次大小查询结果,而是采用循环重试策略:分配缓冲区后调用,若返回STATUS_INFO_LENGTH_MISMATCH(0xC0000004),就根据新返回的大小重新分配更大的缓冲区,直到调用成功。
  • 你提到的项目开发者的说法,正是这种行业经验的直接体现——单次查询的大小根本赶不上系统状态的实时变化,必须做容错处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:24:23