3. QueueUserAPC
#processinjection #queueUserAPC #golang #maldev #malwaredevelopment
This technique is a combination of the two previous techniques. Unlike process hollowing it will not overwrite the contents of the main thread but allocate a new memory region. The main difference is that QueueUserAPC will be used to execute our shellcode when the main thread is resumed.
The benefit is that we won't be calling the CreateRemoteThread API.
The Windows APIs required to perform this technique are the following:
Create suspended process
Starting a process can be achieved by calling the CreateProcess API.
BOOL CreateProcessA(
[in, optional] LPCSTR lpApplicationName,
[in, out, optional] LPSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCSTR lpCurrentDirectory,
[in] LPSTARTUPINFOA lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);The most important parameter is the dwCreationFlags should be set to CREATE_SUSPENDED (0x04)


Allocating memory on remote process
VirtuallAllocEx will be used for allocating memory for our shellcode in the remote memory.
hProcess: Process Handle returned by the CreateProcess API
lpAddress: We will let the API decide where to allocate the memory, therefore this value will be set to 0
dwSize: Will be the size of our shellcode
flAllocationType: We need to reserve and commit memory
flProtect: This can be done in a number of ways. To write and execute shellcode we will need rx permissions.
Writing shellcode to remote process
WriteProcessMemory winapi will be used to write shellcode to the remote memory
hProcess: Process Handle returned by the CreateProcess API
lpBaseAddress: Value returned from VirtualAllocEx
lpBuffer: A pointer to the beginning of our shellcode byte array
nSize: Size of our shellcode
lpNumberOfBytesWritten: Ouputs the number of bytes written to the destination address
Add a user-mode APC ( Asynchronous Procedure Call)
pfnAPC: This will be the address returned by VirtualAllocEx
hThread: Returned by the createprocess API
dwData: Set to 0
Resume Execution
To resume execution we only have to resume the suspended thread. The ResumeThread API will be used to achieve that.
We simply pass the handle returned by the CreateProcess API.

Complete Code
Last updated
Was this helpful?