Handle Tables & Object Manager

Objective:
Understand the role and internals of the Windows Object Manager, the structure and purpose of handle tables, kernel object creation and management, object security, and impersonation techniques. This knowledge is critical for reverse engineering, system analysis, kernel exploitation, and detection of privilege escalation and persistence techniques.


Introduction

Windows internally uses objects to represent resources—files, processes, threads, events, mutexes, semaphores, and more. The Object Manager is a kernel subsystem responsible for creating, managing, securing, and destroying these objects.

Each process maintains a private Handle Table, mapping numeric handles to kernel objects. Accessing these kernel objects securely and efficiently through handles is fundamental for Windows’ stability and security.

handle-tables-object-manager

Windows Object Manager Overview

The Object Manager (ntoskrnl.exe) manages:

  • Creation and deletion of kernel objects.
  • Object namespace management (hierarchical paths).
  • Security via Access Control Lists (ACLs).
  • Reference counting and lifetime management.

Common Kernel Objects

Object TypeDescription
ProcessExecuting program instance
ThreadUnit of execution within a process
FileRepresents open file or I/O device
EventSynchronization primitive
MutexMutual exclusion lock
SemaphoreSynchronization counter
TokenSecurity context (user privileges, groups)

Object Namespace

Kernel objects are structured hierarchically, similar to a file system:

Example paths:

\Device\HarddiskVolume1
\BaseNamedObjects\GlobalEvent

Use tools like WinObj (Sysinternals) to browse the object namespace.


Object Structures and Headers

Every object in kernel mode has a common header (OBJECT_HEADER) with metadata:

typedef struct _OBJECT_HEADER {
 LONG_PTR PointerCount; // Number of active pointers
 LONG_PTR HandleCount; // Active handle count
 PVOID ObjectType; // Pointer to OBJECT_TYPE structure
 PVOID SecurityDescriptor; // ACL for the object
 UNICODE_STRING Name; // Object name
 // ...
} OBJECT_HEADER;

This header precedes the actual object in memory.


Handle Tables

A Handle is an integer value referencing an object entry in a process-specific handle table.

  • Each process has its own handle table.
  • Maps handle values (integers) to pointers to kernel-mode objects.

Handle Table Entry (HANDLE_TABLE_ENTRY):

typedef struct _HANDLE_TABLE_ENTRY {
 union {
 PVOID Object; // Pointer to actual object
 ULONG_PTR Attributes;
 };
 ACCESS_MASK GrantedAccess; // Permissions for the handle
} HANDLE_TABLE_ENTRY;

Handle Tables allow controlled, indirect access to kernel objects.


Working with Handles (APIs)

Common APIs for working with handles:

API FunctionPurpose
OpenProcessGets a handle to an existing process
OpenThreadGets a handle to a thread
CreateFileOpens file/device handle
DuplicateHandleDuplicates existing handles
CloseHandleReleases the handle

Example (C++):

HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
CloseHandle(hProc);

NtQuerySystemInformation

A native NT API function that provides extensive system information.

NTSTATUS NtQuerySystemInformation(
 SYSTEM_INFORMATION_CLASS SystemInformationClass,
 PVOID SystemInformation,
 ULONG SystemInformationLength,
 PULONG ReturnLength
);

Common use:

  • Query process lists (SystemProcessInformation)
  • Handle information (SystemHandleInformation)

Example: Enumerating Handles

NtQuerySystemInformation(SystemHandleInformation, buffer, bufferSize, &returnedSize);

Enumerating Handles via PowerShell:

Get-Process | ForEach-Object {
 $_ | Select-Object -ExpandProperty Handles
}

Object Security & ACLs

Kernel objects include a Security Descriptor (SD):

  • Owner SID
  • Group SID
  • DACL (Discretionary ACL): who has access
  • SACL (System ACL): audit events on access

Example: Changing ACL via WinAPI:

SetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);

Audit ACLs with:

Get-Acl '\\.\pipe\mypipe'

Object Reference Counting

Objects have two counters:

  • Handle Count: Number of handles referencing it.
  • Pointer Count: Direct kernel pointers referencing it.

When both reach zero, the object is destroyed automatically.


Kernel Objects and Impersonation

Windows supports Security Impersonation, allowing threads to execute with another user’s security context (token).

Impersonation Levels:

  • Anonymous: No identification.
  • Identification: Identity check only.
  • Impersonation: Access local resources as the impersonated user.
  • Delegation: Access remote resources as impersonated user.

