Изменение существующих сборников .NET

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

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

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

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

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

/EDIT:

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


@Wedge:

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

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

В целом, я просто не удовлетворен .NET framework.

@Joel:

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

@marxidad:

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

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

Ответы

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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