【问题标题】:Can I unload a DLL from another process? (Win32)我可以从另一个进程卸载 DLL 吗? (Win32)
【发布时间】:2012-01-12 09:02:31
【问题描述】:

我想从另一个进程卸载 DLL。是否可以? 如果是,该怎么做? (我使用的是 Win32 API)

非常感谢。

【问题讨论】:

  • 因为我想阻止其他进程的DLL执行
  • 执行的不是DLL,而是整个地址空间中的进程本身。 DLL 不是“执行”而是“加载”。
  • 是的,一些线程使用了这个 DLL 中的一些函数,我想阻止它们运行这些函数。 (我想如果我卸载 DLL 可能会崩溃 ^^!)
  • 不要费心尝试这样做。只需终止进程即可。
  • 如果你懂一点汇编程序,你可以修改这个 *.dll 并改变这个函数,让它什么都不做——例如只返回 0。但这需要一些逆向工程知识和良好的调试器(如 ollydbg)。这是一种更安全的方式,不会导致崩溃。甚至可以使用 WriteProcessMemory API 对正在运行的应用程序进行此类修改,但这种方式或其他方式您必须知道要更改什么。

标签: winapi dll


【解决方案1】:

是的,这是可能的。它被称为 DLL 弹出,并且由一些 DLL 注入器提供。 DLL 的加载方式通常是通过LoadLibrary,随后通过FreeLibrary 卸载。 FreeLibrary 只接受一个参数,它是要卸载的模块的句柄。如果您首先注入了 DLL,您应该能够很容易地找到它。否则,可以通过Module32First/Module32Next 进一步枚举来获取句柄,例如CreateToolHelp32Snapshot。假设你已经通过某种方式获得了句柄,那么弹出DLL的步骤就很简单了:

  • GetProcAddress获取FreeLibrary的地址。由于 Windows 的工作方式,此地址将与目标中相同功能的地址匹配。
  • 在目标进程上调用CreateRemoteThread,指定lpStartAddressFreeLibrary的地址,lpParameter为模块句柄

DLL 弹出有几个注意事项。

  • 您应该只弹出一个您确定将来没有代码会再次使用的 DLL。如果任何动态链接代码在释放后尝试调用您的代码,则很可能会触发某种形式的页面访问冲突。
  • 您应该确保在出于类似原因执行弹出时,DLL 的代码中没有线程正在执行。

一般情况下应避免DLL 弹出。如果库想要有被释放的选项,它应该提供一些用户可以访问它的接口,最终调用FreeLibraryAndExitThread

如果您需要一个代码示例,我已经编写了一个喷射器作为我过去用 C 编写的喷射器的一部分。我可以搜索它并找到它,但它是多年前的,代码质量不是可能很好。

【讨论】:

    【解决方案2】:

    你不想这样做。

    “加载”一个 DLL 不仅仅是打开(和锁定)一个文件。当 NT 加载器启动一个可执行文件时,它会(递归地)处理映像引用的所有 DLL 并连接函数调用(递归地):加载 DLL、调用 DLL 初始化代码等。

    卸载 DLL 意味着您需要停止所有加载您的 DLL 的进程,加载新的 DLL,并执行 NT 加载器会执行的所有操作。当然,卸载和重新加载 DLL 需要恢复旧 DLL 的状态(初始化变量等),这是 Win32 中未指定的操作。

    有关背景信息,请参阅此article on MSDN 和此Under the Hood article in MSJ

    【讨论】:

      【解决方案3】:

      简短回答:不,这是不可能的。

      Win32 不提供用于卸载另一个进程的 DLL 的 API。如果库被意外释放,进程将崩溃。这会导致严重的安全漏洞,因为它会破坏进程保护机制。

      如果你可以修改这两个进程,你可以修改应用程序并添加例程来释放一个库,并让另一个应用程序发送消息。

      【讨论】:

        【解决方案4】:

        我希望更改当进程尝试调用该 dll 中的函数时调用的函数。我知道这是可能的理论上

        这意味着一些内存黑客和知道函数指针的存储位置,但是所有这些都可以很容易地找到(ollydbg 设法做到),如果他们使用序数会更难,甚至更难如果他们对指针进行硬编码,但现在没有人这样做。然后,您可以注入自己的代码(理想情况下)模仿它们所掩盖的功能,但实际上并不做任何事情。它们可能必须被注入到进程中,这样你就可以让它在进程不知道的情况下工作,也不会发生任何崩溃。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-08
          • 2017-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-19
          相关资源
          最近更新 更多