Impersonation APIs:

  • ImpersonateLoggedOnUser
  • ImpersonateNamedPipeClient
  • SetThreadToken

Example Impersonation:

LogonUser(user, domain, pass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);
ImpersonateLoggedOnUser(hToken);
// Thread now has user privileges

Attackers exploit impersonation by stealing tokens from privileged processes (Token stealing via handle duplication).


Handle Duplication for Privilege Escalation

Attackers commonly duplicate high-privilege handles:

Example exploitation flow:

  1. Open a privileged process handle (OpenProcess).
  2. Duplicate its token (DuplicateHandle).
  3. Assign the duplicated token to the current process (SetThreadToken or SetTokenInformation).

Detection via Sysmon (Event ID 10 – ProcessAccess).


Common Attacker Techniques

TechniqueDescription
Handle HijackingDuplicate handles to privileged processes
Object ACL AbuseModify ACLs of kernel objects
Named Object HijackingHijack named objects (events/mutexes)
Kernel Object LeaksLeaking kernel object addresses

Defensive Strategies & Detection

Sysmon (Process Access Monitoring):

  • Track unusual handle duplications:
Sysmon Event ID 10: PROCESS_ACCESS

Handle & Object Auditing:

  • Use Process Hacker or Process Monitor.
  • Enumerate handles periodically for anomalies.

Object ACL Hardening:

  • Reduce unnecessary write permissions.
  • Regularly audit ACLs on critical named objects.

Tools for Handle & Object Analysis

ToolDescription
WinObjBrowse kernel object namespace (Sysinternals)
Process HackerReal-time handle/object analysis
handle.exeSysinternals command-line handle viewer
Process MonitorFile, registry, and handle monitoring
VolatilityForensic memory object & handle analysis

Example handle enumeration (handle.exe):

handle.exe -p 1234

Summary

  • Windows Object Manager controls lifecycle, security, and naming of kernel objects.
  • Each process has a handle table, mapping handles to kernel objects securely.
  • NtQuerySystemInformation provides detailed handle and object insights.
  • Impersonation techniques allow threads to execute with alternative user privileges.
  • Attackers leverage handle duplication and impersonation for privilege escalation.
  • Defensive controls include Sysmon monitoring, ACL auditing, and continuous handle enumeration.


Related Tutorials

References

Memory Management Internals

Objective:
Understand the internal architecture and functionality of Windows memory management, including virtual memory, physical memory mappings, distinctions between stack and heap allocations, and memory management concepts such as working sets, committed versus reserved memory. This knowledge is essential for reverse engineering, exploit development, malware analysis, and system performance optimization.


Introduction

Windows uses advanced virtual memory management to efficiently handle application and system memory. Understanding how Windows manages memory—from virtual addresses to physical memory mappings—enables better performance tuning, troubleshooting memory leaks, analyzing malware behaviors, and performing memory-based exploit development.

memory-management

Memory Management Overview

Windows memory management involves:

  • Virtual Address Space (VAS)
  • Physical Memory (RAM)
  • Paging and Page Tables
  • Heap and Stack allocations
  • Working Sets
  • Commit and Reserve

Virtual Memory Layout

Each Windows process has a unique virtual address space, typically:

  • User-mode space: Lower addresses (e.g., 0x00000000–0x7FFFFFFF on 32-bit; 0x0000000000000000–0x00007FFFFFFF on 64-bit)
  • Kernel-mode space: Higher addresses (e.g., 0x80000000–0xFFFFFFFF on 32-bit; 0xFFFF800000000000–0xFFFFFFFFFFFFFFFF on 64-bit)

x64 Windows Layout:

+------------------------------+ 0xFFFFFFFFFFFFFFFF
| Kernel-mode space |
+------------------------------+ 0xFFFF800000000000
| Unused |
+------------------------------+ 0x00007FFFFFFFFFFF
| User-mode space |
+------------------------------+ 0x0000000000000000

Stack vs Heap

Applications allocate memory using two main methods: Stack and Heap.

Stack

  • LIFO (Last In, First Out) data structure.
  • Used for function calls, local variables, return addresses.
  • Fixed-size, determined at thread creation (default ~1MB/thread).
  • Stack overflow occurs when usage exceeds allocated stack space.

Example stack allocation (automatic):

int foo() {
 int a = 10; // Stack allocated
 return a;
}

Heap

  • Flexible, dynamically-sized region.
  • Managed explicitly by malloc(), HeapAlloc(), new, VirtualAlloc().
  • Fragmentation can occur over time.

Example heap allocation (manual):

