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


