Inside Windows NT System Data by Sven B. Schreiber Example 1: NTSTATUS NTAPI NtQuerySystemInformation (SYSTEMINFOCLASS sic, PVOID pData, DWORD dSize, PDWORD pdSize); NTSTATUS NTAPI NtSetSystemInformation (SYSTEMINFOCLASS sic, PVOID pData, DWORD dSize); Example 2: NtQuerySystemInformation (18) --> 64 bytes at 0x007B0020 Offset| 00 01 02 03 04 05 06 07 : 08 09 0A 0B 0C 0D 0E 0F | 01234567 : 89ABCDEF ------|-------------------------:-------------------------|----------:--------- 00000 | 00 00 00 00 00 8B 00 00 : 66 0B 00 00 66 0B 00 00 | ....... : f...f... 00010 | 26 00 28 00 38=00=7B=00 : 5C 00 3F 00 3F 00 5C 00 | &.(.8.{. : \.?.?.\. 00020 | 44 00 3A 00 5C 00 70 00 : 61 00 67 00 65 00 66 00 | D.:.\.p. : a.g.e.f. 00030 | 69 00 6C 00 65 00 2E 00 : 73 00 79 00 73 00 00 00 | i.l.e... : s.y.s... Example 3: NtQuerySystemInformation (18) --> 64 bytes Offset| 00 01 02 03 04 05 06 07 : 08 09 0A 0B 0C 0D 0E 0F | 01234567 : 89ABCDEF ------|-------------------------:-------------------------|----------:--------- 00000 | 00 00 00 00 00 8B 00 00 : 66 0B 00 00 66 0B 00 00 | ....... : f...f... 00010 | 26 00 28 00 18=00=00=00 : 5C 00 3F 00 3F 00 5C 00 | &.(..... : \.?.?.\. 00020 | 44 00 3A 00 5C 00 70 00 : 61 00 67 00 65 00 66 00 | D.:.\.p. : a.g.e.f. 00030 | 69 00 6C 00 65 00 2E 00 : 73 00 79 00 73 00 00 00 | i.l.e... : s.y.s... Example 4: NtQuerySystemInformation: 77f67d2c b87c000000 mov eax,0x7c 77f67d31 8d542404 lea edx,[esp+0x4] 77f67d35 cd2e int 2e 77f67d37 c21000 ret 0x10 NtSetSystemInformation: 77f68034 b8ae000000 mov eax,0xae 77f68039 8d542404 lea edx,[esp+0x4] 77f6803d cd2e int 2e 77f6803f c20c00 ret 0xc Listing One NTSTATUS WINAPI QuerySystemInformation (SYSTEMINFOCLASS sic, PPVOID ppData, PDWORD pdData) { PVOID pData; DWORD dData, n; NTSTATUS ns = STATUS_INVALID_PARAMETER; dData = 0; if (ppData != NULL) { n = 0; while ((pData = LocalAlloc (LMEM_FIXED, dData += 0x10000)) != NULL) { ns = NtQuerySystemInformation (sic, pData, dData, &n); if (ns != STATUS_SUCCESS) n = 0; if (ns != STATUS_INFO_LENGTH_MISMATCH) break; LocalFree (pData); } dData = n; if (pData != NULL) { if (ns != STATUS_SUCCESS) { LocalFree (pData); pData = NULL; dData = 0; } } else { ns = STATUS_NO_MEMORY; } *ppData = pData; } if (pdData != NULL) *pdData = dData; return ns; } Listing Two // 05: SystemProcessInformation // see ExpGetProcessInformation() // see also ExpCopyProcessInfo(), ExpCopyThreadInfo() typedef struct _SYSTEM_THREAD { QWORD qKernelTime; // 100 nsec units QWORD qUserTime; // 100 nsec units QWORD qCreateTime; // relative to 01-01-1601 DWORD d18; PVOID pStartAddress; CLIENT_ID Cid; // process/thread ids DWORD dPriority; DWORD dBasePriority; DWORD dContextSwitches; DWORD dThreadState; // 2=running, 5=waiting KWAIT_REASON WaitReason; DWORD dReserved01; } SYSTEM_THREAD; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - typedef struct _SYSTEM_PROCESS_INFORMATION { DWORD dNext; // relative offset DWORD dThreadCount; DWORD dReserved01; DWORD dReserved02; DWORD dReserved03; DWORD dReserved04; DWORD dReserved05; DWORD dReserved06; QWORD qCreateTime; // relative to 01-01-1601 QWORD qUserTime; // 100 nsec units QWORD qKernelTime; // 100 nsec units UNICODE_STRING usName; KPRIORITY BasePriority; DWORD dUniqueProcessId; DWORD dInheritedFromUniqueProcessId; DWORD dHandleCount; DWORD dReserved07; DWORD dReserved08; VM_COUNTERS VmCounters; DWORD dCommitCharge; // bytes SYSTEM_THREAD ast []; } SYSTEM_PROCESS_INFORMATION; Listing Three void WINAPI DisplayProcesses (void) { NTL_TABLE nt; PSYSTEM_PROCESS_INFORMATION pspi; TIME_FIELDS tf; DWORD i; if (NtlTableProcess (&nt) == STATUS_SUCCESS) { printf (T("PID Org BP Th Hdls CommChrg WSetSize ") T("PFCount Start date and time Name\r\n")); pspi = NtlTableFirst (&nt); for (i = 0; i < nt.dCount; i++) { NtlTimeUnpack (&pspi->qCreateTime, &tf); printf (T("\r\n%3lu %3lu %2lu %2lu %4lu %8lu %8lu ") T("%7lu %02u-%02u-%04u %02u:%02u:%02u ") T("\"%ls\""), pspi->dUniqueProcessId, pspi->dInheritedFromUniqueProcessId, pspi->BasePriority, pspi->dThreadCount, pspi->dHandleCount, pspi->dCommitCharge, pspi->VmCounters.WorkingSetSize, pspi->VmCounters.PageFaultCount, tf.Month, tf.Day, tf.Year, tf.Hour, tf.Minute, tf.Second, (pspi->usName.Buffer != NULL ? pspi->usName.Buffer : L"Idle")); pspi = NtlTableNext (&nt, pspi); } NtlTableUnload (&nt); } return; } Listing Four // 11: SystemModuleInformation // see ExpQueryModuleInformation typedef struct _SYSTEM_MODULE { DWORD dReserved01; DWORD d04; PVOID pAddress; DWORD dSize; // bytes DWORD dFlags; WORD wId; // zero based WORD wRank; // 0 if not assigned WORD w18; WORD wNameOffset; BYTE abName [MAXIMUM_FILENAME_LENGTH]; } SYSTEM_MODULE; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - typedef struct _SYSTEM_MODULE_INFORMATION { DWORD dCount; SYSTEM_MODULE asm []; } SYSTEM_MODULE_INFORMATION; Listing Five // 16: SystemHandleInformation // see ExpGetHandleInformation () typedef struct _SYSTEM_HANDLE { DWORD dIdProcess; BYTE bObjectType; // OB_TYPE_* BYTE bFlags; // bits 0..2 HANDLE_FLAG_* WORD wValue; // multiple of 4 POBJECT pObject; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE; Listing Six // 18: SystemPageFileInformation // see MmGetPageFileInformation() typedef struct _SYSTEM_PAGE_FILE_INFORMATION { DWORD dNext; // relative offset DWORD dTotal; // pages DWORD dInUse; // pages DWORD dPeak; // pages UNICODE_STRING usName; } SYSTEM_PAGE_FILE_INFORMATION; Listing Seven // 26: SystemLoadDriver (set mode only) // see MmLoadSystemImage() // user mode: STATUS_PRIVILEGE_NOT_HELD returned typedef struct _SYSTEM_LOAD_DRIVER { UNICODE_STRING usImageFile; // input PVOID pBaseAddress; // output HANDLE hSystemImage; // output PVOID pEntryPoint; // output PVOID pDirectoryEntry; // output } SYSTEM_LOAD_DRIVER; // 27: SystemUnloadDriver (set mode only) // see MmUnloadSystemImage() // user mode: STATUS_PRIVILEGE_NOT_HELD returned typedef struct _SYSTEM_UNLOAD_DRIVER { HANDLE hSystemImage; // received via SystemLoadDriver } SYSTEM_UNLOAD_DRIVER; // 38: SystemAddDriver (set mode only) // see MmLoadSystemImage(), MmUnloadSystemImage() // user mode: SeLoadDriverPrivilege required typedef struct _SYSTEM_ADD_DRIVER { UNICODE_STRING usImageFile; } SYSTEM_ADD_DRIVER; 5