为何NtQuerySystemInformation在x32编译版本中无法正常工作?
问题原因与解决方案
你的代码在32位编译下返回STATUS_INFO_LENGTH_MISMATCH的核心原因是缓冲区分配逻辑错误:你没有根据NtQuerySystemInformation返回的ReturnLength调整缓冲区大小,且循环中始终用0作为ImageName.MaximumLength分配内存,导致无法满足系统要求的缓冲区长度。
关键修正点
- 先调用一次
NtQuerySystemInformation获取所需的总缓冲区大小(包含结构体和进程路径字符串的完整长度)。 - 分配连续的缓冲区,将
SYSTEM_PROCESS_ID_INFORMATION结构体和字符串空间放在同一块内存中(系统要求缓冲区连续)。 - 用
ULONG_PTR转换PID到HANDLE,保证32/64位平台的兼容性。 - 正确设置
ImageName的Buffer指向结构体后的内存区域,MaximumLength设为总缓冲区大小减去结构体本身的大小。
修正后的完整代码
#include <Windows.h> #include <ntstatus.h> #include <winternl.h> #include <stdio.h> #pragma comment(lib, "ntdll.lib") struct SYSTEM_PROCESS_ID_INFORMATION { HANDLE ProcessId; UNICODE_STRING ImageName; }; NTSTATUS GetProcessPath(const DWORD pid) { SYSTEM_PROCESS_ID_INFORMATION info = { 0 }; info.ProcessId = reinterpret_cast<HANDLE>(static_cast<ULONG_PTR>(pid)); ULONG ReturnLength = 0; // 第一次调用获取所需的总缓冲区大小 NTSTATUS status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(0x58), &info, sizeof(info), &ReturnLength); if (status != STATUS_INFO_LENGTH_MISMATCH) { return status; } // 分配包含结构体和字符串的连续缓冲区 PBYTE pBuffer = static_cast<PBYTE>(LocalAlloc(LMEM_FIXED, ReturnLength)); if (!pBuffer) { return STATUS_NO_MEMORY; } // 初始化缓冲区中的结构体 SYSTEM_PROCESS_ID_INFORMATION* pInfo = reinterpret_cast<SYSTEM_PROCESS_ID_INFORMATION*>(pBuffer); pInfo->ProcessId = info.ProcessId; pInfo->ImageName.MaximumLength = static_cast<USHORT>(ReturnLength - sizeof(SYSTEM_PROCESS_ID_INFORMATION)); pInfo->ImageName.Buffer = reinterpret_cast<PWSTR>(pBuffer + sizeof(SYSTEM_PROCESS_ID_INFORMATION)); pInfo->ImageName.Length = 0; // 第二次调用获取进程路径 status = NtQuerySystemInformation(static_cast<SYSTEM_INFORMATION_CLASS>(0x58), pInfo, ReturnLength, &ReturnLength); if (NT_SUCCESS(status)) { wprintf(L"PID %u 的路径: %s\n", pid, pInfo->ImageName.Buffer); } LocalFree(pBuffer); return status; } int main() { // 替换为实际存在的进程ID GetProcessPath(9200); return 0; }
补充说明
SystemProcessIdInformation(编号0x58)属于未公开API,其行为可能随Windows版本变化,使用时需注意兼容性。- 该方法确实可以在非管理员权限下获取其他用户进程的路径(只要当前用户有足够权限访问目标进程)。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

