Tutorial SYSTEM_INFORMATION_CLASS & PROCESSINFOLASS

Opcode

Level 28
Content Creator
Joined
Aug 17, 2017
Messages
1,733
#1
Hello everyone!

If you've ever been required to use Native API functions such as NtQuerySystemInformation/ZwQuerySystemInformation, NtSetSystemInformation/ZwSetSystemInformation, NtQueryInformationProcess/ZwQueryInformationProcess or NtSetInformationProcess/ZwSetInformationProcess then you may have found yourself trying to find the correct class to pass in as a parameter for the function/s. The classes are part of an undocumented enum type definition and Microsoft tend to keep very quiet about these sorts of functions (and their internals).

SYSTEM_INFORMATION_CLASS
Code:
    typedef enum _SYSTEM_INFORMATION_CLASS {
        SystemBasicInformation = 0,
        SystemProcessorInformation = 1,
        SystemPerformanceInformation = 2,
        SystemTimeOfDayInformation = 3,
        SystemPathInformation = 4,
        SystemProcessInformation = 5,
        SystemCallCountInformation = 6,
        SystemDeviceInformation = 7,
        SystemProcessorPerformanceInformation = 8,
        SystemFlagsInformation = 9,
        SystemCallTimeInformation = 10,
        SystemModuleInformation = 11,
        SystemLocksInformation = 12,
        SystemStackTraceInformation = 13,
        SystemPagedPoolInformation = 14,
        SystemNonPagedPoolInformation = 15,
        SystemHandleInformation = 16,
        SystemObjectInformation = 17,
        SystemPageFileInformation = 18,
        SystemVdmInstemulInformation = 19,
        SystemVdmBopInformation = 20,
        SystemFileCacheInformation = 21,
        SystemPoolTagInformation = 22,
        SystemInterruptInformation = 23,
        SystemDpcBehaviorInformation = 24,
        SystemFullMemoryInformation = 25,
        SystemLoadGdiDriverInformation = 26,
        SystemUnloadGdiDriverInformation = 27,
        SystemTimeAdjustmentInformation = 28,
        SystemSummaryMemoryInformation = 29,
        SystemMirrorMemoryInformation = 30,
        SystemPerformanceTraceInformation = 31,
        SystemObsolete0 = 32,
        SystemExceptionInformation = 33,
        SystemCrashDumpStateInformation = 34,
        SystemKernelDebuggerInformation = 35,
        SystemContextSwitchInformation = 36,
        SystemRegistryQuotaInformation = 37,
        SystemExtendedServiceTableInformation = 38,
        SystemPrioritySeparation = 39,
        SystemVerifierAddDriverInformation = 40,
        SystemVerifierRemoveDriverInformation = 41,
        SystemProcessorIdleInformation = 42,
        SystemLegacyDriverInformation = 43,
        SystemCurrentTimeZoneInformation = 44,
        SystemLookasideInformation = 45,
        SystemTimeSlipNotification = 46,
        SystemSessionCreate = 47,
        SystemSessionDetach = 48,
        SystemSessionInformation = 49,
        SystemRangeStartInformation = 50,
        SystemVerifierInformation = 51,
        SystemVerifierThunkExtend = 52,
        SystemSessionProcessInformation = 53,
        SystemLoadGdiDriverInSystemSpace = 54,
        SystemNumaProcessorMap = 55,
        SystemPrefetcherInformation = 56,
        SystemExtendedProcessInformation = 57,
        SystemRecommendedSharedDataAlignment = 58,
        SystemComPlusPackage = 59,
        SystemNumaAvailableMemory = 60,
        SystemProcessorPowerInformation = 61,
        SystemEmulationBasicInformation = 62,
        SystemEmulationProcessorInformation = 63,
        SystemExtendedHandleInformation = 64,
        SystemLostDelayedWriteInformation = 65,
        SystemBigPoolInformation = 66,
        SystemSessionPoolTagInformation = 67,
        SystemSessionMappedViewInformation = 68,
        SystemHotpatchInformation = 69,
        SystemObjectSecurityMode = 70,
        SystemWatchdogTimerHandler = 71,
        SystemWatchdogTimerInformation = 72,
        SystemLogicalProcessorInformation = 73,
        SystemWow64SharedInformationObsolete = 74,
        SystemRegisterFirmwareTableInformationHandler = 75,
        SystemFirmwareTableInformation = 76,
        SystemModuleInformationEx = 77,
        SystemVerifierTriageInformation = 78,
        SystemSuperfetchInformation = 79,
        SystemMemoryListInformation = 80,
        SystemFileCacheInformationEx = 81,
        SystemThreadPriorityClientIdInformation = 82,
        SystemProcessorIdleCycleTimeInformation = 83,
        SystemVerifierCancellationInformation = 84,
        SystemProcessorPowerInformationEx = 85,
        SystemRefTraceInformation = 86,
        SystemSpecialPoolInformation = 87,
        SystemProcessIdInformation = 88,
        SystemErrorPortInformation = 89,
        SystemBootEnvironmentInformation = 90,
        SystemHypervisorInformation = 91,
        SystemVerifierInformationEx = 92,
        SystemTimeZoneInformation = 93,
        SystemImageFileExecutionOptionsInformation = 94,
        SystemCoverageInformation = 95,
        SystemPrefetchPatchInformation = 96,
        SystemVerifierFaultsInformation = 97,
        SystemSystemPartitionInformation = 98,
        SystemSystemDiskInformation = 99,
        SystemProcessorPerformanceDistribution = 100,
        SystemNumaProximityNodeInformation = 101,
        SystemDynamicTimeZoneInformation = 102,
        SystemCodeIntegrityInformation = 103,
        SystemProcessorMicrocodeUpdateInformation = 104,
        SystemProcessorBrandString = 105,
        SystemVirtualAddressInformation = 106,
        SystemLogicalProcessorAndGroupInformation = 107,
        SystemProcessorCycleTimeInformation = 108,
        SystemStoreInformation = 109,
        SystemRegistryAppendString = 110,
        SystemAitSamplingValue = 111,
        SystemVhdBootInformation = 112,
        SystemCpuQuotaInformation = 113,
        SystemNativeBasicInformation = 114,
        SystemErrorPortTimeouts = 115,
        SystemLowPriorityIoInformation = 116,
        SystemBootEntropyInformation = 117,
        SystemVerifierCountersInformation = 118,
        SystemPagedPoolInformationEx = 119,
        SystemSystemPtesInformationEx = 120,
        SystemNodeDistanceInformation = 121,
        SystemAcpiAuditInformation = 122,
        SystemBasicPerformanceInformation = 123,
        SystemQueryPerformanceCounterInformation = 124,
        SystemSessionBigPoolInformation = 125,
        SystemBootGraphicsInformation = 126,
        SystemScrubPhysicalMemoryInformation = 127,
        SystemBadPageInformation = 128,
        SystemProcessorProfileControlArea = 129,
        SystemCombinePhysicalMemoryInformation = 130,
        SystemEntropyInterruptTimingInformation = 131,
        SystemConsoleInformation = 132,
        SystemPlatformBinaryInformation = 133,
        SystemThrottleNotificationInformation = 134,
        SystemPolicyInformation = 134,
        SystemHypervisorProcessorCountInformation = 135,
        SystemDeviceDataInformation = 136,
        SystemDeviceDataEnumerationInformation = 137,
        SystemMemoryTopologyInformation = 138,
        SystemMemoryChannelInformation = 139,
        SystemBootLogoInformation = 140,
        SystemProcessorPerformanceInformationEx = 141,
        SystemSpare0 = 142,
        SystemSecureBootPolicyInformation = 143,
        SystemPageFileInformationEx = 144,
        SystemSecureBootInformation = 145,
        SystemEntropyInterruptTimingRawInformation = 146,
        SystemPortableWorkspaceEfiLauncherInformation = 147,
        SystemFullProcessInformation = 148,
        SystemKernelDebuggerInformationEx = 149,
        SystemBootMetadataInformation = 150,
        SystemSoftRebootInformation = 151,
        SystemElamCertificateInformation = 152,
        SystemOfflineDumpConfigInformation = 153,
        SystemProcessorFeaturesInformation = 154,
        SystemRegistryReconciliationInformation = 155,
        SystemEdidInformation = 156,
        SystemManufacturingInformation = 157,
        SystemEnergyEstimationConfigInformation = 158,
        SystemHypervisorDetailInformation = 159,
        SystemProcessorCycleStatsInformation = 160,
        SystemVmGenerationCountInformation = 161,
        SystemTrustedPlatformModuleInformation = 162,
        SystemKernelDebuggerFlags = 163,
        SystemCodeIntegrityPolicyInformation = 164,
        SystemIsolatedUserModeInformation = 165,
        SystemHardwareSecurityTestInterfaceResultsInformation = 166,
        SystemSingleModuleInformation = 167,
        SystemAllowedCpuSetsInformation = 168,
        SystemDmaProtectionInformation = 169,
        SystemInterruptCpuSetsInformation = 170,
        SystemSecureBootPolicyFullInformation = 171,
        SystemCodeIntegrityPolicyFullInformation = 172,
        SystemAffinitizedInterruptProcessorInformation = 173,
        SystemRootSiloInformation = 174,
        SystemCpuSetInformation = 175,
        SystemCpuSetTagInformation = 176,
        MaxSystemInfoClass = 177,
    } SYSTEM_INFORMATION_CLASS;
