2012-02-12 10 views
10

命令をコンパイルして簡単に実行することもできますが、CILを抽出するために私が見つけた唯一の関数はGetILAsByteArrayなので、その名前が示すように、CIL命令ではなくバイトを返します。プログラムで逆アセンブルするCIL

.NET上でCILをプログラムで逆アセンブルするにはどうすればよいですか?

私は人間が読める形式で結果を望んでいないことに注意してください。他のプログラムから生成されたCILを操作するためのメタプログラムを作成したい。

+1

@JohnPalmerが彼の答えで示唆しているように、[Mono.Cecil](http://www.mono-project.com/Cecil)はこのための良いオプションです。 [Here](http://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.html)はILの書き直しについて議論している役に立つブログです。 –

答えて

8

少なくとも一つの.Netプロファイラで使用されていることを知っています第三者のライブラリに依存したくない場合は、自分でバイトの解析を書く必要があります。

配列の構造は、命令を特定する1バイトまたは2バイトがあり、命令のオペランドが続きます(何もない、4バイトのトークンまたは8バイトの数字のいずれかです)。

コードを取得するには、System.Reflection.EmitからOpCodes構造(MSDN)を参照してください。あなたはすべてのフィールドの上に列挙した場合、あなたは非常に簡単にバイトの読み取りのためのルックアップテーブルを構築することができます。

// 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 

code.Valueプロパティを使用すると、コードのbyteまたはint16値をeithre与えます。 code.Sizeプロパティは、これが1または2バイトコードかどうかを示し、OperandTypeプロパティは、コードに続く引数(バイト数と意味はexplained on MSDN)を指定します。 MethodInfoというトークンのようなものをどのように処理する必要があるのか​​覚えていませんが、それを理解することができるでしょう。

9

モノセシルライブラリ - http://www.mono-project.com/Cecilはあなたが必要なものを行う必要があり、私は「あなたは合理的にはるかにちょうどGetILAsByteArrayメソッドからバイト配列を使用して取得することができ、それが

+4

実際に[ILSpy](https://github.com/icsharpcode/ILSpy)に「セシル」が使用されています。 – pad

+0

このブログでは、Cecilを使用してユーザーの行動を達成するための詳細についてhttp://plaureano.blogspot.com/2011/05/introduction-to-il-rewriting-with-cecil.htmlを参照してください。もう一度やろうとする。 –

2

私は​​プロジェクトでいくつかのIL操作を行いました。それはかなり簡単なAPIです。

5

セシルを使用する代わりに、AbsILプロジェクトを復活させることもできます。セシルはよく書かれていてよく使われていますが、F#で書いていると問題に近づく方法はないでしょう。 AbsILはF#と同時に開始されたプロジェクトで、OCamlとF#がILを読み書きできるようになっています。これはF#プロジェクトのように終わりましたが、現在はF#コンパイラのバックエンドになっています。しかし、ILを読み書きするコードはまだ存在しており、理論上はF#コンパイラから分離して、それ自身の権利で使用可能なライブラリにすることができます。 AbsILコードをF#コンパイラの残りの部分から分離することは、まったく簡単なことではありませんが、少し余裕があり、ある程度の決定がある場合は可能です。あなたが本当に勇気があるなら、OCamlにクロスコンパイルして見たいかもしれません。

関連する問題