【问题标题】:Possible? Modify loaded C# DLL?可能的?修改加载的 C# DLL?
【发布时间】:2011-07-12 22:19:40
【问题描述】:

在我开始研究之前,我只是想知道这是否可能。我可以将 C# 代码注入并运行到正在运行的进程中,以及枚举所有加载的 .NET 模块。另外,我可以编辑 .NET DLL 的指令来添加我的方法调用。显然,在加载 DLL 时我无法编辑 DLL,但是当我尝试它时,系统消息告诉我无法编辑它,因为它是在 另一个 进程中加载​​的。这让我相信,如果我在 same 进程中(例如,因为我的注入代码),我可以编辑加载的 DLL。我怀疑这是不对的。

如果没有,您认为是否可以卸载目标 DLL、对其进行编辑并重新加载目标 DLL?系统是否会正确地重新映射其所有值(因为新的 DLL 会大一些指令)?我有一种感觉,如果可以卸载 DLL,对其进行编辑,然后将其重新加载到进程中,那么操作系统应该负责其余的工作。

感谢您的任何见解和反馈。

【问题讨论】:

  • @David,原因有很多:病毒、间谍软件、root 工具包。不要那么封闭!
  • 它也不需要是恶意的;例如,为某事编写一个自定义插件,而不是出于滥用目的,是完全可以的。
  • 监控 C# 代码... =) 此外,许多编译器使用我正在使用的相同 PE API。基本上,我必须记录单个 C# 函数调用。
  • yolksamurai - 为什么不直接使用 VS 工具?或者找人添加一些性能计数器;甚至是他们可以在#debug 构建中调用的日志记录伙伴接口?
  • 问题是我们必须监视数百个 C# 程序集,而编辑此 C# 代码意味着我们必须重新签入每个已编辑文件的源存储库。其中一些 C# 程序集来自多年前。这个项目的基本前提是在不触及当前进程的情况下添加这个新的日志记录功能。

标签: c# dll portable-executable


【解决方案1】:

是的,这是可能的。

“用您自己的委托替换任何 .NET 方法!”

见:http://research.microsoft.com/en-us/projects/moles/

这是视频:http://channel9.msdn.com/blogs/peli/moles-replace-any-net-method-with-a-delegate

这属于“代码注入”类别。很有趣的东西。

这在技术上会覆盖 MSIL 吗?没有把握。但是,此技术将为您提供相同的最终结果。这就是我们关心的对吧?

【讨论】:

    【解决方案2】:

    一旦 .Net DLL 被 CLR 加载到进程中,删除它的唯一方法是卸载所有使用该 DLL 的 AppDomain 实例。所以我想可以通过执行以下操作来编辑加载的 DLL

    1. 卸载所有包含 DLL 的 AppDomain 实例,从而删除 DLL 上的保留
    2. 编辑磁盘上的 DLL 或将更改后的 DLL 放在其他位置
    3. 创建一个新的AppDomain 并加载修改后的DLL

    【讨论】:

      【解决方案3】:

      我认为在不重新启动应用程序的情况下执行此操作的唯一方法可能是点击 JIT 推出的机器代码;但是实际上找到你正在寻找的东西会很有趣,更不用说处理更改的类型以及发生的所有各种 JIT 优化。然后你必须考虑如何处理动态代码生成(比你想象的要多)和可以被垃圾收集的动态方法。

      您不妨编写自己的 .Net 主机 + JIT;但我怀疑你会说服任何人有意运行它。

      您当然不能修改已加载程序集的 IL,因为 .Net 会在加载后对其进行保护。我想有可能一些讨厌的(强调 nasty 那里)完全绕过 .Net 的低级应用程序可能能够破解 IL记忆;但我怀疑加载执行时的内存表示与磁盘上的表示相同;即使到了你已经“破解”它的时候,它也可能已经被 JITted 了,所以你的任何更改都没有任何区别。

      .Net 最终是专门为防止您所说的行为而设计的。您可以将(静态)动态方法附加到现有类型等以受益于可见性(如果您有权限) - 但修改加载的代码?没有。

      正如其他几个答案所提到的,您通常使用磁盘上的程序集来执行此操作,并且有许多工具可以做到这一点。

      但是,对于强名称的程序集,您将如何处理?您必须能够使用与最初使用的相同的强名称密钥对他们进行签名;不知何故,我怀疑您是否可以访问它。

      【讨论】:

      • 我认为你是对的。我应该注意,这段代码不会在任何用户机器上运行(当然,除了我的机器)。它将在通过自动化测试套件的机器上运行。还有其他不太理想的方式来处理这个项目(不太理想,因为不太有用),但看起来这种方式是一条死胡同。感谢您提供所有信息!
      • @yolksamurai - 不幸的是。对于您可能在这里做一些可怕的事情的任何推断,我们深表歉意。实际上,您的场景是一个很常见的场景,无论多么灵活,解决方案总是相同的 - DLL 文件修改。
      【解决方案4】:

      我可以编辑 .NET DLL 的指令来添加我的方法 来电。

      对你有好处!我不知道你是怎么做到的。

      您认为是否可以卸载目标 DLL,对其进行编辑, 并重新加载目标DLL?

      没有。加载的 DLL 无法卸载或重新加载。期间。

      编辑

      我被提醒可以卸载DLL,如果你卸载整个AppDomain。但我相信这不是你想做的。

      【讨论】:

      • 只要从进程中删除所有引用 AppDomains 的 DLL 就可以卸载
      • 是的,我知道。但你说得对,我需要提到 AppDomain。
      • PERWAPI(或 PEWRAPI?)是我目前使用的。似乎没有更好的 API 可用。
      猜你喜欢
      • 2011-04-04
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多