Process Hollowing

3 minute read

Hello brothers, today I am going to explain anti reversing technique which also is a technique of process injection before digging deep into the details of this method, first we need to explain what process hollowing is, after that, I will explain with code snippets and APIs

process hollowing relies on creating a process, but only in a suspended mode, which makes it seem like it has also been choked with no window to make the user feel nothing; and then it unmaps or cuts the relations of the program with memory that make program code is not in memory (Unmaping) after that it allocates space in memory of the program to write the malicious code into it and then make the EIP points to new Code section of the Malicious code using APIs which we will explain below
,this GIF Explains what it looks like in a clear and simple way

This image belongs to https://www.elastic.co/

moving to our lady IDA, which makes reversing easy something
I have a simple code whose only mission is process hollowing, I am going to explain line-by-line assembly code I hope it looks like what I expect

first

it initiates a cookie which is used to avoid stack overflow vulnerability, then it fills the structure of Statup_info with zeros

— the startup_info is a data structure used to save information about the startup process (exe name, commands and arguments) then it also zeros out the context

Figure(1): zero out startup_info

as we explained before the program is going to lunch a process in suspended mode and our Target process here is svchost.exe, the flag dwCreationFlags = 4 which indicates that is a suspended process which is the core of process hollowing, and it uses CreateProcessA() to do that

Figure(1): Create svchost.exe in suspended mode

after that, it saves the information of the thread before the UnMaping process to avoid crashing, that’s done by Calling GetThreadContext() API

Figure(1): Save thread information

After that, it resolves ZwUnmapViewOfSection() API using dynamic linking via GetModuleHandle(ntdll.dll) and GetProcAddress() and save the address of the API in Eax

Figure(1): zDynamic resolving

after resolving, it calls ZwUnmapViewOfSection() which unmaps the code section that’s addressed is 0x400000h(Base address)

then the swapping process comes and that’s done through many steps first of it is allocating a memory space in the targeted function using VirtualAllocEx() which can allocate a space in another process’s memory and give the svchost.exe handle as the first argument and this API retrieves the address of the allocated memory in EAX register, the argument (flprotect=0x40h → PAGE_EXECUTE_READWRITE) and the argument **(flAllocationType = 0x3000h →MEM_COMMIT   MEM_RESERVE )**

Figure(1): Memory allocation

all thing is ready to inject, we just need to inject data and the program does this by calling WriteProcessMemory() API and passing process handle and base address as arguments
but the important push here is (lpBuffer → this argument is a pointer to the code which is going to be injected) in our case we only need to inject this Byte (0xcc = int3 → a system breakpoint) → the mal devs put their shell code here

Figure(1): Injecting code

code is injected and all thing is done except 2 steps which are very important too

1- fill the thread context with data needed to avoid crashing and that’s done by SetThreadContext() API and fill it with the following

1.0 -BaseAddress which saved in EAX Register  
1.1 -ContextFlags and here we will explain something   the value **0x10002h** is a combination of **Context_Full(0001h)** and **Context_debug_register(2000h)**   — the **Context_full** flag specifies that the context contains all the standard Registers

— the Context_debug_Register flag specifies that the context structure contains Debug Registers DR0-DR7

2-do u remember that we create the process in a suspended state and then we unmap the code, and then we write another code, so we need now to make all things look normal and run the process in a normal state with our payload, and we will do this by using ResumeThread() API which is used to resume a suspended thread

Figure(1): z Complete execution

I hope I have explained enough. This is what I can do. If you see any modifications or mistakes, do not hesitate to tell me, thank you.