Process Information Structure
The Windows kernel exposes detailed information about processes through various data structures. These structures are fundamental for understanding process behavior, resource utilization, and for debugging and performance analysis. The primary structure used to represent process information is often referred to as the Kernel Process Block (KPROCESS) and related structures like the Executive Process Block (EPROCESS).
EPROCESS Structure
The EPROCESS
structure is the most comprehensive representation of a process within the Windows kernel. It contains information relevant to the Executive subsystem, including process management, security, and object management. Key members include:
Pcb
: A pointer to the KPROCESS structure, which contains processor-specific information.UniqueProcessId
: The process identifier (PID).ProcessLock
: A synchronization object for protecting the process object.ExitStatus
: The exit status code of the process.Token
: The process's access token.ThreadListHead
: A linked list of all threads belonging to this process.VadRoot
: The root of the virtual address descriptor tree, managing the process's virtual memory.CommitCharge
: The amount of commit charge consumed by the process.WorkingSetPages
: The number of pages currently in the process's working set.QuotaUsage
: Current resource quotas used by the process.DebugPort
: A pointer to the debugger port if the process is being debugged.SeAuditSession
: Security audit session information.
KPROCESS Structure
The KPROCESS
structure is a part of the EPROCESS
structure and contains processor-dependent information. It is primarily used by the Kernel subsystem.
Header
: The kernel object header.ProfileTable
: Information for profiling.DirectoryTableBase
: The page table base register value.QuantumReset
: Used for time slice management.ThreadListHead
: A linked list of threads.Affinity
: The processor affinity mask.IdealNode
: Used in NUMA systems.
Accessing Process Information
Direct access to kernel structures like EPROCESS
and KPROCESS
is typically done by kernel-mode drivers and the operating system itself. User-mode applications can query process information indirectly using Windows API functions such as:
NtQueryInformationProcess
(and its wrapperZwQueryInformationProcess
in kernel mode): This is the primary function for retrieving various types of process information.EnumProcesses
,GetProcessId
,OpenProcess
,GetProcessMemoryInfo
from the Process and Environment API.
EPROCESS
and KPROCESS
structures can change between Windows versions and even between different builds of the same version. Relying on direct memory inspection of these structures in user mode is highly discouraged and prone to breaking. Always use documented Windows API functions for reliable process information retrieval.
Common Process Information Classes (for NtQueryInformationProcess
)
The NtQueryInformationProcess
function takes a PROCESS_INFORMATION_CLASS
enumeration value to specify which piece of information to retrieve. Some common classes include:
Class Name | Description |
---|---|
ProcessBasicInformation |
Retrieves basic process information like ExitStatus , pebBaseAddress , and AffinityMask . |
ProcessQuotaUsage |
Retrieves current process quota usage. |
ProcessVmCounters |
Retrieves virtual memory counters. |
ProcessHandleCount |
Retrieves the number of open handles for the process. |
ProcessThreadCount |
Retrieves the number of threads in the process. |
ProcessWow64Information |
Indicates if the process is a WOW64 process (running 32-bit on 64-bit Windows). |
ProcessImageFileName |
Retrieves the name of the process image file. |
Example: Retrieving Process Basic Information (Conceptual)
This is a conceptual C++ example demonstrating how to use NtQueryInformationProcess
from user mode to get basic process information.
<code>
#include <windows.h>
#include <winternl.h>
#include <iostream>
// Define the structure for ProcessBasicInformation (may vary slightly by OS version)
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PVOID PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
// Typedef for the NtQueryInformationProcess function pointer
typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESS_INFORMATION_CLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength);
int main() {
HANDLE hProcess = GetCurrentProcess(); // Or OpenProcess for another process
PROCESS_BASIC_INFORMATION pbi;
ULONG returnLength;
// Get the address of NtQueryInformationProcess dynamically
pNtQueryInformationProcess NtQueryInfoProcess =
(pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
if (!NtQueryInfoProcess) {
std::cerr << "Failed to get NtQueryInformationProcess address." << std::endl;
return 1;
}
NTSTATUS status = NtQueryInfoProcess(
hProcess,
ProcessBasicInformation, // Use the enumeration value
&pbi,
sizeof(PROCESS_BASIC_INFORMATION),
&returnLength);
if (NT_SUCCESS(status)) {
std::cout << "Process ID: " << (DWORD)pbi.UniqueProcessId << std::endl;
std::cout << "PEB Base Address: " << pbi.PebBaseAddress << std::endl;
} else {
std::cerr << "NtQueryInformationProcess failed with status: " << status << std::endl;
}
CloseHandle(hProcess);
return 0;
}
</code>
Conclusion
Understanding the process information structures within the Windows kernel is crucial for any systems programmer, debugger, or performance analyst. While direct kernel object manipulation is complex and OS-dependent, the provided Windows APIs offer a stable and documented way to access the essential data that defines a process's state and behavior.