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

Calling functions in a DLL loaded by another process

本文关键字:DLL 函数 加载 另一个 进程 调用      更新时间:2023-10-16

我有一个DLL,我注入到另一个进程,但我希望能够从我的应用程序调用该DLL上的导出。我在其他地方读到,你必须SendMessage API,但我不知道该怎么做。有关于如何做到这一点的任何示例代码吗?

虽然不可能直接在另一个进程中调用函数,但您可以通过几个步骤和Windows API轻松地间接调用。

  1. 从自己的进程中获取LoadLibraryGetProcAddress的地址。kernel32.dll应该在每个进程中加载在相同的地址,所以你可以依赖它们存在于你注入
  2. 的进程中。
  3. 创建一个struct,它将保存你想传递给函数的所有参数,这些参数将在其他进程中调用函数(因为CreateRemoteThread只能传递一个参数给函数,所以我们将使用它来传递一个指向结构的指针),至少包含成员函数指针来保存LoadLibraryGetProcAddress的地址
  4. 通过VirtualAllocEx为远程进程中的struct分配足够的内存,然后用WriteProcessMemory填充正确的信息。
  5. 写一个函数,带一个指向你写的struct的指针,使用LoadLibrary/GetProcAddress来调用你想要的函数。记住要使用指针指向要传递给函数的结构体中的那些函数,而不是函数名。
  6. 在远程进程中分配足够的内存来保存VirtualAllocEx的函数,确保将PAGE_EXECUTE_READWRITE标志传递给VAX,以便它可以保存可执行代码
  7. 通过Read/WriteProcessMemory从你的进程读取和写入函数代码到另一个进程
  8. 使用CreateRemoteThread在远程进程中调用函数(在VirtualAllocEx返回的地址上)

确保传递给函数的所有数据要么存储在结构体中,要么驻留在远程进程的地址空间中(通过VirtualAllocEx/WriteProcessMemory获取)。

它可能看起来有点复杂,但它并没有那么复杂。如果你需要帮助,请在评论中提问。

一般来说,您不能直接在另一个进程中调用函数。但是,您可以使用一些变通方法。

首先,如果您知道导出的地址(很多时候不是这样),并且您调用的函数使用__stdcall调用约定,接受一个指针大小的整数作为参数,并返回一个DWORD,那么您可以使用CreateRemoteThread在远程进程的线程中执行它。这通常用于运行LoadLibrary将DLL注入到目标进程中,因为LoadLibrary在给定计算机上的所有进程上加载在相同的地址。

否则,您注入的DLL将需要与调用它的进程进行某种RPC。例如,您可以让注入的DLL在其DLL_PROCESS_ATTACH处理程序中生成一个线程,该线程依次连接到命名管道,或通过COM或其他方式连接到主进程。

SendMessage将需要一个窗口句柄(隐藏或可见),以及与之关联的消息泵,它可以处理自定义消息。与UAC/Windows-7一样,应用程序的完整性级别可能会阻止其他应用程序从具有低完整性的其他进程发送/发布消息。

最好有另一个线程等待这些自定义消息。为此,您可以使用管道(已命名或未命名)、套接字、邮件槽、共享内存(以及用于触发的互斥锁/事件)。其他进程将使用相同的协议发送消息。

但是在实现这个自定义消息传递/协议/IPC机制之前,我建议您首先确定确切的需求。