Reader small image

You're reading from  Windows APT Warfare

Product typeBook
Published inMar 2023
Reading LevelIntermediate
PublisherPackt
ISBN-139781804618110
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Sheng-Hao Ma
Sheng-Hao Ma
author image
Sheng-Hao Ma

Sheng-Hao Ma is currently working as a threat researcher at TXOne Networks, specializing in Windows reverse engineering analysis for over 10 years. In addition, he is currently a member of CHROOT, an information security community in Taiwan. He has served as a speaker and instructor for various international conferences and organizations such as Black Hat USA, DEFCON, CODE BLUE, HITB, VXCON, HITCON, ROOTCON, Ministry of National Defense, and Ministry of Education.
Read more about Sheng-Hao Ma

Right arrow

Running static PE files as dynamic processes

At this point, you have a general idea of how a minimal program is generated, compiled, and packaged into an executable file by the compiler in the static phase. So, the next question is, What does the OS do to get a static program running?

Figure 1.6 shows the process structure of how an EXE program is transformed from a static to a dynamic process under the Windows system:

Figure 1.6 – Dynamic operation of the process hatching flow

Figure 1.6 – Dynamic operation of the process hatching flow

Note that this is different from the process hatching process in the latest version of Windows. For the sake of explanation, we'll ignore the processes of privilege escalation, the patching mechanism, and kernel generation, and only talk about how a static program is correctly parsed and run from a single execution.

On Windows systems, all processes must be hatched by the parent process by interrupting the system function to jump to the kernel level. For example, a parent process is currently trying to run the cmd.exe /c whoami command, which is an attempt to hatch the cmd.exe static file into a dynamic process and assign its parameters to /c whoami.

So, what happens in the whole process? As shown in Figure 1.6, these are the steps:

  1. The parent process makes a request to the kernel with CreateProcess, specifying to generate a new process (child process).
  2. Next, the kernel will produce a new process container and fill the execution code into the container with file mapping. The kernel will create a thread to assign to this child process, which is commonly known as the main thread or GUI thread. At the same time, the kernel will also arrange a block of memory in Userland’s dynamic memory to store two structural blocks: a process environment block (PEB) for recording the current process environment information and a thread environment block (TEB) for recording the first thread environment information. The details of these two structures will be fully introduced in Chapter 2, Process Memory – File Mapping, PE Parser, tinyLinker, and Hollowing, and in Chapter 3, Dynamic API Calling – Thread, Process, and Environment Information.
  3. The NtDLL export function, RtlUserThreadStart, is the main routing function for all threads and is responsible for the necessary initialization of each new thread, such as the generation of structured exception handling (SEH). The first thread of each process, that is, the main thread, will execute NtDLL!LdrInitializeThunk at the user level and enter the NtDLL!LdrpInitializeProcess function after the first execution. It is the executable program loader, responsible for the necessary correction of the PE module loaded into the memory.
  4. After the execution loader completes its correction, it jumps back to the current execution entry (AddressOfEntryPoint), which is the developer’s main function.

Important note

From a code perspective, a thread can be thought of as a person responsible for executing code, and a process can be thought of as a container for loading code.

The kernel layer is responsible for file mapping, which is the process of placing the program content based on the preferred address during the compiling period. For example, if the image base address is 0x400000 and the .text offset is 0x1000, then the file mapping process is essentially a simple matter of requesting a block of memory at the 0x400000 address in the dynamic memory and writing the actual contents of .text to 0x401000.

In fact, the loader function (NtDLL! LdrpInitializeProcess) does not directly call AddressOfEntryPoint after execution; instead, the tasks corrected by the loader and the entry point are treated as two separate threads (in practice, two thread contexts will be opened). NtDLL!NtContinue will be called after the correction and will hand over the task to the entry to continue execution as a thread task schedule.

The entry point of the execution is recorded in NtHeaders→OptionalHeader.AddressOfEntryPoint of the PE structure, but it is not directly equivalent to the main function of the developer. This is for your understanding only. Generally speaking, AddressOfEntryPoint points to the CRTStartup function (C++ Runtime Startup), which is responsible for a series of C/C++ necessity initialization preparations (e.g., cutting arguments into developer-friendly argc and argv inputs, etc.) before calling the developer’s main function.

In this section, we learned how EXE files are incubated from static to dynamically running processes on the Windows system. With the process and thread, and the necessary initialization actions, the program is ready to run.

Previous PageNext Page
You have been reading a chapter from
Windows APT Warfare
Published in: Mar 2023Publisher: PacktISBN-13: 9781804618110
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Sheng-Hao Ma

Sheng-Hao Ma is currently working as a threat researcher at TXOne Networks, specializing in Windows reverse engineering analysis for over 10 years. In addition, he is currently a member of CHROOT, an information security community in Taiwan. He has served as a speaker and instructor for various international conferences and organizations such as Black Hat USA, DEFCON, CODE BLUE, HITB, VXCON, HITCON, ROOTCON, Ministry of National Defense, and Ministry of Education.
Read more about Sheng-Hao Ma