简体   繁体   English

调用另一个进程加载的 DLL 中的函数

[英]Calling functions in a DLL loaded by another process

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.我有一个 DLL 注入另一个进程,但我希望能够从我的应用程序调用该 DLL 上的导出。 I've read elsewhere that you have to the SendMessage API but I have no idea what to do.我在其他地方读到你必须使用 SendMessage API 但我不知道该怎么做。 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.虽然不可能在另一个进程中直接调用 function,但您可以通过几个步骤和 Windows API 轻松地间接调用。

  1. Get the addresses of LoadLibrary and GetProcAddress from your own process.从自己的进程中获取LoadLibraryGetProcAddress的地址。 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 kernel32.dll应该在每个进程中加载到相同的地址,因此您可以依赖它们存在于您要注入的进程中
  2. 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创建一个struct ,该结构将包含您要传递给 function 的所有 arguments 的结构,该结构将调用另一个进程中的函数(因为CreateRemoteThread只能将一个参数传递给 ZC1C425268E6838A 以传递 414 个指针,所以我们将使用它来传递 414 个指针到结构) 其中至少包含成员 function 指针来保存LoadLibraryGetProcAddress的地址
  3. Allocate enough memory for a struct in the remote process via VirtualAllocEx , then fill it with the correct information with WriteProcessMemory通过VirtualAllocEx为远程进程中的结构分配足够的 memory ,然后使用WriteProcessMemory填充正确的信息
  4. Write a function, taking a pointer to the struct you wrote, that uses LoadLibrary / GetProcAddress to call the function you want.编写一个 function,获取指向您编写的struct的指针,该结构使用LoadLibrary / GetProcAddress调用您想要的 function。 Remember to use the pointers to those functions in the struct you are passing the function, not the names.请记住在传递 function 的结构中使用指向这些函数的指针,而不是名称。
  5. 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在远程进程中分配足够的 memory 以使用VirtualAllocEx保存 function,确保将PAGE_EXECUTE_READWRITE标志传递给VAX ,以便它可以保存可执行代码
  6. Read and write the function's code from your process to the other process via Read/WriteProcessMemory通过Read/WriteProcessMemory从您的进程读取函数代码并将其写入另一个进程
  7. Call the function in the remote process (which is at the address returned by the VirtualAllocEx ) by using CreateRemoteThread .使用CreateRemoteThread在远程进程(位于VirtualAllocEx返回的地址)中调用 function。

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 .确保您传递给 function 的所有数据都存储在结构内和/或驻留在远程进程的地址空间中(使用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.首先,如果您知道导出的地址(很多时候并非如此),并且您调用的 function 使用__stdcall调用约定,将指针大小的 integer 作为参数,并返回一个 DWORD,您可以使用CreateRemoteThread在远程进程的线程中执行它。 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.这通常用于运行LoadLibrary以将 DLL 注入目标进程,因为LoadLibrary在给定计算机上的所有进程上加载到相同地址。

Otherwise, the DLL you inject will need to do some sort of RPC with the process that called it.否则,您注入的 DLL 将需要对调用它的进程执行某种 RPC。 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.例如,您可以让注入的 DLL 在其 DLL_PROCESS_ATTACH 处理程序中生成一个线程,该线程又连接到命名的 pipe,或通过 ZD47C174ED277BDF06CFC72763AB7970 连接到主进程。

SendMessage would need a window handle (hidden or visible), and a message-pump associated with it, that can handle the custom message . SendMessage需要一个 window 句柄(隐藏或可见),以及与之关联的可以处理自定义消息的消息泵。 As with UAC/Windows-7, the integrity levels of applications may prevent other applications to send/post messages from other processes having low integrity.与 UAC/Windows-7 一样,应用程序的完整性级别可能会阻止其他应用程序从其他具有低完整性的进程发送/发布消息。

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).为此,您可以使用管道(命名或未命名)、sockets、邮槽、共享 memory(以及用于触发的互斥锁/事件)。 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.但在实现这种自定义消息/协议/IPC 机制之前,我建议您首先确定确切的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM