Injecting code into remote process

In this article, I want to talk about CreateRemoteThread function and how to use it in order to inject some code on a remote process.

From MSDN, this function permits to create a thread that runs in the virtual address space of another process.

Essentially, we can execute a remote thread from a process to another process. Obviously  the remote thread will reside in the virtual address space of the remote process.

In addiction to this, Windows provides another interesting functions : VirtualAllocEx and WriteProcessMemory.

The first function reserves a memory area within the virtual address space of a specific process, and the second function, as its name suggests, writes on a memory area of a specified process.

Essentially, only using these functions, we can execute custom code on a remote process. The most popular technique to do this is DLL Injection.

Dll Injection permits to execute a custom code into another process by forcing it to load a Dll (Dynamic Link Library). There are several methods to force a process to load a Dll, two of these are:

  • adding this Dll to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs register key, so that each new process loads automatically the specified Dll;
  • process manipulation using CreateRemoteThread to force the process to call LoadLibrary with the specified Dll.

However, in this article I want to talk about the simple code injection on a remote process. I want to execute a custom function on a thread of the remote process.

This work seems simple: we open the remote process, we allocate a space for the custom function on the remote process, we write the custom code on remote memory and call CreateRemoteThread with the function address. There’s a problem: the custom code will use functions with different addresses, because it has been injected in a process with a different address space.

So, we will write the entire image on the remote process, but first we need to patch the relocation table. What is the relocation table? Well, when executables (or image) are compiled and linked, the PE Header contains an image base, an address space where the loader can load the image to execute. If this address space is not available, the loader reads the relocation table to know where it has to load the image and how to resolve all object code addresses.

For more information about PE format and the relocation table I report this link and if you want to play with this, look this repository from my friend Evilsocket.

The base relocation table is contained into the OptionalHeader (that’s not optional on executables) member of IMAGE_NT_HEADERS structure. This is divided into blocks, and each block represents the base relocations for a 4K page.

 We’ll get a handle to the current process image, and we’ll extract the relocation table.

Now, we can allocate a copy of our image and then we can calculate the delta from the remote memory address and the image base. The old delta (actual address of image – image base) will be replaced with the new delta into the relocation table.

Now we can replace the old delta in the relocation table.

And finally we can write the memory buffer into the remote process memory allocated previously, and call CreateRemoteThread on the address of the function ThreadProc .

As I said above, if you need to inject a code within a process on a different session you can’t use CreateRemoteThread because it returns error 0x05 (Access Denied). Replace this function with the undocumented NtCreateThreadEx. You can find some information here.

The complete code and a sample of Dll Injection can found on my GitHub.