修改現有的 .NET 程序集
有沒有辦法修改現有的 .NET 程序集而不求助於 3rd 方工具?我知道PostSharp使這成為可能,但我發現 PostSharp 的開發人員基本上必須重寫整個
System.Reflection命名空間的功能才能使現有程序集可修改,這非常浪費。
System.Reflection.Emit只允許創建新的動態程序集。但是,這裡使用的所有建構器類都繼承自基本反射類(例如TypeBuilder,繼承自System.Type)。不幸的是,似乎沒有辦法將現有的、動態載入的類型強製到類型建構器中。至少,沒有官方支持的方式。那麼不支持怎麼辦?有誰知道允許將現有程序集或類型載入到此類建構器類中的後門?
請注意,我不是在尋找修改目前程序集的方法(這甚至可能是一個不合理的請求),而只是為了修改從光碟載入的現有程序集。我擔心沒有這樣的事情,但我還是想問一下。
在最壞的情況下,人們不得不求助於
ildasm.exe反彙編程式碼然後ilasm.exe重新組裝,但是.NET 中沒有包含工具鏈(閱讀:IL 閱讀器)來處理 IL 數據(或者是否存在?)。/編輯:
我沒有具體的案例。我只是對通用解決方案感興趣,因為修補現有程序集是一項非常常見的任務。以混淆器、分析器或 AOP 庫為例(是的,後者可以以不同的方式實現)。正如我所說,被迫在
System.Reflection.@楔:
你說得對。但是,這裡沒有特定的案例。我已經修改了原始問題以反映這一點。另一個問題引發了我的興趣,提問者想知道如何在每個方法的末尾註入指令
pop,ret以防止 Lutz Roeder 的 Reflector 重新設計(VB 或 C#)原始碼。現在,這個場景可以通過許多工具來實現,例如上面提到的 PostSharp 和用於 Reflector 的Reflexil外掛,而後者又使用Cecil庫。
總而言之,我只是對 .NET 框架不滿意。
@喬爾:
是的,我知道這個限制。無論如何,感謝您指出它,因為它很重要。
@馬克思达德:
這似乎是唯一可行的方法。但是,這意味著您仍然必須使用建構器類重新創建完整的程序集,對嗎?即,您必須手動遍歷整個組件。
嗯,我會調查的。
您可以使用MethodInfo.GetMethodBody().GetILAsByteArray(),對其進行修改,然後將其重新插入MethodBuilder.CreateMethodBody()。
Mono.Cecil 還允許您從給定程序集中刪除強名稱並將其保存為未簽名程序集。從程序集中刪除強名稱後,您只需修改目標方法的 IL 並像使用任何其他程序集一樣使用該程序集。這是使用 Cecil 刪除強名稱的連結:
<http://groups.google.com/group/mono-cecil/browse_thread/thread/3cc4ac0038c99380/b8ee62b03b56715d?lnk=gst&q=strong+named#b8ee62b03b56715d>
刪除強名稱後,您幾乎可以對程序集做任何您想做的事情。享受!