c++ - CreateRemoteThread、LoadLibrary 和 PostThreadMessage。什么是正确的 IPC 方法?

标签 c++ winapi dll ipc

好的,我正在使用 CreateRemoteThread/LoadLibrary 将一些代码注入(inject)到另一个进程中“把戏”。

我最终得到了一个线程 ID,以及一个带有我选择的 DLL 的进程。至少在理论上,DLL 目前什么都不做,因此验证这一点有点棘手。目前,我愿意仅凭信念接受它。此外,在我朝这个方向努力之前,需要先回答这个问题。

基本上,您不能在 DllMain 中阻塞。但是,我必须与远程线程通信的只是它的 id。这实际上是在乞求 PostThreadMessage/GetMessage 恶作剧哪个 block 。我可以在 DllMain 中启动另一个线程,但我无法将其 ID 传回创建线程,也无法将另一个线程的 ID 传递给远程线程。

简而言之,如果我在一个进程中创建一个远程线程,我应该如何与原始进程通信?

最佳答案

步骤零;注入(inject)的 DLL 应该有一个入口点,我们称之为 Init()这需要 LPCWSTR作为其单个参数并返回 int ;即与 LoadLibrary() 相同的签名因此作为线程启动函数地址同样有效...

第一步;使用加载库和远程线程注入(inject)。在注入(inject)的 DLL 中不做任何聪明的事情 DLLMain() .存储 HMODULE作为注入(inject)线程的退出代码返回,这是 HMODULE注入(inject)的 DLL 和 LoadLibrary() 的返回值.

注意如果/DYNAMICBASE,这在 x64 上不再是可靠的方法和 ASLR(地址空间布局随机化)被启用为 HMODULE在 x64 上大于 DWORDGetThreadExitCode() 返回的值地址空间的变化意味着 HMODULE 不再可能的值足够小以适合 DWORD .请参阅下面的评论和链接的问题(此处),了解使用共享内存来通信 HMODULE 的变通方法。

第二步;使用 LoadLibrary 将注入(inject)的 DLL 加载到正在进行注入(inject)的进程中。然后找到你的 Init() 的偏移量地址空间中的入口点并从中减去 HMODULE您在地址空间中注入(inject)的 DLL。您现在有了 Init() 的相对偏移量功能。乘坐HMODULE在目标进程中注入(inject)的 DLL(即您在第一步中保存的值)并添加 Init() 的相对地址给它。您现在的地址是 Init()在您的目标流程中。

第三步;调用Init()在目标进程中使用与调用 LoadLibrary() 相同的“远程线程”方法.您可以将字符串传递给 Init() 调用,这可以是您喜欢的任何内容。

我倾向于传递一个唯一的字符串键,我将其用作命名管道名称的一部分。注入(inject)的 DLL 和注入(inject)进程现在都知道命名管道的名称,您可以在它们之间进行通信。 Init()函数不是 DLLMain()并且不受影响 DLLMain() 的限制(因为它不是从 LoadLibrary 中调用的,等等)所以你可以在里面做正常的事情。一旦注入(inject)的 DLL 和注入(inject)进程通过命名管道连接起来,您就可以根据需要来回传递命令和数据结果。由于您通过了 Init() function a string 您可以确保命名管道对于您的注入(inject)进程的这个特定实例和这个特定注入(inject)的 DLL 是唯一的,这意味着您可以同时运行注入(inject)进程的多个实例,并且每个进程可以注入(inject)多个目标进程所有这些沟通 channel 都是唯一且可控的。

关于c++ - CreateRemoteThread、LoadLibrary 和 PostThreadMessage。什么是正确的 IPC 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1162050/

相关文章:

c++ - For循环间隔

c++ - Boost ASIO - 什么是异步

c# - 给定 x,y 点,如何获取前景窗口中不存在的控件的窗口句柄?

winapi - 如何强制 GetQueuedCompletionStatus() 立即返回?

C++ GetProcAddress() 找不到静态类的方法

c++ - 从动态库中调用函数

c++ - 从字符串创建 boost 日期时出现问题

c++ - 如何在编译时确定字节顺序?

c - 未父窗口无法设置HMENU ID?

c# - 如何判断一个DLL是托管程序集还是原生(防止加载原生dll)?