PROCESSINFOCLASS
Code:
    typedef enum _PROCESSINFOCLASS {
        ProcessBasicInformation = 0,
        ProcessQuotaLimits = 1,
        ProcessIoCounters = 2,
        ProcessVmCounters = 3,
        ProcessTimes = 4,
        ProcessBasePriority = 5,
        ProcessRaisePriority = 6,
        ProcessDebugPort = 7,
        ProcessExceptionPort = 8,
        ProcessAccessToken = 9,
        ProcessLdrInformation = 10,
        ProcessLdtSize = 11,
        ProcessDefaultHardErrorMode = 12,
        ProcessIoPortHandlers = 13,
        ProcessPooledUsageAndLimits = 14,
        ProcessWorkingSetWatch = 15,
        ProcessUserModeIOPL = 16,
        ProcessEnableAlignmentFaultFixup = 17,
        ProcessPriorityClass = 18,
        ProcessWx86Information = 19,
        ProcessHandleCount = 20,
        ProcessAffinityMask = 21,
        ProcessPriorityBoost = 22,
        ProcessDeviceMap = 23,
        ProcessSessionInformation = 24,
        ProcessForegroundInformation = 25,
        ProcessWow64Information = 26,
        ProcessImageFileName = 27,
        ProcessLUIDDeviceMapsEnabled = 28,
        ProcessBreakOnTermination = 29,
        ProcessDebugObjectHandle = 30,
        ProcessDebugFlags = 31,
        ProcessHandleTracing = 32,
        ProcessIoPriority = 33,
        ProcessExecuteFlags = 34,
        ProcessTlsInformation = 35,
        ProcessCookie = 36,
        ProcessImageInformation = 37,
        ProcessCycleTime = 38,
        ProcessPagePriority = 39,
        ProcessInstrumentationCallback = 40,
        ProcessThreadStackAllocation = 41,
        ProcessWorkingSetWatchEx = 42,
        ProcessImageFileNameWin32 = 43,
        ProcessImageFileMapping = 44,
        ProcessAffinityUpdateMode = 45,
        ProcessMemoryAllocationMode = 46,
        ProcessGroupInformation = 47,
        ProcessTokenVirtualizationEnabled = 48,
        ProcessConsoleHostProcess = 49,
        ProcessWindowInformation = 50,
        MaxProcessInfoClass    // always last one so no need to add a value manually
    } PROCESSINFOCLASS;
