Concept of PE Injection
Portable Executable Injection
high level overview of the unpacking routine and the PE injection routine:
List of Process Injection Technique
1. CLASSIC DLL INJECTION VIA CREATEREMOTETHREAD AND LOADLIBRARY
This technique is one of the most common techniques used to inject malware into another process. The malware writes the path to its malicious dynamic-link library (DLL) in the virtual address space of another process, and ensures the remote process loads it by creating a remote thread in the target process.
Before the malware can inject itself into a process (such as svchost.exe), it first needs to find a suitable target. To do this, it scans running processes using three Application Program Interfaces (APIs): CreateToolhelp32Snapshot, Process32First, and Process32Next.
| API | Description |
|---|---|
CreateToolhelp32Snapshot | generates a snapshot of all active processes or specific modules in memory. |
Process32First | extracts details about the first process in that snapshot. |
Process32Next | iterates through the remaining processes, allowing the malware to search for its target. |
Once it identifies the right process, the malware obtains its handle using the OpenProcess API.
As illustrated in Figure 1, the malware then calls VirtualAllocEx to allocate space within the target process’s memory, where it writes the path to its DLL using WriteProcessMemory. To execute malicious code within another process, the malware employs APIs such as CreateRemoteThread, NtCreateThreadEx, or RtlCreateUserThread. The last two methods are undocumented. Regardless of which API is used, the main objective is to pass the address of LoadLibrary to force the remote process to execute the malicious DLL.
Security software commonly flags the CreateRemoteThread API because it requires a malicious DLL to be stored on disk, making it more likely to be detected. Since sophisticated attackers aim to evade detection, they often avoid this method. The screenshot below shows an instance of malware named Rebhip utilizing this technique.
| Phase | Step | API/Action |
|---|---|---|
| 1. Find a Target Process | Scan active processes | CreateToolhelp32Snapshot, Process32First, Process32Next |
Identify a suitable process (e.g., svchost.exe) | Selection logic based on process name, privileges, etc. | |
| Obtain a handle to the target process | OpenProcess | |
| 2. Prepare Memory | Allocate memory in the target process | VirtualAllocEx |
| Write the path to the malicious DLL into the allocated memory | WriteProcessMemory | |
| 3. Execute Malicious Code | Use remote thread creation APIs to execute LoadLibrary | CreateRemoteThread (common, detectable) |
NtCreateThreadEx (undocumented, stealthier) | ||
RtlCreateUserThread (undocumented alternative) | ||
Pass address of LoadLibrary to load the malicious DLL | Used as parameter for thread entry point | |
| 4. Achieve Code Execution | DLL is loaded in the context of the remote process | Remote process executes the DLL’s entry point |
| Malicious functions are executed inside the hijacked process | Code runs with the permissions of the target process |
2. PORTABLE EXECUTABLE INJECTION (PE INJECTION)
Instead of using LoadLibrary, PE injection involves directly copying malicious code (a full PE file) into the memory of a target process and executing it. This avoids dropping a DLL on disk, making it stealthier.
- Memory Setup: Malware allocates memory in a target process using
VirtualAllocExand writes its PE code usingWriteProcessMemory. - Execution: It runs the code via
CreateRemoteThreador a small shellcode. - Relocation Challenge: Since the injected PE loads at a new base address, malware must fix hardcoded addresses. It does this by parsing the relocation table and adjusting offsets dynamically (often using nested loops).
- Indicators: Analysts often see two nested
forloops and anand 0x0fffinstruction beforeCreateRemoteThread—a sign of address relocation handling.
This method is fileless like Reflective DLL Injection and Memory Module:
- Reflective DLL Injection: The DLL maps itself into memory without needing Windows APIs.
- Memory Module: Similar, but the loader handles memory mapping.
These in-memory methods are stealthier as they don’t rely on LoadLibrary or CreateRemoteThread.
| API / Function | Purpose |
|---|---|
VirtualAllocEx | Allocates memory in the remote (target) process |
WriteProcessMemory | Writes the malicious PE code into the allocated memory |
CreateRemoteThread | Starts execution of the injected code in the remote process |
| (Custom Shellcode) | Alternative method to trigger execution instead of using Windows APIs |
| (Relocation Logic) | Not an API, but malware often parses the PE relocation table manually |
LoadLibrary (mentioned) | Common in other techniques, but not used in PE injection itself |
Note: PE injection avoids using LoadLibrary by injecting full PE code, not a DLL path.
3. PROCESS HOLLOWING (A.K.A PROCESS REPLACEMENT AND RUNPE)
Process Hollowing is a stealthy technique where malware creates a legitimate process (like svchost.exe), but replaces its code with malicious code before it runs.
How It Works – Step by Step:
- Create a Suspended Process:
Malware creates a legitimate process in a suspended state using CreateProcess with the CREATE_SUSPENDED flag. This means the process doesn’t start running yet.
- Unmap Legitimate Code:
It removes (unmaps) the original code of that process using ZwUnmapViewOfSection or NtUnmapViewOfSection.
- Allocate Memory for Malicious Code:
It allocates new memory inside the target process using VirtualAllocEx.
- Inject Malicious Code:
The malware writes its own executable sections into the target process using WriteProcessMemory.
- Redirect Execution to Malicious Code:
It modifies the process’s thread to point to its new malicious entry point using SetThreadContext.
- Resume the Process:
Finally, it calls ResumeThread to start execution — but now, the “legitimate” process is running the malware’s code.
API Table for Process Hollowing
| API / Function | Purpose |
|---|---|
CreateProcess | Creates a new process in a suspended state |
ZwUnmapViewOfSection | Unmaps the original code section from the process (variant of NtUnmap...) |
NtUnmapViewOfSection | Same as above (often used interchangeably) |
VirtualAllocEx | Allocates new memory in the target process |
WriteProcessMemory | Writes the malicious executable into the allocated memory |
SetThreadContext | Points the thread’s start address to the malicious entry point |
ResumeThread | Resumes the suspended thread to start execution |
4. THREAD EXECUTION HIJACKING (A.K.A SUSPEND, INJECT, AND RESUME (SIR))
Thread Execution Hijacking is a stealthy injection technique where malware modifies an existing thread in a legitimate process, rather than creating a new thread or process.
This helps the malware avoid detection, since thread creation and process spawning are often flagged by security tools.
How It Works – Flow Summary
- Find a Thread in a Target Process
Malware enumerates threads using CreateToolhelp32Snapshot and Thread32First.
- Open and Suspend the Target Thread
It opens the thread with OpenThread and suspends it using SuspendThread.
- Inject Malicious Code into the Process
Malware allocates memory using VirtualAllocEx and writes the payload using WriteProcessMemory.
- Change the Thread’s Execution Flow
It changes the thread’s EIP (instruction pointer) to point to the malicious code using SetThreadContext.
- Resume the Thread
Finally, ResumeThread is called to let the hijacked thread execute the injected code.
Note: If the thread is suspended during a sensitive operation (like a system call), malware may wait or retry to avoid crashing the system.
API Table for Thread Execution Hijacking
| API / Function | Purpose |
|---|---|
CreateToolhelp32Snapshot | Captures a snapshot of the system’s threads |
Thread32First | Begins iterating through the thread list |
OpenThread | Opens a handle to a specific thread |
SuspendThread | Suspends the thread so it can be hijacked safely |
VirtualAllocEx | Allocates memory in the remote process |
WriteProcessMemory | Writes shellcode or DLL path to the allocated memory |
SetThreadContext | Changes the thread’s execution pointer (EIP) to redirect to the malicious code |
ResumeThread | Resumes the thread, which now executes the injected payload |
5. HOOK INJECTION VIA SETWINDOWSHOOKEX
Hook injection is a technique where malware sets a Windows hook to load its malicious DLL when a specific event (like a keystroke or mouse click) happens in a target thread.
This method lets malware execute in the context of a legitimate process without directly creating threads or injecting shellcode.
Step-by-Step How It Works
- Locate Target Thread (Optional)
Malware can search for a specific thread using CreateToolhelp32Snapshot and Thread32Next.
- Prepare the Malicious DLL
- Load the malicious DLL into memory using
LoadLibrary. - Get the address of the hook function inside the DLL using
GetProcAddress.
- Load the malicious DLL into memory using
- Set the Hook
- Use
SetWindowsHookExto register a hook for an event (e.g., keyboard or mouse input). - Specify the thread to hook into — malware often chooses a specific thread to reduce detection.
- Use
- Trigger the Hook
- When the event occurs (like a keystroke), Windows calls the malicious function in the DLL.
- The malware now executes inside the context of the hooked process.
API Table for Hook Injection
| API / Function | Purpose |
|---|---|
CreateToolhelp32Snapshot | Takes a snapshot of threads (used to find a target thread) |
Thread32Next | Iterates through the thread list |
LoadLibrary | Loads the malicious DLL into memory |
GetProcAddress | Gets the address of the hook function inside the DLL |
SetWindowsHookEx | Installs the hook that triggers the DLL function when an event occurs |
6. INJECTION AND PERSISTENCE VIA REGISTRY MODIFICATION (E.G. APPINIT_DLLS, APPCERTDLLS, IFEO)
Appinit_DLL, AppCertDlls, and IFEO (Image File Execution Options) are all registry keys that malware uses for both injection and persistence. The entries are located at the following locations:
| Technique | Registry Key Location |
|---|---|
| AppInit_DLLs | HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls |
| AppCertDlls | HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls |
| IFEO | HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<Target> |
AppInit_DLLs
Malware can insert the location of their malicious library under the Appinit_Dlls registry key to have another process load their library. Every library under this registry key is loaded into every process that loads User32.dll. User32.dll is a very common library used for storing graphical elements such as dialog boxes. Thus, when a malware modifies this subkey, the majority of processes will load the malicious library. Figure 6 demonstrates the trojan Ginwui relying on this approach for injection and persistence. It simply opens the Appinit_Dlls registry key by calling RegCreateKeyEx, and modifies its values by calling RegSetValueEx.
AppCertDlls
This approach is very similar to the AppInit_DLLs approach, except that DLLs under this registry key are loaded into every process that calls the Win32 API functions CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW, and WinExec.
Image File Execution Options (IFEO)
IFEO is typically used for debugging purposes. Developers can set the “Debugger Value” under this registry key to attach a program to another executable for debugging. Therefore, whenever the executable is launched the program that is attached to it will be launched. To use this feature you can simply give the path to the debugger, and attach it to the executable that you want to analyze. Malware can modify this registry key to inject itself into the target executable. In Figure 7, Diztakun trojan implements this technique by modifying the debugger value of Task Manager.
API Table for Registry-Based Injection
| API / Function | Purpose |
|---|---|
RegCreateKeyEx | Opens or creates a registry key |
RegSetValueEx | Sets a registry value (e.g., path to malicious DLL or debugger) |
| (CreateProcess family) | Triggers AppCertDlls injection indirectly |
| (User32.dll load) | Triggers AppInit_DLLs injection indirectly |
| (Executable launch) | Triggers IFEO debugger replacement |
7. APC INJECTION AND ATOMBOMBING
APC Injection allows malware to queue a function to run in the context of another thread. When that thread enters an alertable state (e.g., while waiting or sleeping), the malware’s code gets executed.
AtomBombing is a stealthier variation of APC injection where malware uses Windows atom tables to store and inject code into another process, bypassing common security tools.
Step-by-Step: APC Injection
- Identify a Target Thread in Alertable State
Malware looks for threads calling functions like SleepEx, WaitForSingleObjectEx, etc.
- Get Handle to the Target Thread
Use OpenThread to get access to that thread.
- Inject Code via APC Queue
- Malware queues its code (e.g.,
LoadLibraryto load a malicious DLL) to that thread usingQueueUserAPC. - Once the thread becomes alertable, it executes the malware’s function.
- Malware queues its code (e.g.,
Step-by-Step: AtomBombing
- Store Payload in Atom Table
Malware stores shellcode or DLL path in a global atom table, which is used by Windows to share small strings across processes.
- Write into Target Memory
Instead of using WriteProcessMemory, the malware retrieves the data from the atom table within the target process.
- Queue APC with Malicious Function
Like in standard APC injection, malware uses QueueUserAPC to call the malicious function (e.g., LoadLibraryA).
- Code Executes When Thread Becomes Alertable
APIs Used in APC Injection & AtomBombing
| API / Function | Purpose |
|---|---|
OpenThread | Opens a handle to the target thread |
QueueUserAPC | Queues the malicious function to the target thread’s APC queue |
LoadLibraryA | Common function pointer used in APC to load a malicious DLL |
SleepEx, WaitForSingleObjectEx, etc. | Cause a thread to enter alertable state, allowing queued APCs to run |
GlobalAddAtom, GlobalGetAtomName (AtomBombing) | Add/retrieve malicious data into/from atom table |
8. EXTRA WINDOW MEMORY INJECTION (EWMI) VIA SETWINDOWLONG
EWMI is a stealthy code injection method that targets extra window memory (EWM) of windows like Shell_TrayWnd (part of explorer.exe). Malware uses this small memory space to hijack function pointers and redirect execution to malicious code stored in a shared memory section.
Step-by-Step: EWMI
- Write Shellcode to Shared Memory Section
- Malware either creates or maps a shared memory section into both its own and
explorer.exe’s memory. - Writes the malicious code (shellcode) into that shared memory region.
- Malware either creates or maps a shared memory section into both its own and
- Modify Extra Window Memory of Target Window (
Shell_TrayWnd)- Calls
GetWindowLongto read current function pointer (at a certain offset). - Calls
SetWindowLongto overwrite the pointer to now point to the shellcode.
- Calls
- Trigger Execution
- Calls
SendNotifyMessageto send a message toShell_TrayWnd. - That message indirectly triggers the execution of the shellcode by calling the pointer set in the EWM.
- Calls
APIs Used in EWMI
| API / Function | Purpose |
|---|---|
NtMapViewOfSection | Maps a shared memory section into the address space of both processes |
GetWindowLong | Retrieves a value from the extra window memory of a target window |
SetWindowLong | Modifies a value (e.g., function pointer) in the extra window memory |
SendNotifyMessage | Triggers the execution of the pointer in EWM by sending a window message |
9. INJECTION USING SHIMS
Shims are normally used by Microsoft to make older software compatible with newer versions of Windows. They let Windows apply “fixes” (like compatibility adjustments) to programs. However, malware can abuse this feature to inject code or persist by telling Windows to always load a malicious DLL when a specific executable (like chrome.exe) runs.
Step-by-Step: Shim Injection
- Create Malicious Shim Database (.sdb)
- The malware creates an
.sdbfile with a malicious “fix” (likeInjectDLL) that forces a specific app (e.g., Chrome) to load a malicious DLL.
- The malware creates an
- Install Shim
- Malware installs this
.sdbdatabase using the toolsdbinst.exe.
- Malware installs this
- Trigger Application
- When the targeted app (like Chrome) is launched, the Shim Engine kicks in, finds the
.sdb, and loads the malicious DLL automatically—without needing traditional injection methods.
- When the targeted app (like Chrome) is launched, the Shim Engine kicks in, finds the
APIs / Tools / Features Used in Shim Injection
| Tool / Feature / API | Purpose |
|---|---|
sdbinst.exe | Installs the .sdb shim database into the system |
| Shim Engine (internal) | Built into Windows; automatically applies shims when executables are launched |
InjectDLL (Shim fix) | Loads a specified DLL into the target executable |
DisableNX, DisableSEH | Other shim “fixes” often used by malware to weaken protections |
Shim-based injection is stealthy and does not require runtime API calls like
CreateRemoteThreadorWriteProcessMemory. It’s handled entirely by Windows during process startup.
10. IAT HOOKING AND INLINE HOOKING (A.K.A USERLAND ROOTKITS)
Malware can secretly change how Windows functions work by intercepting API calls in two main ways:
- IAT Hooking (Import Address Table): The malware changes function pointers in the Import Address Table of a process, so when the process tries to call a standard API (e.g.,
CreateFile), it ends up calling the malware’s function instead. - Inline Hooking: Instead of altering pointers, the malware directly modifies the first few bytes of the actual API function in memory, replacing them with a jump to its own code. This intercepts execution even if the API is called directly.
Step-by-Step: How Hooking Works
IAT Hooking:
- Malware locates the target process’s Import Address Table (IAT).
- Finds a specific imported API (e.g.,
CreateWindowEx). - Replaces the function pointer with its own malicious function address.
- When the process calls the API, it executes malware’s function instead.
Inline Hooking:
- Malware finds the memory location of the target API (e.g.,
CreateWindowEx) in system DLLs. - Overwrites the first few instructions (usually 5 bytes) with a JMP instruction to its own malicious code.
- API call is now redirected to malicious logic.
APIs / Concepts Used in Hooking Techniques
| API / Concept | Purpose / Usage |
|---|---|
CreateWindowEx | Common target function shown in FinFisher’s IAT hook |
VirtualProtect / NtProtectVirtualMemory | Used to change memory protection before modifying code or IAT |
GetProcAddress | Locates original function address to hijack or preserve original call |
ReadProcessMemory / WriteProcessMemory | May be used to read/write into the IAT or DLL memory |
IMAGE_IMPORT_DESCRIPTOR | PE structure used to navigate the Import Address Table |
jmp (assembly instruction) | Used in inline hooking to redirect execution flow |

















