修改现有的.NET程序集

时间:2008-09-23 20:11:23

标签: .net reflection assemblies reflection.emit cil

有没有办法在不使用第三方工具的情况下修改现有的.NET程序集?我知道PostSharp使这成为可能,但我发现PostSharp的开发人员基本上必须重写整个System.Reflection命名空间的功能以使现有的程序集可修改,这令人难以置信地浪费。

System.Reflection.Emit仅允许创建新的动态程序集。但是,此处使用的所有构建器类都继承自基本反射类(例如TypeBuilder继承自System.Type)。不幸的是,似乎没有办法将现有的动态加载类型强制转换为类型构建器。至少,没有正式的,受支持的方式。

那么不支持呢?有没有人知道允许将现有程序集或类型加载到这样的构建器类中的后门程序?

请注意,我正在搜索修改当前程序集的方法(此可能甚至是一个不合理的请求),但只是修改从光盘加载的现有程序集。我担心没有这样的事情,但无论如何我都想问。

在最坏的情况下,人们不得不求助于ildasm.exe来反汇编代码然后再转移到ilasm.exe进行重组,但是.NET中没有工具链(读取:IL读取器)可以使用IL数据(或者存在?)。

/编辑:

我没有具体的用例。我只是对通用解决方案感兴趣,因为修补现有的程序集是一项非常常见的任务。以混淆器为例,或者分析器或AOP库(是的,后者可以以不同方式实现)。正如我所说,被迫重写System.Reflection中现有基础设施的大部分内容似乎非常浪费。


@Wedge:

你是对的。但是,这里没有具体的用例。我修改了原始问题以反映这一点。我的兴趣是由另一个问题引发的,其中提问者想知道如何在每种方法结束时注入指令popret以保持Lutz Roeder的Reflector不再重新设计(VB或C#) )源代码。

现在,可以使用许多工具实现这种情况,例如:上面提到的PostSharp和Reflector的Reflexil插件,反过来,它使用Cecil库。

总而言之,我对.NET框架不满意。

@Joel:

是的,我知道这个限制。非常感谢你指出它,因为它很重要。

@marxidad:

这似乎是唯一可行的方法。但是,这意味着您仍然需要使用构建器类重新创建完整的程序集,对吧?即你必须手动遍历整个组件。

嗯,我会调查一下。

6 个答案:

答案 0 :(得分:11)

Mono.Cecil还允许您从给定程序集中删除强名称,并将其另存为无符号程序集。从程序集中删除强名称后,只需修改目标方法的IL并像使用任何其他程序集一样使用程序集。以下是使用Cecil删除强名称的链接:

http://groups.google.com/group/mono-cecil/browse_thread/thread/3cc4ac0038c99380/b8ee62b03b56715d?lnk=gst&q=strong+named#b8ee62b03b56715d

一旦你删除了强名称,你就可以随心所欲地使用程序集。享受!

答案 1 :(得分:10)

您可以使用 MethodInfo.GetMethodBody()。GetILAsByteArray(),修改它,然后将其重新插入 MethodBuilder.CreateMethodBody()

答案 2 :(得分:4)

如果你能提供一个更具体的用例会有所帮助,可能有更好的方法来解决你的问题。

在.NET 3.5中,可以向现有框架类添加扩展方法,这可能就足够了吗?

答案 3 :(得分:3)

重要的一点是:如果程序集是签名,任何更改都将失败,您将最终得到一个哑弹。

答案 4 :(得分:1)

.NET Framework程序集已签名,就像Joel Coehoorn说你会得到一个哑弹一样。

答案 5 :(得分:-3)

您可以使用IronRuby加载程序集,并混合您梦寐以求的所有功能