int* arr = (int*)malloc(10 * sizeof(int));

Working Sets

The Working Set is a set of physical memory pages currently used by a process.

  • Windows tracks per-process working sets.
  • Working sets dynamically change based on usage.
  • Windows trims working sets under memory pressure.

Use Task Manager or Process Explorer to examine Working Sets:

  • Private Working Set: memory exclusive to a process.
  • Shareable Working Set: memory shared between processes.

Inspect via PowerShell:

Get-Process | Select Name, WorkingSet, PagedMemorySize, PrivateMemorySize

Commit vs Reserve

When an application allocates virtual memory, Windows allows two different states:

Reserved Memory

  • Reservation of virtual address range without allocating physical memory or paging file.
  • Not usable until committed.
  • Used to ensure contiguous memory availability for future use.

Committed Memory

  • Backed by physical RAM or paging file.
  • Usable immediately by applications.
  • Counts against system commit limit.

Example (C++):

// Reserve virtual memory
LPVOID reserved = VirtualAlloc(NULL, 4096, MEM_RESERVE, PAGE_READWRITE);

// Commit reserved memory
LPVOID committed = VirtualAlloc(reserved, 4096, MEM_COMMIT, PAGE_READWRITE);

Paging and Page Tables

Windows uses paging to map virtual addresses to physical addresses.

  • Page size typically 4KB.
  • Uses Multi-level page tables (x64: PML4 → PDPT → PD → PT).
  • On access violation (page fault), Windows loads the requested page from disk if available (paging).

Example of Page Fault Handling:

  • A program references an address not in RAM.
  • CPU raises a page fault.
  • Windows kernel fetches the page from disk or allocates memory.
  • Instruction is retried.

Memory Protection & Permissions

Each page has memory protection attributes:

  • PAGE_EXECUTE_READWRITE: executable, readable, writable (often abused by malware)
  • PAGE_READONLY: read-only
  • PAGE_NOACCESS: no access permitted

Example memory permission change:

DWORD oldProtect;
VirtualProtect(address, size, PAGE_EXECUTE_READWRITE, &oldProtect);

Heap Internals

Windows provides several heaps per process:

  • Default Process Heap: created automatically at startup (GetProcessHeap()).
  • Private Heaps: created explicitly (HeapCreate()).

Heap allocations are tracked via internal heap structures:

  • Heap headers: track size, flags.
  • Heap fragmentation: caused by frequent allocations/deallocations.

Tools like WinDbg or !heap extension allow analysis of heap internals:

!heap -s ; Summary of heaps
!heap -h 0xAddr ; Analyze specific heap

Stack Internals

  • Each thread gets its own stack.
  • Stack grows downward (high → low addresses).
  • Stack Pointer (ESP/RSP) tracks current stack top.

Typical stack frame (x64):

+------------------------+
| Local Variables |
+------------------------+
| Saved Registers |
+------------------------+
| Return Address |
+------------------------+
| Function Parameters |
+------------------------+

Memory Management APIs & Tools

Common Memory APIs:

FunctionPurpose
VirtualAllocReserve/commit virtual pages
VirtualFreeRelease/decommit memory
HeapAllocAllocate heap memory
HeapFreeFree heap memory
RtlAllocateHeapNT heap allocation API

Memory Analysis Tools:

  • VMMap: Detailed virtual memory analysis.
  • RAMMap: Physical memory usage inspection.
  • Process Hacker: Real-time memory allocation inspection.
  • WinDbg: In-depth debugging and analysis.

Malware and Exploit Use Cases

TechniqueAbuse Scenario
Heap SprayPreparing predictable memory layout for exploitation
Stack OverflowOverwriting return addresses for RCE
ROP GadgetsExecuting chained snippets of legitimate code in stack
Code InjectionAllocating executable memory (PAGE_EXECUTE_READWRITE)
Shellcode LoadingUsing VirtualAlloc/VirtualProtect to execute payloads

Memory Forensics & Detection

  • Use Volatility Framework for memory forensics:
volatility -f memory.dmp pslist
volatility -f memory.dmp malfind
  • Monitor abnormal allocations (PAGE_EXECUTE_READWRITE pages) with Sysmon:
Sysmon Event ID 10 (ProcessAccess)

Summary

  • Windows manages memory through complex virtual-to-physical mapping.
  • Stack is used for automatic, function-local allocations.
  • Heap handles dynamic memory, manually managed by developers.
  • Working Sets optimize performance and memory efficiency.
  • Commit and Reserve control memory usage strategy.
  • Understanding these internals enables effective memory forensics, exploit development, and performance tuning.


