2012-02-12 10 views
10

Posso compilare le istruzioni per bytecode e persino eseguirle facilmente, ma l'unica funzione che ho trovato per estrarre CIL è GetILAsByteArray e, come suggerisce il nome, restituisce solo byte e non istruzioni CIL.Smontare programmaticamente CIL

Quindi, come si disattiva a livello di programmazione CIL su .NET?

Nota che non voglio il risultato in forma leggibile. Voglio scrivere metaprogrammi per manipolare il CIL generato da altri programmi.

+1

Come suggerisce @JohnPalmer nella sua risposta, [Mono.Cecil] (http://www.mono-project.com/Cecil) è una buona opzione per questo. [Qui] (http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html) è un buon blog che discute della riscrittura di IL che potrebbe essere utile. –

risposta

8

È possibile ottenere ragionevolmente lontano usando solo l'array di byte da GetILAsByteArray metodo, ma si' Dovrai scrivere da solo l'analisi dei byte (se non vuoi fare affidamento sulla libreria di terze parti).

La struttura della matrice è che ci sono uno o due byte che identificano l'istruzione seguita da operandi per l'istruzione (che è o nulla, qualche token a 4 byte o un numero di 8 byte).

Per ottenere i codici, è possibile esaminare la struttura OpCodes (MSDN) da System.Reflection.Emit. Se si enumerano su tutti i campi, si può facilmente costruire una tabella di ricerca per la lettura dei byte:

// 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 proprietà code.Value dà eithre byte o int16 valore del codice. La proprietà code.Size indica se si tratta di codice a 1 o 2 byte e la proprietà OperandType specifica quali argomenti seguono il codice (il numero di byte e il significato è explained on MSDN). Non ricordo esattamente come è necessario elaborare cose come i token che fanno riferimento a MethodInfo, ma immagino che riuscirai a capirlo!

9

Il Mono Cecil biblioteca - http://www.mono-project.com/Cecil dovrebbe fare quello che ti serve, so che è usato in almeno un profiler Net

+4

'Cecil' è utilizzato in [ILSpy] (https://github.com/icsharpcode/ILSpy). – pad

+0

Si potrebbe voler guardare questo blog postando http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html per un po 'più di informazioni sull'uso di Cecil per realizzare ciò che si' sto cercando di fare. –

2

Ho eseguito alcune manipolazioni IL con il progetto Mono Cecil. È un'API abbastanza facile.

5

Un'alternativa interessante all'utilizzo di Cecil sarebbe quella di resuscitare il progetto AbsIL. Cecil è ben scritto e ben utilizzato, ma probabilmente non è come ti avvicineresti al problema se lo stessi scrivendo in F #. AbsIL era un progetto avviato contemporaneamente a F # per consentire a OCaml e F # di leggere e scrivere IL, da allora è stato preso come dal progetto F # e ora è solo il back-end per il compilatore F #. Tuttavia, il codice per leggere e scrivere IL è ancora lì e in teoria potrebbe essere separato dal compilatore F # e trasformato in libreria utilizzabile a pieno titolo. Separare il codice AbsIL dal resto del compilatore F # non è del tutto banale, ma dovrebbe essere possibile se hai un po 'di tempo libero e una certa dose di determinazione. Se ti senti davvero coraggioso, potresti anche voler guardare a compilarlo su OCaml.

Problemi correlati