【问题标题】:How to share a process?如何共享一个进程?
【发布时间】:2010-06-07 01:58:51
【问题描述】:

我怎样才能进入另一个进程?喜欢,共享另一个进程的名称?因此,如果我的应用程序是 griddemo.exe,并且我想嵌入到 explorer.exe,这可能吗?只需从 kernel32 中阅读有关 CreateRemoteThread() 的内容。这是在正确的方向吗?会有安全/UAC 问题吗?

【问题讨论】:

  • 您不必在标题中包含标签。这就是标签的用途。
  • 您想让您的代码在另一个进程中执行,该进程不知道该进程吗?有一个比“依偎”更常见的术语。我相信这个词是“病毒”。

标签: c# winapi processor


【解决方案1】:

首先很抱歉,但我的答案会更长。

多年来,我在不同版本的操作系统(从 Windows NT 4.0 到 Windows 7)中使用 DLL 注入,并且我对任何病毒扫描程序(包括不同版本的 Norton 和 McAfee)都没有任何问题。所以我在这方面不同意 Stephen Cleary(见他的回答)。

CreateRemoteThread() 的使用实际上只是其中一种方式。 AppInit_DLLs 是另一种方式。两者都有其优点和缺点。 AppInit_DLLs 的主要优点是在任何进程中注入 DLL 的简单性。 AppInit_DLLs 方法的主要缺点如下:

  1. 所有 GUI 应用程序都会加载 DLL。如果您只想在 explorer.exe 这样的一个进程中加载​​它,则不能这样做。所以你的DLL会增加所有GUI进程的工作空间。您的 DLL 中的错误(尤其是在 DllMain 内部或您的 DLL 的任何依赖 DLL 中)可能会导致您当前不知道的许多进程崩溃。
  2. 您不能在控制台应用程序或任何不依赖于 User32.dll 的 EXE 中注入有关 AppInit_DLLs 方法的 DLL。
  3. 你应该非常小心你的DllMain,因为它会被调用之前 User32.dll 将被完全初始化。因此,您可以在 DLL 的DllMain 内部使用的安全 DLL 是 Kernel32.dll。

关于CreateRemoteThread(),可以在进程中启动一个额外的线程。 CreateRemoteThread() 的主要问题是它的lpStartAddress 参数必须是来自远程进程的地址。所以必须使用函数OpenProcessVirtualAllocExWriteProcessMemory 将一些信息写入目标进程的内存。为了能够打开一个进程,必须启用调试权限。如果您只想在目标进程中执行 2 + 2,您可以将相应的二进制代码直接复制到目标进程中。所有真正有趣的工作都可以通过使用一些 Windows API 来完成。所以大多数人不复制代码。而不是在目标进程内部调用LoadLibrary("MyPath\\MyDll.dll")。因为LoadLibrary 的原型与CreateThreadThreadProc 的原型相同,所以您可以将LoadLibrary 称为ThreadProcCreateRemoteThread()。这种方式的名称为DLL Injection

我建议您仅在确实需要时才使用此 DLL 注入。如果您的目标应用程序有其他方式(例如插件)在进程中加载​​您的 DLL,您应该使用这种方式而不是 DLL 注入。

