Processes & PEB Structure
Processes & the Process Environment Block (PEB) is crucial to understand thoroughly. There's a lot to it, I'll try to cover most of it here.
Introduction
In short, a process is an instance of an executing program. It consists of various resources such as threads, handles, memory, and security contexts.
A process in Windows includes:
A Unique Process ID (PID)
Virtual Address Space (VAS): Every process is allocated it's own Virtual Address Space. This VAS is compartmentalized into PE sections (code, data, stack).
Executable Code (PE Image): The image of the file stored on disk.
Handle Table: Holds the handles that are opened.
Access Tokens (Security Context): Access tokens encapsulate information about the processes security privileges. Includes the user account and it's access rights.
Threads: Processes run atlest 1 or more threads. Threads enable concurrent execution.
Process Initialization and csrss.exe
Normally, a new process is created with CreateProcess
(or one of it's variants). Here is the general flow:
NtCreateProcess is called.
The target exe file is opened and the .text section is called.
The initial thread and stack are created along with it's security context.
Windows subsystem initialization is performed
A message is sent to the Client/Server Runtime Subsystem (csrss.exe) to notify the creation of a new process.
csrss performs it's own initialization (such as allocating structures for new process)
The initial thread is resumed
Process initialization is performed in the security context of the new process.
The first thread that a process runs is LdrInitializeThunk
. This is the initialization function before execution is transferred to the user-supplied thread entry point.
PEB Structure
BeingDebugged: Is the process in debugging mode.
PEB_LDR_DATA
The PEB_LDR_DATA structure contains informations about the loaded DLL's
InMemoryOrderModuleList: Doubly linked list of LIST_ENTRYs containing pointers to a loaded DLL.
Length: Length of the list.
LIST_ENTRY
Flink: points to the next entry in the list.
Blink: points to the previous entry in the list
IMPORTANT: Flink and Blink don't point to the start of the struct. They point to the InMemoryOrderModuleList member of the struct. To get the start of
LDR_DATA_TABLE_ENTRY
from them, subtract InMemoryOrderModuleList offset(0x10)
. OrCONTAINING_RECORD
macro.Example: (->Flink - 0x10) Full example below.
Access Local PEB (x64)
Getting a pointer to the PEB in C, for every architecture that NT was ported to
Get Local Base Address (NTDLL)
Flink actually returns the address of the end of the structure. Which is why we subtract 0x10 (size of entry) to get to the beginning.
Access Remote PEB (x64)
To access a remote processes PEB structure & get the remote address of entry point we can use the following:
Suspended Processes
Suspended processes can be a nice trick when it comes to EDR since they can't load their hooks into a process that is suspended
Create Suspended Process
Additional
Iterate through LDR_DATA_TABLE_ENTY Linked List
LDR_DATA_TABLE_ENTRY is an important data structure in the PEB. There's some important information here so strap in.
Iterate through linked list:
The
pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
is a common method for advancing in linked lists in C.In this linked list, the pointer to the next node is obtained by derefencing the current node. This is because the nodes embedded within a larger structure (
PLDR_DATA_TABLE_ENTRY
), and the linked list pointers are part of that structure.
To understand more how this works, let's examine the following code:.
The above command derefernces the value stored at the address pointed to by pDte
and then casting the result to a pointer to the PLDR_DATA_TABLE_ENTRY
structure. This is simply how linked lists work. It looks like this:
LDR_DATA_TABLE_ENTRY
This is a node of the doubly linked list that contains loaded DLL information. Look above to enumerate.
This is the documented version of LDR_DATA_TABLE_ENTRY.
InInitializationOrderLinks.Flink:
This is the base address of the DLL.
It isReserved2[0]
in WinAPI. The name doesn't suggest it, but Microsoft likes to confuse people.
Last updated