2009-09-02 17 views
3

私はReflectorの逆アセンブリ機能を使ってメソッドを理解しようとしています。このツールを使用する人は誰でも知っているように、特定のコードは元のソースで使用されていない(おそらく)C#ラベルで表示されます。Label_マーカーはReflectorのどこから来たのですか?

私が見ている110行の方法では、というラベルステートメントがあります。ランダムなスニペット例:

Label_0076: 
    if (enumerator.MoveNext()) 
    { 
     goto Label_008F; 
    } 
    if (!base.IsValid) 
    { 
     return; 
    } 
    goto Label_0219; 
Label_0087: 
    num = 0; 
    goto Label_01CB; 
Label_01CB: 
    if (num < entityArray.Length) 
    { 
     goto Label_0194; 
    } 
    goto Label_01AE; 
Label_01F3: 
    num++; 
    goto Label_01CB; 

リフレクターはどこにでもこれらのラベルを表示し、なぜそれがそれらを分解することはできませんになり、コードのどのような?

これらを解読するための優れたテクニックはありますか?

答えて

3

コンパイラによって生成されたコードがあります。コンパイラはあなたを尊重しません。いいえ、本当に。それは私や他の誰も尊重しません。私たちのコードを見て、私たちを嘲笑し、可能な限り効率的に実行するよう書き直します。

ステートメント、再帰、 "yield"、case文、およびその他のコードショートカットが入れ子になっていると、奇妙なコードが返されます。また、たくさんのエンクロージャーを備えたラムダを使用している場合は、それがきれいであるとは思わないでください。

どこでも、コンパイラがコードを書き直してより速く実行できるようにします。したがって、これを引き起こすような「コードの並べ替え」はありません。リフレクターは分解するのに最善を尽くしますが、作者のオリジナルのコードを書き直したバージョンから区別することはできません。 ILを何らかの形で受け入れ可能なコードに変換するのに最適です(時には間違っていることもあります)。

難解なことを解読している場合は、一度呼び出されるだけのインラインgotoと、メソッド呼び出しに複数回呼び出されるリファクタリングgotoを手動で編集することができます。もう1つの選択肢は、別の言語に分解する方法です。 ILを高級言語に翻訳するコードは同じではありません。 C++/CLIデコンパイラはあなたにとってより良い仕事をするかもしれませんが、理解できるようにはまだ似ています(find/replace - > with。)。

本当にこのための銀色の弾丸はありません。誰かがより良い逆アセンブラプラグインを書くまで、少なくとも。

7

実際には、C#コンパイラはほとんどの最適化を行わず、JITコンパイラ(またはngen)に任せます。したがって、生成するILはかなり一貫性があり、予測可能です。そのため、ReflectorのようなツールはILを非常に効果的に逆コンパイルすることができます。コンパイラがコードを変換する1つの状況は、iteratorメソッドです。あなたが見ている方法は、おそらくの線に沿って何か含ま:イテレータ変換はかなり複雑になる可能性があるので

foreach(var x in something) 
    if(x.IsValid) 
    yield return x; 

を、リフレクターは実際にそれに対処することはできません。探しているものに慣れ親しむには、独自のイテレータメソッドを作成し、Reflectorを使用してそれらを実行し、C#コードに基づいてどのような種類のILが生成されるかを確認します。それからあなたは何を探すべきかを知るでしょう。

関連する問題