好吧,我注入一些代码,使用另一个进程远程线程/调用LoadLibrary “猫腻”。
我结束了一个线程ID,并与我的选择的DLL旋转起来的过程。 至少在理论上,DLL什么事情都不做,以便确认这是一个有点棘手的时刻。 暂时我愿意独自接受它的信仰。 此外,需要这个要回答的问题之前,我推到硬这个方向发展。
基本上,你不能在DllMain中阻塞。 然而,我的一切通讯与远程线程是其ID。 这几乎乞求PostThreadMessage /有心计的GetMessage哪一个块。 我可以旋转起来另一个线程DllMain中,但我没有传达其ID回创建线程的方式,并没有经过另一个线程的ID到一台远程的方式。
概括地说,如果我在一个进程中创建远程线程我应该如何与原有工艺进行通信?
步骤零; 注入DLL应该有一个切入点,让我们把它Init()
采用一个LPCWSTR
作为其唯一的参数,返回一个int
; 即相同的签名LoadLibrary()
因此同样作为一个线程启动函数地址有效...
第一步; 注入使用加载库和远程线程。 什么都不做在注入的DLL聪明DLLMain()
存储HMODULE
被返回注入线程的退出代码,这是HMODULE
注入DLL和返回值LoadLibrary()
请注意 ,这不再是在x64的可靠方法,如果/DYNAMICBASE
和ASLR(地址空间布局随机化)作为启用HMODULE
在x64上是比较大的DWORD
从返回的值GetThreadExitCode()
和地址空间的变化意味着它不再作为可能是HMODULE
的值是小到足以进入DWORD
。 看到周围使用共享内存进行通信的下面工作的评论和链接的问题(在这里) HMODULE
第二步; 加载利用的LoadLibrary到被操作的方式注入的过程中注入的DLL。 然后找到你的偏移Init()
在你的地址空间的入口点,并从中减去HMODULE
你注入DLL的地址空间。 您现在有相对偏移Init()
函数。 就拿HMODULE
在目标进程注入DLL(即你在第一步中保存的值),并添加的相对地址Init()
它。 你现在有地址Init()
在你的目标进程。
第三步; 调用Init()
就是用于调用相同的“远程线程”的方式在目标进程LoadLibrary()
您可以将字符串传递到Init()调用,这可以是任何你喜欢的。
我倾向于做的就是通过我作为一个命名管道名称的一部分使用一个唯一的字符串键。 注入DLL,并注入进程现在都知道命名管道的名字,你可以在它们之间进行通信。 在Init()
函数没有DLLMain()
并且不会影响限制遭受DLLMain()
因为它没有从内部被称为LoadLibrary
等),所以你可以在它做正常的东西。 一旦注入DLL和注入过程经由命名管道连接,只要你喜欢你可以传递命令和数据的结果来回。 既然你传递Init()
函数的字符串,你可以确保命名管道是您注射过程的这种特定情况下,这尤其是注入DLL,这意味着你可以在同一时间运行注入进程的多个实例,且每个独特过程可以注入到多个目标过程和所有这些通信信道是唯一的和可控制的。
您不必在远程进程中的线程的线程ID,因为当你的模块已成功加载到进程的地址空间,您来加载DLL的一个退出。
您可以轻松地使用正常的进程间通信的方法,如命名段/管/创建一个名为窗/等。 与你的“注射”的过程进行通信。
文章来源: CreateRemoteThread, LoadLibrary, and PostThreadMessage. What's the proper IPC method?