Process injection is one of those stealthy techniques malware loves to use to stay under the radar. By injecting malicious code into legitimate processes, attackers can hide in plain sight, making detection a real challenge.
In this post, I’ll walk you through an actual malware sample that uses process injection, breaking down how it works.
Target:
Malware Name: REMCOS RAT (Remote Control & Surveillance) is a Remote Access Trojan used for stealthy remote control, data exfiltration, and persistence on compromised systems.
Hash: 88a02967d6fa5c0eff65f71b9fae969b8125a20115c2d2ee21053832fdc2fc2b
Process injection is a technique used by malware to execute code within the address space of another legitimate process. This allows attackers to evade detection by blending malicious activity with trusted system processes. Common injection methods include Remote Thread Injection, Process Hollowing, APC Injection, and DLL Injection, each leveraging system APIs to manipulate memory and execution flow.
By injecting code into a legitimate process, malware can bypass security mechanisms, hide from forensic tools, and maintain persistence. Security analysts detect these techniques by monitoring suspicious API calls, analyzing memory regions, and inspecting process behaviors. Identifying process injection early is crucial for preventing privilege escalation and stealthy persistence in compromised systems.
We’ll go step by step, looking at how the injection happens, what’s going on under the hood, and how we can spot it using the right tools. Let’s get into it!
We are going to perform a Basic Static Analysis of the malware sample to identify process injection and, to do this, we will load our sample into Ghidra and open Symbol References to examine function calls and memory manipulations related to the injection technique.
![](https://static.wixstatic.com/media/6a4a49_9d8c827171794fda85299c6bfee04958~mv2.png/v1/fill/w_980,h_526,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/6a4a49_9d8c827171794fda85299c6bfee04958~mv2.png)
Right away we see these functions:
![These are essential Windows API functions, often utilized by malware for process enumeration and control over system processes. Let’s break down what each function does and why it might be used by Remcos.](https://static.wixstatic.com/media/6a4a49_f58b777f39f14f028bb00b64a7cfb680~mv2.png/v1/fill/w_980,h_181,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/6a4a49_f58b777f39f14f028bb00b64a7cfb680~mv2.png)
Let me explain what these functions do and why they are relevant for malware analysis. By understanding how they work, we can get a clearer picture of how Remcos RAT interacts with the system to perform process injection.
CreateToolhelp32Snapshot
This function creates a snapshot of all running processes, threads, heaps, and modules on the system. Malware frequently uses it to get a full list of active processes before choosing a target for injection. Once it has the snapshot, it can iterate through the processes using Process32First and Process32Next.
Reference: Microsoft Docs - CreateToolhelp32Snapshot
Process32First & Process32Next
These functions allow the malware to go through each process in the system. This is typically a reconnaissance step where the malware:
Identifies security-related processes, potentially to terminate them.
Searches for a suitable target for injection or function hooking.
Monitors specific applications that might handle sensitive data.
Reference: Microsoft Docs - Process32First | Process32Next
By analyzing these API calls, we can start piecing together how Remcos RAT interacts with the system, selects its targets, and ultimately executes its injection method. Understanding this behavior is key to detecting and mitigating similar threats.
How Remcos Uses These Functions
Remcos likely uses these APIs for process enumeration and possibly privilege escalation. This is a common technique in malware to gather information about the system and prepare for further actions.
Reconnaissance: By taking a snapshot and enumerating processes, Remcos can map out the running environment, including security solutions or monitoring tools that might interfere with its execution.
Process Injection/Hooking: If it finds a suitable target, such as explorer.exe or another high-privilege process, it may attempt to inject itself to maintain persistence or evade detection.
Anti-Analysis Tactics: Some malware uses process enumeration to check if it's running in a sandbox or monitored environment. If it detects analysis tools or debuggers, it might alter its behavior to avoid detection.
The functions CreateToolhelp32Snapshot, Process32First, and Process32Next are often used in the initial reconnaissance phase of malware that performs process injection. This setup phase is crucial, as it lays the foundation for the actual injection technique, which we’ll analyze next.
Now, let's take a look at the VirtualAllocEx function.
![](https://static.wixstatic.com/media/6a4a49_3307ba9eac8745289e58f69df978a308~mv2.png/v1/fill/w_980,h_101,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/6a4a49_3307ba9eac8745289e58f69df978a308~mv2.png)
VirtualAllocEx is a Windows API function that allows a process to allocate memory in the address space of another process. It is commonly used in legitimate applications for interprocess communication, but it is also frequently abused by malware for Process Injection techniques. By allocating memory in a remote process, an attacker can write and execute malicious code within a trusted system process, making detection more difficult.
Malware often uses VirtualAllocEx alongside other APIs like WriteProcessMemory and CreateRemoteThread to inject and execute payloads. This function provides fine-grained control over memory allocation, allowing the malware to specify the size, protection level, and location of the allocated memory. This makes it a critical component of many injection techniques.
Reference: Microsoft Docs - VirtualAllocEx
![](https://static.wixstatic.com/media/6a4a49_9ce9658fcddf4980bdeb1db92293e4db~mv2.png/v1/fill/w_980,h_507,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/6a4a49_9ce9658fcddf4980bdeb1db92293e4db~mv2.png)
Here’s the function signature for context:
hProcess: Handle to the target process in which memory is being allocated.
lpAddress: The base address for the region of memory to allocate (usually set to NULL to let the system choose).
dwSize: The size of the memory to allocate.
flAllocationType: Specifies the type of memory allocation (e.g., MEM_COMMIT).
flProtect: Specifies the memory protection, often set to PAGE_EXECUTE_READWRITE in malware to allow code execution.
![](https://static.wixstatic.com/media/6a4a49_6d2fc73c7c844721911e18cc72ea9261~mv2.png/v1/fill/w_980,h_374,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/6a4a49_6d2fc73c7c844721911e18cc72ea9261~mv2.png)
Now, let's take a look at this code, and I will explain it to you in detail to make it easier to interpret.
![](https://static.wixstatic.com/media/6a4a49_6250a9b4e1af4dc3b4b80c916be7f7fc~mv2.png/v1/fill/w_980,h_511,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/6a4a49_6250a9b4e1af4dc3b4b80c916be7f7fc~mv2.png)
PUSH 0x40
Pushes 0x40 onto the stack. 0x40 corresponds to PAGE_EXECUTE_READWRITE, meaning the allocated memory will have read, write, and execute permissions.
PUSH 0x3000
Pushes 0x3000 onto the stack. 0x3000 is a combination of the MEM_COMMIT | MEM_RESERVE flags, which means the memory will be allocated and committed for use.
PUSH dword ptr [ESI + 0x50]
Pushes the value stored at [ESI + 0x50] onto the stack. This is likely the handle to the target process, retrieved earlier in the execution.
PUSH dword ptr [ESI + 0x34]
Pushes another value from [ESI + 0x34] onto the stack. This is likely the size of the memory region to be allocated.
PUSH dword ptr [EBP + local_80]
Pushes a local variable (local_80) onto the stack. This might be a pointer related to the allocated memory or additional arguments for the function.
CALL dword ptr [KERNEL32.DLL::VirtualAllocEx]
Calls VirtualAllocEx, to allocate memory in another process. As we said, this function is commonly used in process injection attacks to allocate memory in a remote process before writing shellcode.
MOV dword ptr [EBP + local_6C], EAX
Stores the return value of VirtualAllocEx (the allocated memory address) in local_6C. If EAX is NULL, the allocation failed.
TEST EAX, EAX
Checks whether the function succeeded (EAX != 0). If EAX is 0, the allocation failed, and the program will likely handle the error.
From this code, we can deduce that Remcos RAT is attempting to allocate executable, writable memory in a specific target process. This is a classic step in process injection, especially if followed by a call to WriteProcessMemory (which we see right after this VirtualAllocEx call) to copy its malicious payload into the allocated memory.
Now, let's take a look at the decompiled code window located to our right in Ghidra.
![](https://static.wixstatic.com/media/6a4a49_28c5ead19a1e46fca10d9bc9527fef71~mv2.png/v1/fill/w_980,h_429,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/6a4a49_28c5ead19a1e46fca10d9bc9527fef71~mv2.png)
We now turn our attention to another critical function observed in the decompiled code: NtUnmapViewOfSection. This function is often used to "hollow out" or remove the legitimate code of a target process.
By unmapping the original executable section, Remcos can replace it with its own malicious payload. This technique enables the malware to run under the appearance of a legitimate process, enhancing its evasion capabilities.
The likely workflow involves the following:
The malware starts a legitimate process in a suspended state.
It calls NtUnmapViewOfSection to remove the original memory sections of the target process.
Using VirtualAllocEx, it allocates new memory in the process’s address space.
WriteProcessMemory is then used to inject the malicious payload.
Finally, the malware modifies the execution context to redirect execution to its injected code and resumes the process.
Observing the sequence of API calls (VirtualAllocEx, WriteProcessMemory, NtUnmapViewOfSection), we can infer that Remcos follows a typical process hollowing workflow:
Start Target Process – The malware starts a legitimate process, such as svchost.exe, in a suspended state.
Unmap Original Memory – It calls NtUnmapViewOfSection to remove the legitimate executable sections from memory.
Allocate Memory and Write Payload – Using VirtualAllocEx, the malware reserves memory in the process, and WriteProcessMemory is used to inject the malicious payload.
Modify Execution Context – The thread context is adjusted to ensure execution of the payload once the process is resumed.
Summary
Combining these observations, it is evident that Remcos employs process hollowing for stealthy execution. The full step-by-step process based on the analyzed APIs is as follows:
Create a Suspended Process – A trusted or common Windows process is launched in a suspended state.
Unmap Legitimate Sections – The malware calls NtUnmapViewOfSection to remove the legitimate code from memory.
Allocate New Memory – It uses VirtualAllocEx to allocate writable and executable memory in the hollowed-out process.
Inject Malicious Code – The payload is written into the allocated memory space using WriteProcessMemory.
Resume and Execute – The malware modifies the thread context to point to the injected code, then resumes the process, allowing its payload to execute under the disguise of a legitimate process.
Now, if you want to learn all of this in detail and much more, I recommend enrolling in our Reverse Engineering for Malware Analysts courses. In this course, we cover everything step by step, with real-world examples like the one I just showed you.
SmouK out!