Injecting thread with codecave

1.8k Views Asked by At

By using 'codecave' technique to inject code into another process; is it possible to inject code to create a new thread (and also inject the code for the new thread) and let that thread execute parallel with the target process main thread?

I can manage this with dll injection but I want to know if it is possible with just pure code injection.

The intention is first of all to learn about different injection techniques but in the end create a heartbeat feature for random processes in order to supervise execution (High Availability). Windows is the target OS and language is C/C++ (with inline ASM when required).

Thanks.

5

There are 5 best solutions below

3
On

There is CreateRemoteThread function.

0
On

When using a DLL injection loader such as "Winject (the one that calls CreateRemoteThread) it is very easy to create Threads that remain until the target process closes.

Just create the Thread within the function:

void run_thread(void* ass)
{
  // do stuff until process terminates
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD result, LPVOID lpReserved)
{
  HANDLE handle = (HANDLE)_beginthread(run_thread, 0, 0);
}

regards, michael

0
On

Sure, but you would have to also inject the code for the remote thread into the process (e.g. a function). Injecting an entire function into a remote process is a pain because there is no clear-cut way to determine the size of a function. This approach would be far more effective if the injected code was small, in which case you would just inject a short assembly stub, then call CreateRemoteThread.

Really though, what would be a benefit of doing this over just straight-up DLL injection? Your 'heartbeat' feature could be implemented just as easily with an injected DLL. (unless someone is going to tell me there's significant overhead?)

0
On

The problem is, even if you inject your code into the process, unless you create a thread at the start of your injected code, it will still not run. Typically, to do code injection you would inject a full DLL. One of popular ways of injecting DLLs is to:

  • Get a handle to the target process (EnumProcesses, CreateTool32Snapshot/Process32First/Process32Next, FindWindow/GetWindowThreadProcessId/OpenProcess, etc.)
  • Allocate memory in the target process that is the same length as a string pointing to the path of your DLL (VirtualAllocEx)
  • Write a string pointing to the path of your DLL to this allocated memory (WriteProcessMemory)
  • Create a remote thread at the LoadLibrary routine (get the address by GetModuleHandle/GetProcAddress) and pass the pointer to the allocated memory as a parameter (CreateRemoteThread)
  • Release the allocated memory (VirtualFreeEx)
  • Close any opened handles (process handles, snapshot handles, etc. with CloseHandle)

Unless there is a particular reason you want to avoid this method, it is by far preferable to copying in the code yourself (WriteProcessMemory and probably setting up page protections (VirtualProtectEx)). Without loading a library you will need to manually map variables, relocate function pointers and all the other work LoadLibrary does.

You asked earlier about the semantics of CreateRemoteThread. It will create a thread in another process which will keep going until it terminates itself or something else does (someone calls TerminateThread or the process terminates and calls ExitProcess, etc.). The thread will run as parallel in the same way a thread that was legitimately created would (context switching).

0
On

You can also use the RtlCreateUserThread function to create the remote thread.