Related Tutorials

References

Threads and the TEB (Thread Environment Block)

Objective: Understand the internal workings of threads on Windows, the lifecycle of a thread from creation to termination, the critical role of the Thread Environment Block (TEB), and fundamentals of thread injection techniques. This foundational knowledge is crucial for system developers, reverse engineers, malware analysts, and red teamers.


Introduction

A thread is the smallest execution unit within a process on Windows, scheduled independently by the OS kernel. Every process contains at least one thread, but often many more. Each thread maintains its own state, CPU registers, stack, and local storage.

Central to each thread’s operation is the Thread Environment Block (TEB), a user-mode structure containing thread-specific data critical for thread execution, error handling, exception handling, and system call interfacing.

TEB

Thread Lifecycle

A typical thread undergoes these stages:

Creation → Scheduling → Execution → Waiting/Blocking → Termination

Detailed Steps:

  • Creation:
    Initiated via APIs like:
    • CreateThread()
    • RtlCreateUserThread()
    • NtCreateThreadEx()
  • Scheduling (Kernel):
    Windows uses priority-based preemptive scheduling:
    • Quantum: Thread time-slice allocated for execution.
    • Threads can have different priority levels (0 to 31).
  • Execution (User-Mode):
    Execution starts at thread entry function (LPTHREAD_START_ROUTINE).
  • Waiting/Blocking:
    Threads often enter waiting states (WaitForSingleObject(), Sleep(), I/O waits).
  • Termination:
    Ends via:
    • Returning from thread function
    • Calling ExitThread()
    • Termination by another thread (TerminateThread() – unsafe)

Thread Environment Block (TEB)

Each thread has a unique TEB, accessed quickly via the FS:[0x18] register on x86 or GS:[0x30] on x64.

Key TEB fields:

typedef struct _TEB {
 NT_TIB NtTib;
 PVOID EnvironmentPointer;
 CLIENT_ID ClientId; // Unique Thread ID and Process ID
 PVOID ActiveRpcHandle;
 PVOID ThreadLocalStoragePointer;
 PPEB ProcessEnvironmentBlock; // Pointer to the PEB
 ULONG LastErrorValue;
 ULONG CountOfOwnedCriticalSections;
 PVOID Win32ThreadInfo;
 ULONG CurrentLocale;
 ULONG FpSoftwareStatusRegister;
 // ... (more fields)
} TEB;

Notable Fields Explained:

  • ClientId: Contains the thread’s TID and owning PID.
  • ProcessEnvironmentBlock (PEB): Points to the process-wide PEB structure.
  • ThreadLocalStoragePointer: Points to thread-local storage (TLS).
  • LastErrorValue: Stores the last error value (GetLastError()).
  • NtTib: Contains:
    • Stack Base (StackBase)
    • Stack Limit (StackLimit)
    • Exception handler list

Accessing the TEB (x64):

mov rax, gs:[0x30] ; RAX now contains TEB pointer

Thread Creation APIs (Detailed)

1. CreateThread()

Commonly used high-level API:

HANDLE CreateThread(
 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 SIZE_T dwStackSize,
 LPTHREAD_START_ROUTINE lpStartAddress,
 LPVOID lpParameter,
 DWORD dwCreationFlags,
 LPDWORD lpThreadId
);

2. NtCreateThreadEx() (Native)

Lower-level, flexible NTAPI:

NTSTATUS NtCreateThreadEx(
 PHANDLE ThreadHandle,
 ACCESS_MASK DesiredAccess,
 POBJECT_ATTRIBUTES ObjectAttributes,
 HANDLE ProcessHandle,
 PVOID StartRoutine,
 PVOID Argument,
 ULONG CreateFlags,
 SIZE_T ZeroBits,
 SIZE_T StackSize,
 SIZE_T MaximumStackSize,
 PVOID AttributeList
);
  • Powerful for cross-process thread injection.

Thread Injection Basics

Thread injection is a fundamental technique in malware development and red teaming, allowing execution of code in a remote process.

Thread Injection Workflow:

  1. Obtain Handle:
    OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  2. Allocate Memory:
    VirtualAllocEx(hProc, ...)
  3. Write Payload:
    WriteProcessMemory(hProc, remoteMemory, ...)
  4. Create Remote Thread:
    CreateRemoteThread(hProc, ..., remoteMemory, ...)

Simplified Example (Remote Thread Injection):

// Open handle to target process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

