Modificación de ensamblajes.NET existentes
reflection assemblies (6)
¿Hay alguna forma de modificar ensamblajes .NET existentes sin recurrir a herramientas de terceros? Sé que PostSharp hace esto posible, pero me parece increíblemente derrochador que el desarrollador de PostSharp básicamente tuvo que reescribir la funcionalidad de todo el System.Reflection
nombres de System.Reflection
para poder modificar ensamblajes existentes.
System.Reflection.Emit
solo permite la creación de nuevos ensamblajes dinámicos. Sin embargo, todas las clases de constructores utilizadas aquí heredan de las clases de reflexión básicas (p TypeBuilder
Ej., TypeBuilder
hereda de System.Type
). Desafortunadamente, no parece haber una forma de obligar a un tipo existente cargado dinámicamente en un generador de tipos. Al menos, no hay una forma oficial y compatible.
Entonces, ¿qué hay de no apoyado? ¿Alguien sabe de puertas traseras que permiten cargar ensamblajes o tipos existentes en dichas clases de constructores?
Tenga en cuenta que no estoy buscando formas de modificar el ensamblaje actual (esto incluso puede ser una solicitud irracional) sino simplemente modificar ensamblajes existentes cargados desde el disco. Me temo que no existe tal cosa, pero me gustaría preguntar de todos modos.
En el peor de los casos, uno tendría que recurrir a ildasm.exe
para desensamblar el código y luego a ilasm.exe
para volver a ilasm.exe
pero no hay una cadena de herramientas (leer: lector IL) contenida en .NET para trabajar con datos IL (¿o no? )
/EDITAR:
No tengo un caso de uso específico. Solo me interesa una solución de propósito general porque parchar ensamblajes existentes es una tarea bastante común. Tome ofuscadores por ejemplo, o perfiladores, o librerías AOP (sí, este último puede implementarse de manera diferente). Como ya he dicho, parece increíblemente dispendioso verse obligado a reescribir grandes partes de la infraestructura existente en System.Reflection
.
@Cuña:
Tienes razón. Sin embargo, no hay un caso de uso específico aquí. He modificado la pregunta original para reflejar esto. Mi interés se vio provocado por otra pregunta en la que el autor de la pregunta quería saber cómo podía inyectar las instrucciones pop
y ret
al final de cada método para evitar que el Reflector de Lutz Roeder reiniciara el código fuente (VB o C #).
Ahora, este escenario se puede realizar con varias herramientas, por ejemplo, PostSharp mencionado anteriormente y el complemento Reflexil para Reflector, que, a su vez, usa la biblioteca de Cecil .
En general, simplemente no estoy satisfecho con .NET Framework.
@Joel:
Sí, soy consciente de esta limitación. Gracias de todos modos por señalarlo, ya que es importante.
@marxidad:
Este parece ser el único enfoque factible. Sin embargo, esto significaría que aún tendría que volver a crear el ensamblaje completo utilizando las clases de compilador, ¿verdad? Es decir, tendrías que caminar sobre toda la asamblea manualmente.
Hmm, lo investigaré.
Ayudaría si pudieras proporcionar un caso de uso más específico, probablemente haya mejores formas de solucionar tu problema que esto.
En .NET 3.5, es posible agregar métodos de extensión a las clases de framework existentes, ¿quizás eso es suficiente?
Los ensamblados de .NET Framework están firmados y, al igual que Joel Coehoorn, dijo que no tendrá problemas.
Puede cargar el ensamblaje con IronRuby y mezclar toda la funcionalidad que pueda soñar
Puede usar MethodInfo.GetMethodBody (). GetILAsByteArray () , modificar eso y luego volver a conectarlo a MethodBuilder.CreateMethodBody () .
Un punto importante: si el ensamble está firmado , cualquier cambio fallará y terminará con un fiasco.
Mono.Cecil también le permite eliminar el nombre fuerte de un ensamblaje determinado y guardarlo de nuevo como un ensamblaje sin firmar. Una vez que elimine el nombre fuerte del ensamblaje, puede simplemente modificar el IL de su método objetivo y usar el ensamblaje como lo haría con cualquier otro ensamblaje. Aquí está el enlace para eliminar el nombre fuerte con Cecil:
Una vez que haya eliminado el nombre fuerte, puede hacer prácticamente lo que quiera con el ensamblaje. ¡Disfrutar!