在获得 DLL 注入的工作示例后,您必须解决一些一般性问题。这个问题你第一次看是看不到的,但是在你的应用程序长期使用之后你会发现它的重要性:

  1. 您应该找到目标进程已经在运行的时刻,然后才能使用CreateRemoteThread()
  2. 在调用CreateRemoteThread() 之前,目标应用程序必须已经初始化。所以你不应该过早使用CreateRemoteThread()。在 explorer.exe 的情况下,您可以使用从运行注册表项启动您的小型触发器程序。目前 explorer.exe 已为 DLL 注入做好充分准备。
  3. 您应该考虑 64 位版本的 Windows。
  4. 不要忘记目标进程内部的 DLL 重定位。请注意,您的 DLL 可以像在您的进程中一样被加载到另一个地址的目标进程中。大多数情况下,为您将注入的 DLL 选择一个好的基地址(链接器选项)是一个好主意。 Kernel32.dll 有时(很少)会加载到源进程中的其他地址。您可以创建一个没有此问题的 DLL 注入代码。
  5. 终端服务通过设计隔离每个终端会话。因此,如果目标进程与调用进程处于不同的会话中,CreateRemoteThread 将失败。如果您尝试从 Windows 服务进行 DLL 注入,您可以在 XP(未连接到域)或 Vista 或 Windows 7 上看到该问题。要解决此问题,您应该从与目标进程在同一终端会话上运行的进程进行 DLL 注入,或者您必须在使用 CreateRemoteThread 之前切换当前会话。您的进程必须启用SE_TCB_NAME 权限并使用SetTokenInformationTokenSessionId 参数。要获取目标进程的会话 ID,您可以使用不同的方法。带有 WTS 前缀的函数(如 WTSGetActiveConsoleSessionId)非常有用。

所以一切都不是很容易,但这是一个非常有趣的主题,你可以在其中学习很多关于操作系统的东西。您应该只花一点时间来分析您的问题以及解决问题的不同方法,然后再选择一种符合您项目要求的方法并开始编程。

【讨论】:

  • @JBRWilkinson:你在 ASLR 下是什么意思? DLL 重定位或 Kernel32.dll 重定位或其他问题?
  • @JBRWilkinson:如果您的意思是地址空间布局随机化,那绝对是其他技术。我的意思是仅使用您编译的 DLL 的链接器的 /base 开关和良好的 DLL 注入代码,如果目标进程将 Kernel32.dll 作为源进程加载到另一个地方,它们也可以工作。如果不使用 /base 开关,您的 DLL 可以在几乎加载期间重新定位,并且会根据需要占用更多内存(将消耗内存)。
【解决方案2】:

DLL 注入是执行此操作的传统方法。这很棘手,尤其是因为病毒扫描程序对这种做法持怀疑态度。因此,即使您让它正常工作,Norton/McAfee 也可能会阻止您 - 或在未来阻止您。

DLL 注入的一种简单方法是AppInit_DLLs registry value。请注意,Microsoft 保留了简单地删除此功能的权利(将来可能会这样做)。

Microsoft 批准的实现 DLL 注入的方法是许可 Microsoft Detours

请注意,您的 DLL 必须针对 CLR 4.0 或更高版本构建才能安全地执行 DLL 注入,因为这是第一个支持并行进程的版本。

【讨论】:

    【解决方案3】:

    如果您的意思是将代码注入另一个进程,那么 dll 注入是一种技术:

    http://en.wikipedia.org/wiki/DLL_injection

    多年来一直没有这样做,所以不确定现代 MS Windows 操作系统(即 XP 后)会对此有多满意。

    【讨论】:

      【解决方案4】:

      我最近没有尝试过,但另一种方法是创建一个 Hook DLL:

      1. 创建一个包含像MessageProc这样的挂钩过程的DLL。

      2. 将此 DLL 安装到 Windows\System32。

      3. 使用 FindWindows(Ex) 定位受害者进程的窗口。

      4. 使用GetWindowThreadProcessId() 查找该窗口的所属线程。这是必要的,以避免将您的 DLL 注入系统上的每个进程。

      5. 使用SetWindowsHookEx 钩住该线程。

      6. PostMessage 将 WM_USER 消息发送到窗口 - 如果 Hook DLL 尚未激活,则激活它。

      如果您不是具有足够特权的用户,这可能会调用新的Windows Vista/7 UIPI/UAC,但这取决于许多因素 - 您的里程可能会有所不同。

      【讨论】:

        猜你喜欢
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        • 2014-09-21
        • 1970-01-01
        • 2018-06-09
        • 1970-01-01
        • 2012-12-15
        • 2012-07-21
        相关资源
        最近更新 更多