// Allocate memory
LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, payloadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Write payload (shellcode or DLL loader)
WriteProcessMemory(hProcess, remoteMemory, payload, payloadSize, NULL);

// Start remote thread execution
CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)remoteMemory, NULL, 0, NULL);

Common Thread Injection Techniques

TechniqueDescription
CreateRemoteThreadDirect injection of threads into another process
NtCreateThreadExMore advanced version of CreateRemoteThread
QueueUserAPCInjecting asynchronous procedure calls
SetThreadContextHijacking an existing thread’s execution context

Detection and Analysis of Thread Injection

Indicators:

  • Suspicious CreateRemoteThread() calls targeting unexpected processes
  • Memory allocated (VirtualAllocEx) with execute permissions (PAGE_EXECUTE_READWRITE)
  • Threads created by processes other than expected parent processes

Tools for Detection:

  • Sysmon (Event ID 8: CreateRemoteThread)
  • Process Hacker, Process Monitor
  • API hooking (EDR solutions)
  • Memory scanners (Volatility, Rekall)

Thread Hijacking via TEB Manipulation (Advanced)

Malware can directly manipulate the TEB to hijack threads:

  • Overwrite TEB’s stack pointers or exception handlers
  • Intercept thread execution flow

Example (x64 Assembly):

mov rax, gs:[0x30] ; TEB base
mov [rax+0x8], myStackBase ; overwrite StackBase
mov [rax+0x10], myStackLimit ; overwrite StackLimit

This is advanced and dangerous but illustrates TEB exploitation potential.


Forensics and Incident Response Tips

  • Collect thread information during IR investigations:
Get-Process -Id $PID | Select -Expand Threads
  • Dump TEB structures and thread contexts with WinDbg or volatility.
  • Watch for abnormal thread creations in unexpected processes or sudden thread terminations.

Summary

  • Threads are fundamental units of execution managed by Windows.
  • Each thread maintains critical data in the TEB structure.
  • Threads can be created, injected, and manipulated by advanced APIs.
  • Injection techniques are commonly abused by malware and red teams.
  • Detection relies on system-level monitoring (Sysmon, API hooks).


Related Tutorials

References

Windows Process Creation Internals & PEB

Objective: Deeply understand how Windows creates new processes, detailing the internal workings of the CreateProcess API, kernel object management, memory mapping, and the structure and role of the Process Environment Block (PEB). This is essential knowledge for analyzing and understanding malware behavior, reverse engineering, and advanced debugging.


Introduction

Process creation on Windows is a sophisticated, multi-step procedure involving extensive kernel and user-mode coordination. At the center of this operation is the CreateProcess() API, which initializes process structures, allocates memory, maps executables, and prepares environment variables.

Each Windows process also maintains a Process Environment Block (PEB), a crucial data structure that contains runtime information about the loaded modules, command-line arguments, and more. The PEB is frequently leveraged by attackers and defenders for various advanced techniques.

Windows-Process-Creation

High-Level CreateProcess Flow

The general steps when calling CreateProcess():

  1. User-mode API Call:
    Application invokes kernel32!CreateProcessW or similar.
  2. Kernel Transition (ntdll):
    CreateProcessW invokes ntdll!NtCreateUserProcess.
  3. Kernel Mode Initialization (ntoskrnl):
  4. PE File Loading:
    • PE loader maps executable image sections.
    • Resolves imports and relocations.
    • Sets initial execution context (thread, stack, registers).
  5. Subsystem Notification (CSRSS):
    • Subsystem server creates structures for console/GUI.
  6. Initial Thread Execution:
    • Execution begins at the AddressOfEntryPoint.

Detailed Step-by-Step Flow

Step 1: User-mode API Invocation

When an application wants to start a new process, it uses:

BOOL CreateProcessW(
 LPCWSTR lpApplicationName,
 LPWSTR lpCommandLine,
 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 BOOL bInheritHandles,
 DWORD dwCreationFlags,
 LPVOID lpEnvironment,
 LPCWSTR lpCurrentDirectory,
 LPSTARTUPINFO lpStartupInfo,
 LPPROCESS_INFORMATION lpProcessInformation
);

This call eventually resolves down to an NTDLL syscall:

NtCreateUserProcess(&ProcessHandle, &ThreadHandle, ..., &ProcessParameters, ...);

Step 2: Kernel-side Initialization

Kernel (ntoskrnl) creates key kernel structures:

  • EPROCESS: Process kernel object
  • ETHREAD: Initial thread kernel object
  • VAD Tree: Virtual Address Descriptors for memory management
  • Initializes security tokens and handles