Enum entries may be removed or added depending on the version of Windows you are running. There are a few cases where some of them may not be present past an OS version or on any versions of Windows over than one, and new versions of Windows usually adds new ones. Make sure you understand what you are doing with them before attempting to use them in any software which may be used by other people for compatibility reasons. These enum type definitions are undocumented and do not appear to be officially supported by Microsoft, and the functions also appear to be undocumented - for this reason, using them at all may cause issues if caution is not applied.

I have posted a "tutorial" here which demonstrates how to call NtQuerySystemInformation to enumerate the running processes on the system and extract the Process ID based on the Process Name passed in as a parameter to the function. You can find it here: Tutorial - NtQuerySystemInformation and Process IDs (it makes use of the SYSTEM_INFORMATION_CLASS for SystemProcessInformation which has a class ID of 5).

For the record, when using functions exported by NTDLL (NTDLL.DLL), it will not matter whether you use the Nt* or Zw* function stub. All the Nt*/Zw* function prologues are identical because they are designed to do the exact same thing: move the identifier for the function being called into the EAX register and then perform a system call (however on older versions of Windows there may be other functions involved like KiFastSystemCall, and on 64-bit environments any 32-bit processes will be required to go through emulation (WOW64 - Windows On Windows 64) which will end in the 64-bit NTDLL being used internally).

