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.
There is CreateRemoteThread function.
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
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?)
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).
You can also use the RtlCreateUserThread function to create the remote thread.
Related
I have a DLL that I inject into another process but I want to be able to call the exports on that DLL from my application. I've read elsewhere that you have to the SendMessage API but I have no idea what to do. Is there any example code on how this is done?
While it is not possible to directly call a function in another process, you can do it indirectly pretty easily with a few steps and the Windows API.
Get the addresses of LoadLibrary and GetProcAddress from your own process. kernel32.dll should be loaded at the same address in every process, so you can rely on them being present in the process into which you are injecting
Create a struct that will hold all the arguments you want to pass to your function that will call the functions in the other process (because CreateRemoteThread can only pass one argument to a function, so we'll use it to pass a pointer to the structure) which at least contains member function pointers to hold the addresses of LoadLibrary and GetProcAddress
Allocate enough memory for a struct in the remote process via VirtualAllocEx, then fill it with the correct information with WriteProcessMemory
Write a function, taking a pointer to the struct you wrote, that uses LoadLibrary/GetProcAddress to call the function you want. Remember to use the pointers to those functions in the struct you are passing the function, not the names.
Allocate enough memory in the remote process to hold the function with VirtualAllocEx, making sure to pass VAX the PAGE_EXECUTE_READWRITE flag so that it can hold executable code
Read and write the function's code from your process to the other process via Read/WriteProcessMemory
Call the function in the remote process (which is at the address returned by the VirtualAllocEx) by using CreateRemoteThread.
Make sure that all the data you pass to the function is either stored inside the struct and/or resides in the remote process's address space (get it there with VirtualAllocEx/WriteProcessMemory.
It may look a little involved, but it's not really that complicated. If you need some help with it, feel free to ask in a comment.
You can't directly call functions in another process, in general. There are, however, some workarounds you can use.
First, if you know the address of the export (which isn't the case a lot of the time), and the function you call uses the __stdcall calling convention, takes a pointer-sized integer as an argument, and returns a DWORD, you can use CreateRemoteThread to execute it in a thread in the remote process. This is often used to run LoadLibrary to inject a DLL into a target process, since LoadLibrary is loaded in the same address on all processes on a given computer.
Otherwise, the DLL you inject will need to do some sort of RPC with the process that called it. For example, you could have your injected DLL spawn a thread in its DLL_PROCESS_ATTACH handler, which in turn connects to a named pipe, or connects over COM or something to the master process.
SendMessage would need a window handle (hidden or visible), and a message-pump associated with it, that can handle the custom message. As with UAC/Windows-7, the integrity levels of applications may prevent other applications to send/post messages from other processes having low integrity.
It is better to have another thread that waits for these custom messages. For this, you may use pipes (named or unnamed), sockets, mail-slots, shared memory (along with mutex/event for triggering). The another processes would send the message using same protocol.
But before implementing this custom messaging/protocol/IPC mechanism, I suggest you to first determine the exact need.
I have an multithreaded application that uses a DLL that I created. There is a certain function that will fail if the DLL has not run a certain function yet. How can I make sure that the thread that runs this application function waits for that DLL function to complete before continuing?
Visualization:
O = DLL Function Completes
T = Application Function Starts
App Thread:--------------O----------------------------------
DLL Thread:----------------------T--------------------------
Several approaches:
First thought would be to put the code into DLLMain(), which is executed automatically on application/DLL load. Not everything can be done here though, like blocking operations or operations that require loading other DLLs. Be sure to read and understand the docs if you try this approach.
The second thought is to throw or assert(), so that the init function must be called before any other one, like WSAStartup(). You would then have to call this once in main() before creating any other threads. This is a simple approach. It requires manual work and you can't create threads inside the ctors of globals (which is always dangerous anyway), but at least it will tell you if you got it wrong and, assuming the assert() approach, has zero overhead for release builds.
A third variant is using Boost.Thread's One-time Initialization initialization, which seems to do what you want.
You could use a named event.
Create an event for both the app and DLL to share first:
HANDLE myEvent = CreateEvent(NULL, false, false, L"MyEvent");
To signal complete use:
SetEvent(myEvent);
To wait for completion use:
WaitForSingleObject(myEvent, INFINITE);
I have a DLL that I inject into another process but I want to be able to call the exports on that DLL from my application. I've read elsewhere that you have to the SendMessage API but I have no idea what to do. Is there any example code on how this is done?
While it is not possible to directly call a function in another process, you can do it indirectly pretty easily with a few steps and the Windows API.
Get the addresses of LoadLibrary and GetProcAddress from your own process. kernel32.dll should be loaded at the same address in every process, so you can rely on them being present in the process into which you are injecting
Create a struct that will hold all the arguments you want to pass to your function that will call the functions in the other process (because CreateRemoteThread can only pass one argument to a function, so we'll use it to pass a pointer to the structure) which at least contains member function pointers to hold the addresses of LoadLibrary and GetProcAddress
Allocate enough memory for a struct in the remote process via VirtualAllocEx, then fill it with the correct information with WriteProcessMemory
Write a function, taking a pointer to the struct you wrote, that uses LoadLibrary/GetProcAddress to call the function you want. Remember to use the pointers to those functions in the struct you are passing the function, not the names.
Allocate enough memory in the remote process to hold the function with VirtualAllocEx, making sure to pass VAX the PAGE_EXECUTE_READWRITE flag so that it can hold executable code
Read and write the function's code from your process to the other process via Read/WriteProcessMemory
Call the function in the remote process (which is at the address returned by the VirtualAllocEx) by using CreateRemoteThread.
Make sure that all the data you pass to the function is either stored inside the struct and/or resides in the remote process's address space (get it there with VirtualAllocEx/WriteProcessMemory.
It may look a little involved, but it's not really that complicated. If you need some help with it, feel free to ask in a comment.
You can't directly call functions in another process, in general. There are, however, some workarounds you can use.
First, if you know the address of the export (which isn't the case a lot of the time), and the function you call uses the __stdcall calling convention, takes a pointer-sized integer as an argument, and returns a DWORD, you can use CreateRemoteThread to execute it in a thread in the remote process. This is often used to run LoadLibrary to inject a DLL into a target process, since LoadLibrary is loaded in the same address on all processes on a given computer.
Otherwise, the DLL you inject will need to do some sort of RPC with the process that called it. For example, you could have your injected DLL spawn a thread in its DLL_PROCESS_ATTACH handler, which in turn connects to a named pipe, or connects over COM or something to the master process.
SendMessage would need a window handle (hidden or visible), and a message-pump associated with it, that can handle the custom message. As with UAC/Windows-7, the integrity levels of applications may prevent other applications to send/post messages from other processes having low integrity.
It is better to have another thread that waits for these custom messages. For this, you may use pipes (named or unnamed), sockets, mail-slots, shared memory (along with mutex/event for triggering). The another processes would send the message using same protocol.
But before implementing this custom messaging/protocol/IPC mechanism, I suggest you to first determine the exact need.
What's the cheapest way for a JavaScript like setTimeout-function in C++?
I would need this:
5000 miliseconds from now, start function xy (no parameters, no return value).
The reason for this is I need to initialize COM for text to speech, but when I do it on dll attach, it crashes.
It works fine however if I do not call CoInitialize from dllmain.
I just need to call CoInitialize and CoCreateInstance, and then use the instance in other functions. I can catch the uninitialized instance by checking for NULL, but I need to initialize COM - without crashing.
Calling CoInitialize() from DllMain() is a bad thing to do; there are LOTS of restrictions on what you can do from DllMain(); see here: http://blogs.msdn.com/larryosterman/archive/2004/04/23/118979.aspx
Even if it DID work reliably then initialising COM from within DllMain() isn't an especially nice thing to do as COM is initialised per thread and you don't know what the application itself wants to do with regards to COM apartments for the thread that you want to initialise COM for... This means that you might initialise COM in one way and then the application might need to initialise it in another way and might fail because of what your DLL had done...
You COULD spin up a thread in DllMain() as long as you are careful (see here http://blogs.msdn.com/oldnewthing/archive/2007/09/04/4731478.aspx) and then initialise COM on that thread and do all your COM related work on that thread. You would need to marshal whatever data you need to use COM with from whatever thread you're called on to your own COM thread and make the COM call from there...
And then there's the question of whether the instance of the COM object that you create (could you reliably do what you want to do) would be usable from the thread that was calling into your DLL to make the call... You do understand how you'd have to marshal the interface pointer if required, etc?
Alternatively you should expose YOUR functionality via COM and then have the application load your DLL as a COM DLL and everything will work just fine. You can specify the apartment type that you need and the app is responsible for setting things up for you correctly.
So, in summary, you don't need the answer to your question.
When it is OK to stop the execution for 5 seconds entirely, you can use the Winapi Sleep function. Beware that the documentation of Sleep minds some possible problems with CoInitialize and Messages.
Alright, I'm injecting some code into another process using the CreateRemoteThread/LoadLibrary "trick".
I end up with a thread id, and a process with a DLL of my choice spinning up. At least in theory, the DLL does nothing at the moment so verifying this is a little tricky. For the time being I'm willing to accept it on faith alone. Besides, this question needs to be answered before I push to hard in this direction.
Basically, you can't block in DllMain. However, all I've got to communicate with the remote thread is its id. This practically begs for PostThreadMessage/GetMessage shenanigans which block. I could spin up another thread in DllMain, but I have no way of communicating its id back to the creating thread and no way of passing the another thread's id to the remote one.
In a nutshell, if I'm creating a remote thread in a process how should I be communicating with the original process?
Step zero; the injected DLL should have an entry point, lets call it Init() that takes a LPCWSTR as its single parameter and returns an int; i.e. the same signature as LoadLibrary() and therefore equally valid as a thread start function address...
Step one; inject using load library and a remote thread. Do nothing clever in the injected DLLs DLLMain(). Store the HMODULE that is returned as the exit code of the injecting thread, this is the HMODULE of the injected DLL and the return value of LoadLibrary().
Note that this is no longer a reliable approach on x64 if /DYNAMICBASE and ASLR (Address space layout randomisation) is enabled as the HMODULE on x64 is larger than the DWORD value returned from GetThreadExitCode() and the address space changes mean that it's no longer as likely that the HMODULE's value is small enough to fit into the DWORD. See the comments below and the linked question (here) for a work around using shared memory to communicate the HMODULE
Step two; load the injected DLL using LoadLibrary into the process that is doing the injecting. Then find the offset of your Init() entrypoint in your address space and subtract from it the HMODULE of your injected DLL in your address space. You now have the relative offset of the Init() function. Take the HMODULE of the injected DLL in the target process (i.e. the value you saved in step one) and add the relative address of Init() to it. You now have the address of Init() in your target process.
Step three; call Init() in the target process using the same 'remote thread' approach that you used to call LoadLibrary(). You can pass a string to the Init() call, this can be anything you fancy.
What I tend to do is pass a unique string key that I use as part of a named pipe name. The Injected DLL and the injecting process now both know the name of a named pipe and you can communicate between them. The Init() function isn't DLLMain() and doesn't suffer from the restrictions that affect DLLMain() (as it's not called from within LoadLibrary, etc) and so you can do normal stuff in it. Once the injected DLL and the injecting process are connected via a named pipe you can pass commands and data results back and forth as you like. Since you pass the Init() function a string you can make sure that the named pipe is unique for this particular instance of your injecting process and this particular injected DLL which means you can run multiple instances of the injecting process at the same time and each process can inject into multiple target processes and all of these communication channels are unique and controllable.
You don't have the thread id of a thread in the remote process, because the one you used to load the dll exited when your module was successfully loaded into the address space of your process.
You can easily use the normal interprocess communication methods like named sections/pipes/creating a named window/etc. to communicate with your 'injecting' process.