Step 3: PE Image Loading

Kernel PE loader:

  • Maps PE executable sections (.text, .data, etc.) into memory.
  • Handles relocations and import resolutions (IAT resolution).
  • Initializes the stack, heap, and default libraries (ntdll.dll).

Step 4: User-mode initialization (ntdll)

Upon kernel returning control, ntdll.dll runs user-mode initializations:

Step 5: Subsystem Initialization (CSRSS)

  • Windows subsystem (csrss.exe) notified to handle GUI or console session management.

Step 6: Main Thread Execution

  • Execution control transferred to the PE file’s AddressOfEntryPoint.

Process Environment Block (PEB)

The PEB is a crucial process structure located in user mode memory (fs:[0x30] on 32-bit, gs:[0x60] on 64-bit Windows).

typedef struct _PEB {
 BYTE Reserved1[2];
 BYTE BeingDebugged;
 BYTE Reserved2[1];
 PVOID Reserved3[2];
 PPEB_LDR_DATA Ldr; // Loaded modules
 PRTL_USER_PROCESS_PARAMETERS ProcessParameters; // Command-line, env
 BYTE Reserved4[104];
 PVOID Reserved5[52];
 PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
 BYTE Reserved6[128];
 ULONG SessionId;
} PEB, *PPEB;

Key Fields:

  • BeingDebugged: Indicates if a debugger is attached.
  • Ldr: Contains loaded module information (PEB_LDR_DATA).
  • ProcessParameters: Command line, environment variables, startup directory, window settings.

PEB_LDR_DATA Structure

This structure points to the loaded modules (DLLs) in the process:

typedef struct _PEB_LDR_DATA {
 ULONG Length;
 BYTE Initialized;
 PVOID SsHandle;
 LIST_ENTRY InLoadOrderModuleList;
 LIST_ENTRY InMemoryOrderModuleList;
 LIST_ENTRY InInitializationOrderModuleList;
 PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

These linked lists (InLoadOrderModuleList, etc.) contain information about every DLL mapped into the process memory, crucial for module enumeration.


RTL_USER_PROCESS_PARAMETERS Structure

Contains the runtime parameters of the process:

typedef struct _RTL_USER_PROCESS_PARAMETERS {
 ULONG MaximumLength;
 ULONG Length;
 ULONG Flags;
 ULONG DebugFlags;
 HANDLE ConsoleHandle;
 ULONG ConsoleFlags;
 HANDLE StandardInput;
 HANDLE StandardOutput;
 HANDLE StandardError;
 UNICODE_STRING CurrentDirectoryPath;
 HANDLE CurrentDirectoryHandle;
 UNICODE_STRING DllPath;
 UNICODE_STRING ImagePathName; // Path to the executable
 UNICODE_STRING CommandLine; // Process arguments
 PVOID Environment; // Environment block
 ULONG StartingX;
 ULONG StartingY;
 ULONG CountX;
 ULONG CountY;
 ULONG CountCharsX;
 ULONG CountCharsY;
 ULONG FillAttribute;
 ULONG WindowFlags;
 ULONG ShowWindowFlags;
 UNICODE_STRING WindowTitle;
 UNICODE_STRING DesktopInfo;
 UNICODE_STRING ShellInfo;
 UNICODE_STRING RuntimeData;
 RTL_DRIVE_LETTER_CURDIR CurrentDirectories[32];
 ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

Common Malware & Defense Uses of PEB

Malware Uses:

  • Anti-debugging: Check BeingDebugged flag.
  • Module hiding: Manipulate PEB_LDR_DATA to hide loaded DLLs from tools like Process Explorer or debuggers.
  • Process injection: Read remote process PEB to locate modules and perform injection.

Defense Uses:

  • Forensics: Analyzing PEB structures to detect hidden modules or unusual command-line arguments.
  • Behavioral detection: Monitoring PEB accesses can indicate stealthy operations (like hiding loaded modules).

Practical Inspection of PEB

WinDbg Commands:

  • Inspect PEB:
!peb
  • View loaded modules:
lm
  • Dump PEB structure directly:
dt _PEB @$peb

Summary

  • Process creation (CreateProcess) is complex, involving kernel and user-mode coordination.
  • Key kernel objects (EPROCESS, ETHREAD) manage process lifecycle and resources.
  • The PEB contains vital runtime details and is heavily utilized by both malware and security tools.
  • Deep understanding aids in reverse engineering, malware analysis, and debugging.


Related Tutorials

References