If you think you are missing an enum value or need one for a new version of Windows, you can try using WinDbg to extract them yourselves. A faster alternate would be trying to search if someone else has already found them (e.g. ReactOS can be useful for finding the class IDs for older versions of Windows).

Thank you for reading. :)
 

Opcode

Level 28
Content Creator
Joined
Aug 17, 2017
Messages
1,733
#3
How can I get them using windbg?
"dt _SYSTEM_INFORMATION_CLASS" does not work
It is undocumented and you'll need to use debugging of kernel-mode I believe. First of all though, make sure you setup the correct symbols for WinDbg...

1. Open up WinDbg.
2. Go to File -> Symbol File Path



3. Set the correct path and URL.
- Make a folder anywhere on your system to hold the symbol files (e.g. *.pdb files).
- Now type srv*FILEPATH*URL
- The URL is http://msdl.microsoft.com/download/symbols

Example.
Code:
srv*C:\winsymbols*http://msdl.microsoft.com/download/symbols


Where C:\winsymbols is the folder I had created to hold the symbols many months ago. You don't have to specify a folder but it is better to do so. Saves internet connection (no need to re-download each time) and allows you to debug properly when you haven't got internet.

I attached to notepad.exe and used the following command.
Code:
dt ntdll!*


I noticed _KAPC_STATE was listed so I used the following comment.

Code:
dt ntdll!_KAPC_STATE
Result: it listed the entries for the structure.



Using the above alone we can create a structure. Below is an example.

Code:
typedef struct _KAPC_STATE {
    LIST_ENTRY ApcListHead[2];
    PKPROCESS Process;
    UCHAR InProcessFlags;
    UCHAR KernelApcInProgress;
    UCHAR SpecialApcInProgress;
    UCHAR KernelApcPending;
    UCHAR UserApcPending;
} KAPC_STATE, *PKAPC_STATE;
Now if we look at the one from the Nirsoft documentation we will see that the one I just made for Windows 10 has entries the Nirsoft one does not have. This tells us that some of the new entries are for modern versions of Windows, and not on an older version like Windows Vista.

Code:
typedef struct _KAPC_STATE
{
    LIST_ENTRY ApcListHead[2];
    PKPROCESS Process;
    UCHAR KernelApcInProgress;
    UCHAR KernelApcPending;
    UCHAR UserApcPending;
} KAPC_STATE, *PKAPC_STATE;
Notice how the one above is lacking InProcessFlags and SpecialApcPending? Maybe Nirsoft just didn't include, or it means those entries were added after Windows Vista (I am not sure, I don't have an environment for Win2k, Windows XP or Windows Vista right now).

If it doesn't get listed then the symbols don't include it or you can't access it from user-mode debugging. In-case you're wondering how I got the correct entries for the structures in the original post, I used ReactOS and a website called geoffchappel. I looked at them to know the correct orders and the types -> manually entered them one by one. Took awhile because of how big they are but I wanted to do it because the ones online from others are not complete (e.g. some people have definitions but they will only have a few entries, I wanted all of them).

ReactOS: drivers/filesystems/udfs/Include/ntddk_ex.h File Reference
SYSTEM_INFORMATION_CLASS

-> setup in Visual Studio manually. :) I did it by hand so I could double check and assign the = correctly so when something is updated the values will maintain right or can easily be changed. Instead of letting the enum auto-decide the value based on the order.

Be aware that the information on both those websites may be outdated, I found new entries thanks to a GitHub post a few months recent which weren't included on either ReactOS or Geoffchappel documentation, but they were related to modern versions of Windows only.
 
Last edited: