Модификация существующих сборок .NET - PullRequest
14 голосов
/ 24 сентября 2008

Есть ли способ изменить существующие сборки .NET, не прибегая к сторонним инструментам? Я знаю, что PostSharp делает это возможным, но я нахожу невероятно расточительным, что разработчик PostSharp в основном должен был переписать функциональность всего пространства имен System.Reflection, чтобы сделать существующие сборки модифицируемыми.

System.Reflection.Emit позволяет создавать только новые динамические сборки. Однако все используемые здесь классы построителей наследуются от базовых классов отражений (например, TypeBuilder наследуется от System.Type). К сожалению, кажется, нет способа принудительно привести существующий, динамически загружаемый тип в конструктор типов. По крайней мере, нет официального, поддерживаемого способа.

Так как насчет неподдерживаемых? Кто-нибудь знает о бэкдорах, которые позволяют загружать существующие сборки или типы в такие классы компоновщиков?

Имейте в виду, я не ищу способы изменить текущую сборку (этот может даже быть необоснованным запросом), а просто изменяет существующие сборки, загруженные с диска. Боюсь, что такого нет, но я все равно хотел бы спросить.

В худшем случае для дизассемблирования кода придется прибегнуть к ildasm.exe, а для повторной сборки - к ilasm.exe, но в .NET отсутствует набор инструментов (читай: IL reader) для работы с данными IL (или есть?).

/ EDIT:

У меня нет конкретного случая использования. Я просто заинтересован в решении общего назначения, потому что исправление существующих сборок - довольно распространенная задача. Возьмите, например, обфускаторы, или профилировщики, или библиотеки AOP (да, последние могут быть реализованы по-другому). Как я уже сказал, кажется невероятно расточительным переписывать большие части уже существующей инфраструктуры в System.Reflection.


@ Клин:

Ты прав. Однако здесь нет конкретного варианта использования. Я изменил исходный вопрос, чтобы отразить это. Меня заинтересовал еще один вопрос, когда спрашивающий хотел узнать, как он может вводить инструкции pop и ret в конце каждого метода, чтобы не допустить реинжиниринга исходного кода Лутца Родера (VB или C #).

Теперь этот сценарий может быть реализован с помощью ряда инструментов, например, PostSharp, упомянутый выше, и плагин Reflexil для Reflector, который, в свою очередь, использует библиотеку Cecil .

В общем, я просто не удовлетворен .NET Framework.

@ Joel:

Да, я знаю об этом ограничении. В любом случае, спасибо за указание на это, так как это важно.

@ marxidad:

Это кажется единственно возможным подходом. Однако это будет означать, что вам все равно придется воссоздавать полную сборку, используя классы компоновщика, верно? То есть вам придется пройтись по всей сборке вручную.

Хм, я посмотрю на это.

Ответы [ 6 ]

11 голосов
/ 18 декабря 2008

Mono.Cecil также позволяет вам удалить строгое имя из данной сборки и сохранить его как неподписанную сборку. После удаления строгого имени из сборки вы можете просто изменить IL своего целевого метода и использовать сборку так же, как и любую другую сборку. Вот ссылка для удаления строгого имени с помощью Сесила:

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

Как только вы удалите строгое имя, вы можете делать с сборкой все, что захотите. Наслаждайтесь!

10 голосов
/ 24 сентября 2008

Вы можете использовать MethodInfo.GetMethodBody (). GetILAsByteArray () , изменить его и затем подключить обратно в MethodBuilder.CreateMethodBody () .

4 голосов
/ 24 сентября 2008

Было бы полезно, если бы вы могли предоставить более конкретный вариант использования, возможно, есть более эффективные способы решения вашей проблемы, чем эта.

В .NET 3.5 возможно добавлять методы расширения к существующим классам каркаса, возможно, этого достаточно?

3 голосов
/ 24 сентября 2008

Один важный момент: если сборка подписана , любые изменения не удастся, и в итоге вы получите dud.

1 голос
/ 24 сентября 2008

Сборки .NET Framework подписаны, и, как сказал Джоэл Коухорн, вы получите глупость.

0 голосов
/ 24 сентября 2008

Вы можете загрузить сборку с помощью IronRuby и смешать все функции, о которых вы можете мечтать

...