2009-09-02 15 views
3

J'essaie de comprendre une méthode utilisant la fonction de désassemblage de Reflector. Comme tous les utilisateurs de cet outil le savent, certains codes sont affichés avec des étiquettes C# qui n'ont probablement pas été utilisées dans la source d'origine.D'où viennent les marqueurs Label_ dans Reflector et comment les déchiffrer?

Dans la méthode de ligne 110, je regarde il ya 11 déclarations d'étiquette. Exemples de snippet au hasard:

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; 

Quelle sorte de code fait afficher réflecteur ces étiquettes partout et pourquoi ne peut-il les démonter?

Existe-t-il une bonne technique pour les déchiffrer?

Répondre

3

Vous regardez le code généré par le compilateur. Le compilateur ne vous respecte pas. Pas vraiment. Cela ne me respecte pas non plus, moi ou quelqu'un d'autre. Il regarde notre code, se moque de nous et le réécrit pour fonctionner aussi efficacement que possible. Si les instructions sont imbriquées, la récursivité, le rendement, les instructions de cas et d'autres raccourcis de code entraîneront un code bizarre. Et si vous utilisez des lambdas avec beaucoup d'enceintes, eh bien, ne vous attendez pas à ce qu'il soit joli.

N'importe où, n'importe quelle chance le compilateur peut réécrire votre code pour le faire courir plus vite qu'il le fera. Il n'y a donc pas de "type de code" qui puisse causer cela. Reflector fait de son mieux pour se démonter, mais il ne peut pas deviner le code original de l'auteur à partir de sa version réécrite. Il fait de son mieux (ce qui est parfois même incorrect!) Pour traduire IL en une forme de code acceptable.

Si vous avez du mal à le déchiffrer, vous pouvez éditer manuellement le code pour les goto en ligne qui ne sont appelés qu'une fois et les goto de refactor qui sont appelés plus d'une fois dans les appels de méthode. Une autre alternative est de démonter dans une autre langue. Le code qui traduit IL en langues de niveau supérieur n'est pas le même. Le décompilateur C++/CLI peut faire un meilleur travail pour vous et être toujours assez similaire (trouver/remplacer -> avec.) Pour être compréhensible.

Il n'y a vraiment pas de solution miracle pour cela; au moins pas jusqu'à ce que quelqu'un écrit un meilleur plugin de désassembleur.

7

En fait, le compilateur C# ne fait pas beaucoup d'optimisation - il laisse cela au compilateur JIT (ou ngen). En tant que tel, l'IL qu'il génère est plutôt cohérent et prévisible, ce qui explique pourquoi des outils tels que Reflector sont capables de décompiler IL si efficacement. Une situation où le compilateur transforme votre code est dans une méthode iterator. La méthode que vous regardez contenait probablement quelque chose le long des lignes de:

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

Depuis la transformation iterator peut être assez complexe, réflecteur ne peut pas vraiment faire face. Pour vous familiariser avec ce qu'il faut rechercher, écrivez vos propres méthodes d'itérateur et exécutez-les via Reflector pour voir quel type d'IL est généré en fonction de votre code C#. Ensuite, vous saurez ce qu'il faut rechercher.