NtQuerySystemInformation参数详解

    技术2025-07-26  13

    NtQuerySystemInformation函数,其中SystemBasicInformation(0号功能)返回的结果是一个SYSTEM_BASIC_INFORMATION结构,其中的域bKeNumberProcessors将返回系统CPU的个数。 下面是该函数的具体说明: /×------------------------------------------------------------- NtQuerySystemInformation is used to check some system informations avaiable only in KernelMode (above 0x80000000). All avaiable (or all known) information classes are described in SYSTEM_INFORMATION_CLASS. Requirements Client: Requires Windows XP or Windows 2000 Professional. Server: Requires Windows 2000 Server. Header: Declared in Winternl.h. DLL: Requires Ntdll.dll. [NtQuerySystemInformation is available for use in Windows 2000 and Windows XP. It may be altered or unavailable in subsequent versions. Applications should use the alternate functions listed in this topic.] */ 注:NtQuerySystemInformation底层使用中写为ZwQuerySystemInformation,两个函数完全相同,只是入口不同。 NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(              //SystemInformationClass              //[in] One of the values enumerated in SYSTEM_INFORMATION_CLASS,              //indicating the kind of system information to be retrieved.              IN SYSTEMINFOCLASS SystemInformationClass,              // SystemInformation              // [in, out] Points to a buffer where the requested information is              // to be returned. The size and structure of this information varies              // depending on the value of the SystemInformationClass parameter:              OUT PVOID pSystemInformation,              //  SystemInformationLength              //  [in] Size of the buffer pointed to by the SystemInformation parameter,              //  in bytes.              IN ULONG uSystemInformationLength,              //  ReturnLength              //  [out, optional] Optional pointer to a location where the function              //  writes the actual size of the information requested.              //  If that size is less than or equal to the SystemInformationLength              //  parameter, the function copies the information into the              //  SystemInformation buffer; otherwise, it returns an NTSTATUS error code              //  and returns in ReturnLength the size of buffer required to receive              //  the requested information.              OUT PULONG puReturnLength OPTIONAL              ); //  Return Values //  Returns an NTSTATUS success or error code. //  The forms and significance of NTSTATUS error codes are listed //  in the Ntstatus.h header file available in the Windows Device //  Driver Kit (DDK), and are described in the DDK documentation //  under Kernel-Mode Driver Architecture / Design Guide / Driver //  Programming Techniques / Logging Errors. typedef enum _SYSTEMINFOCLASS {     SystemBasicInformation, //0     SystemProcessorInformation, // 1     SystemPerformanceInformation, //2     SystemTimeOfDayInformation, //3     SystemPathInformation, //4 SystemNotImplemented1     SystemProcessInformation, //5  per process SystemProcessesAndThreadsInformation     SystemCallCountInformation, //6  SystemCallInformation     SystemConfigurationInformation, //7    SystemDeviceInformation     SystemProcessorPerformanceInformation, //8  per cpu SystemProcessorCounters     SystemGlobalFlag, //SystemFlagsInformation     SystemCallTimeInformation, //10     SystemModuleInformation, //11     SystemLockInformation, //12     SystemStackTraceInformation, //13  SystemNotImplemented2     SystemPagedPoolInformation, //14   checked build only     SystemNonPagedPoolInformation, //15  checked build only     SystemHandleInformation, //16     SystemObjectInformation, //17   SystemObjectTypeInformation     SystemPageFileInformation, //18  per page file     SystemVdmInstemulInformation, //19  SystemVdmInstemulInformation     SystemVdmBopInformation, //20     SystemFileCacheInformation, //21     SystemPoolTagInformation, //22     SystemInterruptInformation, //23     SystemDpcBehaviorInformation, //24     SystemFullMemoryInformation, //25  checked build only     SystemLoadGdiDriverInformation, //26  set mode only     SystemUnloadGdiDriverInformation, //27  set mode only     SystemTimeAdjustmentInformation, //28  writeable     SystemSummaryMemoryInformation, //29  checked build only     SystemNextEventIdInformation, //30  checked build only     SystemEventIdsInformation, //31  checked build only     SystemCrashDumpInformation, //32     SystemExceptionInformation, //33     SystemCrashDumpStateInformation, //34     SystemKernelDebuggerInformation, //35     SystemContextSwitchInformation, //36     SystemRegistryQuotaInformation, //37     SystemExtendServiceTableInformation, //38  set mode only  SystemAddDriver     SystemPrioritySeperation, //39  set mode only    SystemPrioritySeparationInformation     SystemPlugPlayBusInformation, //40  not implemented     SystemDockInformation, //41  not implemented     SystemPowerInformation, //42  XP only     SystemProcessorSpeedInformation, //43  XP only     SystemCurrentTimeZoneInformation, //44     SystemLookasideInformation, //45     SystemSetTimeSlipEvent, //46     SystemCreateSession, // set mode only     SystemDeleteSession, // set mode only     SystemInvalidInfoClass1, // invalid info class     SystemRangeStartInformation, // 0x0004 (fails if size != 4)     SystemVerifierInformation,     SystemAddVerifier,     SystemSessionProcessesInformation, // checked build only     MaxSystemInfoClass } SYSTEMINFOCLASS, *PSYSTEMINFOCLASS; typedef struct _SYSTEM_BASIC_INFORMATION {   DWORD dwUnknown1; // 0   ULONG uKeMaximumIncrement; // x86: 0x0002625A or 0x00018730   ULONG uPageSize; // bytes   ULONG uMmNumberOfPhysicalPages;   ULONG uMmLowestPhysicalPage;   ULONG uMmHighestPhysicalPage;   ULONG uAllocationGranularity; // bytes   PVOID pLowestUserAddress;   PVOID pMmHighestUserAddress;   KAFFINITY uKeActiveProcessors;   BYTE bKeNumberProcessors;   BYTE bUnknown2;   WORD wUnknown3; } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {   LARGE_INTEGER IdleTime;   LARGE_INTEGER KernelTime;   LARGE_INTEGER UserTime;   LARGE_INTEGER DpcTime;   LARGE_INTEGER InterruptTime;   DWORD InterruptCount;   DWORD dwUnknown1; } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION typedef struct _SYSTEM_PERFORMANCE_INFORMATION {   LARGE_INTEGER liIdleTime;   LARGE_INTEGER IoReadTransferCount;   LARGE_INTEGER IoWriteTransferCount;   LARGE_INTEGER IoOtherTransferCount;   ULONG IoReadOperationCount;   ULONG IoWriteOperationCount;   ULONG IoOtherOperationCount;   ULONG AvailablePages;   ULONG CommittedPages;   ULONG CommitLimit;   ULONG PeakCommitment;   ULONG PageFaultCount;   ULONG CopyOnWriteCount;   ULONG TransitionCount;   ULONG CacheTransitionCount;   ULONG DemandZeroCount;   ULONG PageReadCount;   ULONG PageReadIoCount;   ULONG CacheReadCount;   ULONG CacheIoCount;   ULONG DirtyPagesWriteCount;   ULONG DirtyWriteIoCount;   ULONG MappedPagesWriteCount;   ULONG MappedWriteIoCount;   ULONG PagedPoolPages;   ULONG NonPagedPoolPages;   ULONG PagedPoolAllocs;   ULONG PagedPoolFrees;   ULONG NonPagedPoolAllocs;   ULONG NonPagedPoolFrees;   ULONG FreeSystemPtes;   ULONG ResidentSystemCodePage;   ULONG TotalSystemDriverPages;   ULONG TotalSystemCodePages;   ULONG NonPagedPoolLookasideHits;   ULONG PagedPoolLookasideHits;   ULONG Spare3Count;   ULONG ResidentSystemCachePage;   ULONG ResidentPagedPoolPage;   ULONG ResidentSystemDriverPage;   ULONG CcFastReadNoWait;   ULONG CcFastReadWait;   ULONG CcFastReadResourceMiss;   ULONG CcFastReadNotPossible;   ULONG CcFastMdlReadNoWait;   ULONG CcFastMdlReadWait;   ULONG CcFastMdlReadResourceMiss;   ULONG CcFastMdlReadNotPossible;   ULONG CcMapDataNoWait;   ULONG CcMapDataWait;   ULONG CcMapDataNoWaitMiss;   ULONG CcMapDataWaitMiss;   ULONG CcPinMappedDataCount;   ULONG CcPinReadNoWait;   ULONG CcPinReadWait;   ULONG CcPinReadNoWaitMiss;   ULONG CcPinReadWaitMiss;   ULONG CcCopyReadNoWait;   ULONG CcCopyReadWait;   ULONG CcCopyReadNoWaitMiss;   ULONG CcCopyReadWaitMiss;   ULONG CcMdlReadNoWait;   ULONG CcMdlReadWait;   ULONG CcMdlReadNoWaitMiss;   ULONG CcMdlReadWaitMiss;   ULONG CcReadAheadIos;   ULONG CcLazyWriteIos;   ULONG CcLazyWritePages;   ULONG CcDataFlushes;   ULONG CcDataPages;   ULONG ContextSwitches;   ULONG FirstLevelTbFills;   ULONG SecondLevelTbFills;   ULONG SystemCalls; } 我们在任务管理器中所见到的所有信息只使用了下面5个调用: 0    SystemBasicInformation 2    SystemPerformanceInformation 5    SystemProcessInformation 8    SystemProcessorPerformanceInformation 21   SystemFileCacheInformation 初始化部分使用了其中的3个调用(0、2、8),这里给出的是任务管理器的初始化部分: 010058D6 InitPerfInfo proc near 010058D6 010058D6 SYSPROCPERFINFO= SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ptr -76Ch 010058D6 SYSPERFINFO= SYSTEM_PERFORMANCE_INFORMATION ptr -16Ch 010058D6 SYSBASICINFO= SYSTEM_BASIC_INFORMATION ptr -34h 010058D6 pBuf= dword ptr -8 010058D6 i   = dword ptr -4 010058D6 010058D6     push ebp 010058D7     mov ebp, esp 010058D9     sub esp, 76Ch 010058DF     push ebx 010058E0     push esi 010058E1     xor ebx, ebx 010058E3     push edi 010058E4     push ebx                ; puReturnLength 010058E5     lea eax, [ebp+SYSBASICINFO] 010058E8     push 2Ch                ; SizeOf(SYSTEM_BASIC_INFORMATION) 010058EA     push eax                ; pSystemInformation 010058EB     push ebx                ; ebx = 0  SystemBasicInformation 010058EC     call ds:NtQuerySystemInformation 010058F2     cmp eax, ebx 010058F4     jl  Err_CpuNumAbove32 010058FA     mov eax, [ebp+SYSBASICINFO.uPageSize] 010058FD     mov g_PageSize, eax     ; 页面大小 01005902     mov al, [ebp+SYSBASICINFO.bKeNumberProcessors] 01005905     cmp al, 32              ; 32位Windows操作系统最多允许系统有32个CPU 01005907     mov g_cProcessors, al   ; CPU的个数 0100590C     ja  Err_CpuNumAbove32 01005912     mov esi, ds:LocalAlloc 01005918     mov edi, 1F40h 0100591D     test al, al 0100591F     jbe short CpuNumEquOne 01005921 01005921 Loop_for_AllocMem: 01005921     push edi 01005922     push LMEM_ZEROINIT 01005924     call esi ; LocalAlloc 01005926     test eax, eax 01005928     mov g_pCPUHistory[ebx*4], eax 0100592F     jz  Err_CpuNumAbove32 01005935     push edi 01005936     push LMEM_ZEROINIT 01005938     call esi ; LocalAlloc 0100593A     test eax, eax 0100593C     mov g_pKernelHistory[ebx*4], eax 01005943     jz  Err_CpuNumAbove32 01005949     movzx eax, g_cProcessors 01005950     inc ebx 01005951     cmp ebx, eax 01005953     jl  short Loop_for_AllocMem 01005955 01005955 CpuNumEquOne: 01005955     push edi 01005956     push LMEM_ZEROINIT 01005958     call esi ; LocalAlloc 0100595A     test eax, eax 0100595C     mov g_pMEMHistory, eax 01005961     jz  Err_CpuNumAbove32 01005967     push 0                  ; puReturnLength 01005969     lea eax, [ebp+SYSPROCPERFINFO] 0100596F     push 600h               ; 为32个CPU准备空间 0100596F                             ; SizeOf(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*32 01005974     push eax                ; pSystemInformation 01005975     push SystemProcessorPerformanceInformation ; SystemInformationClass 01005977     call ds:NtQuerySystemInformation 0100597D     test eax, eax 0100597F     jl  Err_CpuNumAbove32 01005985     movzx eax, g_cProcessors 0100598C     and [ebp+i], 0 01005990     test eax, eax 01005992     jle short CpuNumEquOne_1 01005994     lea eax, [ebp+SYSPROCPERFINFO.KernelTime] 0100599A     mov [ebp+pBuf], offset PreviousCPUKernelTime 010059A1 010059A1 Loop_IniCpuAllTime: 010059A1     mov ecx, [ebp+i] 010059A4     mov edx, [eax-8]        ; edx = IdleTime.LowPart 010059A7     mov edi, [eax+8]        ; edi = UserTime.LowPart 010059AA     mov esi, [eax+4]        ; esi = KernelTime.HighPart 010059AD     shl ecx, 3              ; ecx = i X 8 010059B0     mov ebx, [eax+0Ch]      ; ebx = UserTime.HighPart 010059B3     mov dword ptr PreviousCPUIdleTime.LowPart[ecx], edx 010059B9     mov edx, [eax-4]        ; edx = IdleTime.HighPart 010059BC     mov PreviousCPUIdleTime.HighPart[ecx], edx 010059C2     mov edx, [eax]          ; KernelTime.LowPart 010059C4     add edi, edx            ; edi = UserTime.LowPart + KernelTime.LowPart 010059C6     adc ebx, esi            ; 带进位加 010059C6                             ; ebx = UserTime.HighPart + KernelTime.HighPart 010059C8     add edx, [eax-8]        ; edx = KernelTime.LowPart + IdleTime.LowPart 010059CB     mov dword ptr PreviousCPUTotalTime.LowPart[ecx], edi 010059D1     mov PreviousCPUTotalTime.HighPart[ecx], ebx 010059D7     mov ecx, [ebp+pBuf]     ; PreviousCPUKernelTime的指针 010059DA     adc esi, [eax-4]        ; 带进位加 010059DA                             ; esi = KernelTime.HighPart + IdleTime.HighPart 010059DD     add eax, 30h            ; 取下一个CPU的相关数据 010059DD                             ; SizeOf(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) 010059E0     inc [ebp+i] 010059E3     mov [ecx], edx          ; PreviousCPUTotalTime.LowPart = KernelTime.LowPart + IdleTime.LowPart 010059E5     mov [ecx+4], esi        ; PreviousCPUTotalTime.HighPart = KernelTime.HighPart + IdleTime.HighPart 010059E8     add ecx, 8              ; 移动PreviousCPUKernelTime的指针 010059EB     mov [ebp+pBuf], ecx     ; 保存PreviousCPUKernelTime的指针 010059EE     movzx ecx, g_cProcessors 010059F5     cmp [ebp+i], ecx        ; 和Cpu的个数比较 010059F8     jl  short Loop_IniCpuAllTime 010059FA 010059FA CpuNumEquOne_1:             ; puReturnLength 010059FA     push 0 010059FC     lea eax, [ebp+SYSPERFINFO] 01005A02     push 138h               ; SizeOf(SYSTEM_PERFORMANCE_INFORMATION) 01005A07     push eax                ; pSystemInformation 01005A08     push SystemPerformanceInformation ; SystemInformationClass 01005A0A     call ds:NtQuerySystemInformation 01005A10     test eax, eax 01005A12     jge short Init_Exit 01005A14 01005A14 Err_CpuNumAbove32:          ; 如果出错返回 0 01005A14     xor al, al 01005A16     jmp short Exit 01005A18 01005A18 Init_Exit: 01005A18     mov eax, g_PageSize 01005A1D     shr eax, 10 01005A20     imul eax, [ebp+SYSPERFINFO.CommitLimit] 01005A27     mov g_MEMMax, eax 01005A2C     mov al, g_cProcessors   ; 返回Cpu的个数 01005A31 01005A31 Exit: 01005A31     pop edi 01005A32     pop esi 01005A33     pop ebx 01005A34     leave 01005A35     retn 01005A35 InitPerfInfo endp 01005A35 NtQuerySystemInformation非常复杂,其中的结构随着Windows的版本变化会发生变化,这里给出的结构是2K系统的。

    最新回复(0)