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?
问题:
回答1:
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.
回答2:
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
andGetProcAddress
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 (becauseCreateRemoteThread
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 ofLoadLibrary
andGetProcAddress
- Allocate enough memory for a struct in the remote process via
VirtualAllocEx
, then fill it with the correct information withWriteProcessMemory
- Write a function, taking a pointer to the
struct
you wrote, that usesLoadLibrary
/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 passVAX
thePAGE_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 usingCreateRemoteThread
.
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.
回答3:
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.