typeparam returns remarks net name code c# .net il

remarks - summary returns c#



Ejecutar código.NET IL en C# (1)

¿Hay alguna forma de ejecutar una matriz de códigos IL en C # como los códigos de shell en C / C ++?

Quiero crear un método, convertirlo en código IL, ofuscarlo y almacenarlo en una matriz de bytes y, finalmente, querer ejecutarlo descifrar el contenido de la matriz y ejecutar el código IL.

Por ejemplo, este es mi código C #:

static int MyMethod(string A, int B) { B += 10; if (A.Equals("A")) B = 0; return B; }

Ahora lo convierto a código IL:

private static int MyMethod(string A, int B) { locals: int local_0, bool local_1 /* 0000025C 00 */ nop /* 0000025D 03 */ ldarg_1 // int B /* 0000025E 1F 0A */ ldc_i4_s 10 /* 00000260 58 */ add /* 00000261 10 01 */ starg_s arg_1 // int B /* 00000263 02 */ ldarg_0 // string A /* 00000264 72 01 00 00 70 */ ldstr "A" /* 00000269 6F 11 00 00 0A */ callvirt System.String::Equals(string) // returns bool /* 0000026E 16 */ ldc_i4_0 /* 0000026F FE 01 */ ceq /* 00000271 0B */ stloc_1 // bool local_1 /* 00000272 07 */ ldloc_1 // bool local_1 /* 00000273 2D 03 */ brtrue_s loc_28 /* 00000275 16 */ ldc_i4_0 /* 00000276 10 01 */ starg_s arg_1 // int B loc_28: /* 00000278 03 */ ldarg_1 // int B /* 00000279 0A */ stloc_0 // int local_0 /* 0000027A 2B 00 */ br_s loc_32 loc_32: /* 0000027C 06 */ ldloc_0 // int local_0 /* 0000027D 2A */ ret }

Y, finalmente, esta es una matriz de bytes:

private byte[] ilcode = { 0x00, 0x03, 0x1F, 0x0A, 0x58, 0x10, 0x01, 0x02, 0x72, 0x01, 0x00, 0x00, 0x70, 0x6F, 0x11, 0x00, 0x0, 0x0A, 0x16, 0xFE, 0x01, 0x0B, 0x07, 0x2D, 0x03, 0x16, 0x10, 0x01, 0x03, 0x0A, 0x2B, 0x00, 0x06, 0x2A };


Deberá usar la infraestructura en el espacio de nombres System.Reflection.Emit. Específicamente, debe consultar los docs para MethodBuilder.CreateMethodBody que toma una matriz de bytes que representan las instrucciones de MSIL. Hay un ejemplo completo allí, pero a continuación hay un breve fragmento de su uso. Aquí, también crearé un delegado al método dinámico.

Observaré que esto solo se admite de forma muy limitada, como se indica en los documentos:

Esto actualmente no es totalmente compatible. El usuario no puede proporcionar la ubicación de arreglos de token y controladores de excepciones.

El problema es que los tokens de metadatos utilizados en IL para hacer referencia a tipos, métodos, cadenas literales, etc. se resuelven a nivel de módulo. Por lo tanto, la IL no es completamente portátil en el sentido de que no puede tomar una IL bruta y arbitraria de un método en un módulo y simplemente dejarla caer en otro método en otro módulo. Necesita los tokens de metadatos adecuados en el nuevo módulo. Sin embargo, si sabe que su IL no contiene tokens de metadatos, puede hacerlo, pero esto limita severamente lo que puede hacer con esto. (HT: svick, Simon Svensson)

class Program { static void Main(string[] args) { // opcodes for pushing two arguments to the stack, adding, and returning the result. byte[] ilcodes = { 0x02, 0x03, 0x58, 0x2A }; var method = CreateFromILBytes(ilcodes); Console.WriteLine(method(2, 3)); } private static Func<int, int, int> CreateFromILBytes(byte[] bytes) { var asmName = new AssemblyName("DynamicAssembly"); var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); var module = asmBuilder.DefineDynamicModule("DynamicModule"); var typeBuilder = module.DefineType("DynamicType"); var method = typeBuilder.DefineMethod("DynamicMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(int), typeof(int) }); method.CreateMethodBody(bytes, bytes.Length); var type = typeBuilder.CreateType(); return (Func<int, int, int>)type.GetMethod("DynamicMethod").CreateDelegate(typeof(Func<int, int, int>)); } }

Tenga en cuenta el uso de la opción RunAndSave . Esto guardará el ensamblaje dinámico en el disco en una ubicación temporal. Puede ser más conveniente usar RunAndCollect que generará el ensamblaje solo en la memoria y permitirá que se recopile más tarde cuando todas las referencias al mismo estén muertas. Sin embargo, hay algunas advertencias a los llamados conjuntos de colección, que se detallan here .