可能?修改加载的C#DLL?

时间:2011-07-12 22:19:40

标签: c# dll portable-executable

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

如果没有,您认为可以卸载目标DLL,编辑它并重新加载目标DLL吗?系统是否会正确地重新映射其所有值(因为新DLL会因为一些指令而变大)?我有一种感觉,如果可以卸载DLL,编辑它,并将其重新加载到进程中,操作系统应该处理其余的事情。

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

4 个答案:

答案 0 :(得分:2)

是的,这是可能的。

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

请参阅:http://research.microsoft.com/en-us/projects/moles/

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

这是“代码注入”类别。非常有趣的东西。

这在技术上是否覆盖了MSIL?不确定。但是,这种技术会给你相同的最终结果。这就是我们关心的事情吗?

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

我认为没有app-restart的唯一方法就是点击JIT推出的机器代码;但是你真的会有很多乐趣找到你正在寻找的东西,更不用说处理更改的类型以及发生的所有各种JIT优化。然后你必须考虑如何处理动态代码生成(它比你想象的更多)和可以被垃圾收集的动态方法。

您也可以编写自己的.Net主机+ JIT;但后来我怀疑你是否说服任何人明知

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

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

正如其他几个答案所提到的,你通常使用磁盘上的程序集来完成这项工作,并且有很多工具可以做到这一点。

但那么你打算怎么做有名的组装呢?您必须能够使用最初使用的相同强名称密钥对其进行重新签名;不知何故,我怀疑你是否可以访问它。

答案 3 :(得分:0)

  

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

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

  

你认为可以卸载目标DLL,编辑它,   并重新加载目标DLL?

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

修改

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