2012-02-12 16 views
10

Puedo compilar instrucciones para bytecode e incluso ejecutarlas fácilmente pero la única función que he encontrado para extraer CIL es GetILAsByteArray y, como su nombre lo indica, simplemente devuelve bytes y no instrucciones CIL.Desarmar programáticamente CIL

Entonces, ¿cómo desmontar mediante programación CIL en .NET?

Tenga en cuenta que no quiero el resultado en forma legible para los humanos. Quiero escribir metaprogramas para manipular el CIL generado desde otros programas.

+1

Como @JohnPalmer sugiere en su respuesta, [Mono.Cecil] (http://www.mono-project.com/Cecil) es una buena opción para esto. [Aquí] (http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html) es un buen blog sobre la reescritura de IL que podría ser útil. –

Respuesta

8

Usted puede obtener razonablemente lejos sólo el uso de la matriz de bytes de GetILAsByteArray método, pero' Necesitaré escribir el análisis de los bytes usted mismo (si no quiere confiar en la biblioteca de terceros).

La estructura de la matriz es que hay uno o dos bytes que identifican la instrucción seguida de operandos para la instrucción (que no es nada, un token de 4 bytes o un número de 8 bytes).

Para obtener los códigos, puede consultar la estructura OpCodes (MSDN) desde System.Reflection.Emit. Si enumerar sobre todos los campos, se puede construir fácilmente una tabla de consulta para la lectura de los bytes:

// Iterate over all byte codes to build lookup table 
for fld in typeof<OpCodes>.GetFields() do 
    let code = fld.GetValue(null) :?> OpCode 
    printfn "%A (%d + %A)" code.Name code.Size code.OperandType 

La propiedad code.Value le da eithre byte o int16 valor del código. La propiedad code.Size le dice si este es el código de 1 o 2 bytes y la propiedad OperandType especifica qué argumentos siguen al código (el número de bytes y el significado es explained on MSDN). No recuerdo cómo exactamente necesita procesar elementos como tokens que se refieren a, por ejemplo, MethodInfo, pero creo que podrá descifrarlo.

9

El Mono Cecil biblioteca - http://www.mono-project.com/Cecil debería hacer lo que tiene, sé que se utiliza en al menos un generador de perfiles .Net

+4

'Cecil' de hecho se usa en [ILSpy] (https://github.com/icsharpcode/ILSpy). – pad

+0

Es posible que desee consultar este blog publicando http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html para obtener más información sobre el uso de Cecil para lograr lo que desea ' Estoy tratando de hacer. –

2

Hice algunas manipulaciones IL con el proyecto Mono Cecil. Es bastante fácil API.

5

Una alternativa interesante al uso de Cecil sería resucitar el proyecto AbsIL. Cecil está bien escrito y bien utilizado, pero probablemente no sea así como abordarías el problema si lo escribieras en F #. AbsIL fue un proyecto que se inició al mismo tiempo que F # para permitir que OCaml y F # lean y escriban IL, desde entonces se ha tomado como el proyecto F # y ahora es solo el back-end para el compilador F #. Sin embargo, el código para leer y escribir IL todavía está allí y, en teoría, podría separarse del compilador F # y convertirse en biblioteca utilizable por sí solo. Separar el código AbsIL del resto del compilador F # no es completamente trivial, pero debería ser posible si tiene un poco de tiempo libre y una cierta cantidad de determinación. Si te sientes realmente valiente, es posible que también quieras consultar la compilación cruzada de OCaml.

Cuestiones relacionadas