First of all I do apologize for any mistake that I might made here. I'm always open to opinions and tips. I hope this can be useful to somebody.
In this post I will try to introduce you to the concept of PEB (Process Environment Block) that is a structure in the Windows's processes containing very important information, it's important to know it better. But before to get into it I will try to introduce you to some basic concepts like, what is Process, Thread and Jobs. We need to know the difference, because they have different structures.
Like I always said, I will keep this post simple and objective. In the end of the post I will leave good references so you can do your own in-depth researches. If you really want to know the Windows you need to get the Windows Internals book it is a must to know more this operating system.
Processes
The concept of process and programs are important to understand. A process is not a program, programs are sequences of instructions and processes are containers where the programs are included along with other properties and resources. So in order to run a Window's program a container is needed, where it can run freely with everything it needs is already within. Windows certifies that.
A Windows process comprehends basically:
- Private Virtual Address
- A private virtual space in memory to allocate everything the program may need to run.
- Processes can't access others processes's virtual memory space if there is nothing allowing it.
- Program
- The program is the part of the process that has instructions to the processor execute.
- List of Handles
- Handles are pointers to resources allocated in memory utilized by the program like Synchronization objects (Basically are shared objects between threads), opened files and so on.
- Security Information
- All security information about the process like, user, group of user, privileges in the system, User Account Control (UAC), session and so on.
- Process ID
- Unique identifier of the process.
- Threads
- At least one thread will be running for any given process.
It's important to say that CreateProcess is an API of Windows, but it is a high-level one so to speak. For example we have default processes that are created in the beginning of boot process of Windows, like Smss.exe. Smss (Session manager) isn't created by CreateProcess, instead it is created by NtCreateUserProcess (Ntdll) since it is created directly by the Kernel.
There is a difference between native processes and normal proceses that are created after the Windows boot initialization. These native processes like Smss.exe, Csrss.exe and so on cannot be created as a common process, the CreateProcessInternalW will reject native images. There are some functions used to create a process, but all of them will end up calling CreateProcessInternalW that is the last documented function called in the process creation no matter which one was called first.
All processes created in the system have a structure called EPROCESS (Executive Process) and is maintained in the system address space (memory space reserved for the Windows system). And as we will speak later in this post also maintains a structure in the user address space called PEB (Process Environment Block). So just have in mind that Windows maintain a structure for everything that it creates. In these structures always have a reference in memory for each information it keeps. So when the "process" is executing in user-mode (user address space) it uses the PEB as a reference to access the objects allocated in memory. When the execution is in kernel-mode (kernel address space) and needs to access some information about processes it uses the EPROCESS. However even being the main representations of processes's structures in each side of the operating system (kernel-mode and user-mode) there are more structures created by another processes, Windows Internals cover this thoroughly.
So as mentioned before the process isn't the program itself, thus when a process is created a thread is created with it to execute the main program function. It's important to know this difference, thread execute the program and is the thread that have all CPU context to execute.
Threads
- The Processor Context
- State of CPU registers, the information of the program state is contained in the thread context.
- Stack information
- One stack to the kernel-mode and user-mode.
- Thread ID
- Unique identifier of the thread.
Thread is a program that can run in user-mode and kernel-mode it must have a stack for each one. As the process have the PEB structure, thread have the TEB structure both of them are in the user-mode. The system maintains structures both in user-mode and kernel-mode, so in this way the user-mode components that wants to grab information about processes or threads doesn't need to make any system call.
As the process, the thread have an executive thread (ETHREAD) structure to represent the thread object in the system address space for Kernel usage. There are more structures maintained by the system for the same thread and process, for example since Windows Architecture can support more than it's own subsystem (Windows Subsystem - Csrss.exe) it creates the CSR_THREAD and also creates the CSR_PROCESS. These structures are maintained by the Windows Subsystem for internal purposes.
The scheduler and dispatcher are the components in the Windows to switch threads. They are responsible to load the thread context to continue or starts to execution of a program. Basically threads can be interrupted or they just gives up of the processor when they finish execution. When a thread becomes idle, then the components mentioned before put this thread in wait and switch to another thread. Every thread have a time-limit (quantum) to run, when it reaches this time-limit the components put the thread in wait and switch to another thread. This process is continuous. The scheduling decisions are made based in the dispatcher-database, is group of structures maintained by processor with all thread's information like priority, state and so on.
So basically processes are containers and threads run programs. Threads run programs that need resources from processes. Just to make it very clear. So when you debug any "process" you must to know actually which thread you are executing/debugging.
Jobs
Jobs are an extension of the process model. Basically it can manage and manipulate one or multiple processes as a unit. So working with a Job is work with all processes linked to it. There is a plenty system mechanisms that the Job can manipulate and various process-related, I/O-related and CPU-related limits that can be manipulated by the job. To a more thorough look on Jobs subject, please search for it in Windows Internals.
The PEB
All processes loaded in the windows have a Executive Process Structure (EPROCESS) that points and maintain many structures relative to it's execution in the system. Here we will just talk about the PEB (Process Environment Block). The PEB is created by the kernel through MmCreatePeb function after setting up the EPROCESS structure. As we already discussed before, this structure is useful on sharing information about the process without transiting between user-mode and kernel-mode. So the main structure is the EPROCESS (Executive Process) that is located in System Address Space (Kernel) and has a pointer (EPROCESS_ADDRESS+0x01B0 *Peb) to PEB that is located in User Address Space (User-Mode).
The PEB is located in the memory segment fs in 32bits architecture and gs in the 64bits architecture at offset 0x30. Actually in one of these memory segments is located the TEB (Thread Environment Block) structure that has the member ProcessEnvironmentBlock (TEB_ADDRESS+0x30) with a pointer to the PEB. Another way to get the PEB address is only with semi-documented or undocumented functions. To get a better view of the structure access the link below (OpenRCE - PDF). Note that it isn't exactly the same as the up-to-date windows version, but still fits to visualize the internal structure.
Would be very expensive to access process information through system calls (system address space), PEB came to enhance performance making process information available in the user address space. Some components of the windows that resides in the user address space need to access information about the process, like the image loader, heap manager and some other components.
PEB structure has a lot of member-fields that you can check on the link I posted above from OpenRCE. In this post I will write about two of them:
- Loader Database (PEB_LDR_DATA)
- Process Heap
Loader Database / PEB_LDR_DATA
Each loaded module is represented as another structure LDR_MODULE, storing the information about the module loaded and the rest of linked list. So any PE file that this process needs to use and has loaded in memory is located in this structure. Let's see how the LDR_MODULE structure looks like:
LDR_MODULE Structure
As you can see the three first members of structure is the linked list and after it there are information about the module itself like, BaseAddress, BaseDllName and so on. So you wanna know the modules loaded by some process ? PEB_LDR_DATA is the way.
Process Heap
In the PEB structure there are two undocumented pointer to heaps. In the offset PEB_ADDRESS+0x18, the ProcessHeap member has the address of the first created heap and the PEB_ADDRESS+0x90, the ProcessHeaps member is a pointer to an array of all heaps created. When the process is created by a debugger in first heap there are two fields, ForceFlags and Flags that are set to tell the kernel if the process was created by a debugger or not. Some debugger like x64dbg already have the option "Hide Debugger" to unset these fields.
In the reference below I listed some good resource to analyze. The offset relative to PEB_ADDRESS can variate due the Windows Version. There is a good repo in github from al-khaser there are many anti-"everything" techniques including ForceFlags and Flags which I said here. Check it out. :)
No comments:
Post a Comment