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

时间:2011-07-08 22:51:11

标签: c++ dll hook

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

3 个答案:

答案 0 :(得分:10)

虽然无法在另一个进程中直接调用函数,但只需几步和Windows API就可以间接地间接调用它。

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

    它可能看起来有点牵扯,但它并不是那么复杂。如果您需要一些帮助,请随时在评论中提问。

答案 1 :(得分:1)

通常,您无法直接调用其他进程中的函数。但是,您可以使用一些变通方法。

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

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

答案 2 :(得分:1)

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

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

但在实施此自定义消息/协议/ IPC机制之前,我建议您首先确定确切的需求。