修改现有的.NET程序集
有没有一种方法可以修改现有的.NET程序集,而无需借助第三方工具?我知道PostSharp使这成为可能,但是我发现PostSharp的开发人员基本上不得不重写整个System.Reflection
命名空间的功能以使现有程序集可修改,这实在是非常浪费。
System.Reflection.Emit仅允许创建新的动态程序集。但是,这里使用的所有构建器类都继承自基本反射类(例如,TypeBuilder继承自System.Type)。不幸的是,似乎没有一种方法可以将现有的,动态加载的类型强制转换为类型构建器。至少,没有官方的,受支持的方式。
那么不受支持的情况又如何呢?没有人知道允许将现有程序集或者类型加载到此类构建器类中的后门吗?
注意,我不是在寻找修改当前程序集的方法(这甚至可能是不合理的请求),而只是在修改从光盘加载的现有程序集。我担心没有这种事情,但是我还是想问一下。
在最坏的情况下,人们将不得不诉诸" ildasm.exe"来反汇编代码,然后诉诸于" ilasm.exe"来进行重新组装,但.NET中没有工具链(阅读:IL阅读器)来处理IL数据(还是在那里?)。
/编辑:
我没有特定的用例。我只是对通用解决方案感兴趣,因为修补现有程序集是很常见的任务。以混淆器或者Profiler或者AOP库为例(是的,后者可以以不同的方式实现)。正如我已经说过的,被迫重写System.Reflection中已经存在的基础结构的大部分似乎是非常浪费。
@楔:
你是对的。但是,这里没有特定的用例。我已经修改了原始问题以反映这一点。另一个问题引起了我的兴趣,问问问问者是谁想要知道他如何在每种方法的末尾插入指令pop和ret,以防止Lutz Roeder的Reflector重新设计(VB或者C#)源代码。
现在,可以使用多种工具来实现此方案,例如上面提到的PostSharp和Reflector的Reflexil插件,依次使用Cecil库。
总而言之,我只是对.NET框架不满意。
@Joel:
是的,我知道这个限制。无论如何,感谢我们指出它,因为它很重要。
@marxidad:
这似乎是唯一可行的方法。但是,这意味着我们仍然必须使用builder类来重新创建完整的程序集,对吗? IE。我们将不得不手动遍历整个装配体。
嗯,我会调查一下。
解决方案
如果我们可以提供更具体的用例,这将有所帮助,可能有比此更好的方法来解决问题。
在.NET 3.5中,可以将扩展方法添加到现有框架类中,也许就足够了吗?
我们可以使用IronRuby加载程序集,并混合所有我们梦dream以求的功能
我们可以使用MethodInfo.GetMethodBody()。GetILAsByteArray()进行修改,然后将其重新插入MethodBuilder.CreateMethodBody()。
重要的一点:如果程序集已签名,则任何更改都将失败,并且我们将最终被淘汰。
.NET Framework程序集已签名,就像Joel Coehoorn所说的那样,我们会很无聊。
Mono.Cecil还允许我们从给定的程序集中删除强名称,并将其另存为未签名的程序集。从程序集中删除强名称后,就可以修改目标方法的IL并像使用其他程序集一样使用该程序集。这是使用Cecil删除强名的链接:
http://groups.google.com/group/mono-cecil/browse_thread/thread/3cc4ac0038c99380/b8ee62b03b56715d?lnk=gst&q=strong+named#b8ee62b03b56715d
删除强名后,我们几乎可以对程序集进行任何操作。享受!