2016-08-03 24 views
1

Aus Neugier entschied ich, den Code meines Projekts zu dekompilieren. Ich nahm die Assembly-DLL-Datei und verwendete ILSpy, um sie zu dekompilieren. Es scheint zu funktionieren, außer IEnumerator<> Methoden.Decompilieren von IEnumerators

[DebuggerHidden] 
private IEnumerator sP() 
{ 
    WaveManager.<sP>c__Iterator7 <sP>c__Iterator = new WaveManager.<sP>c__Iterator7(); 
    <sP>c__Iterator.<>f__this = this; 
    return <sP>c__Iterator; 
} 

Gibt es eine Möglichkeit decompile dass IEnumerator genau:

IEnumerator sP() 
{ 
     for (int i = 0; i < maxEnemies; i++) 
     { 
      var p = Porczaks[Random.Range(0, Porczaks.Length)]; 
      Instantiate(p, new Vector3(Random.Range(245, 360), 16.8f, Random.Range(292, 366)), Quaternion.Euler(0f, Random.Range(0f, 359f), 0f)); 
      yield return new WaitForEndOfFrame(); 
     } 
} 

... wird zum Beispiel in diese decodiert werden?

EDIT: ich die gleiche Anordnung mit dem dotPeek Decompiler dekompiliert, und es erstellt Weise mehr Code. Obwohl ich noch nicht sicher bin, ob Variablen können solche Namen in .net haben:

// Method sP with token 060000AB 
[/*Attribute with token 0C000051*/DebuggerHidden] 
private IEnumerator sP() 
{ 
    WaveManager.\u003CsP\u003Ec__Iterator7 sPCIterator7 = new WaveManager.\u003CsP\u003Ec__Iterator7(); 
    sPCIterator7.\u003C\u003Ef__this = this; 
    return (IEnumerator) sPCIterator7; 
} 

// Type <sP>c__Iterator7 with token 02000031 
[/*Attribute with token 0C000026*/CompilerGenerated] 
private sealed class \u003CsP\u003Ec__Iterator7 : IEnumerator<object>, IEnumerator, IDisposable 
{ 
    // Field <i>__0 with token 040000C7 
    internal int \u003Ci\u003E__0; 
    // Field <p>__1 with token 040000C8 
    internal GameObject \u003Cp\u003E__1; 
    // Field $PC with token 040000C9 
    internal int \u0024PC; 
    // Field $current with token 040000CA 
    internal object \u0024current; 
    // Field <>f__this with token 040000CB 
    internal WaveManager \u003C\u003Ef__this; 

    // Property System.Collections.Generic.IEnumerator<object>.Current with token 17000017 
    object IEnumerator<object>.System\u002ECollections\u002EGeneric\u002EIEnumerator\u003Cobject\u003E\u002ECurrent 
    { 
     // Method System.Collections.Generic.IEnumerator<object>.get_Current with token 060000EA 
     [/*Attribute with token 0C00006E*/DebuggerHidden] get 
     { 
     return this.\u0024current; 
     } 
    } 

    // Property System.Collections.IEnumerator.Current with token 17000018 
    object IEnumerator.Current 
    { 
     // Method System.Collections.IEnumerator.get_Current with token 060000EB 
     [/*Attribute with token 0C00006F*/DebuggerHidden] get 
     { 
     return this.\u0024current; 
     } 
    } 

    // Method .ctor with token 060000E9 
    public \u003CsP\u003Ec__Iterator7() 
    { 
     base.\u002Ector(); 
    } 

    // Method MoveNext with token 060000EC 
    public bool MoveNext() 
    { 
     uint num = (uint) this.\u0024PC; 
     this.\u0024PC = -1; 
     switch (num) 
     { 
     case 0: 
      this.\u003Ci\u003E__0 = 0; 
      break; 
     case 1: 
      this.\u003Ci\u003E__0 = this.\u003Ci\u003E__0 + 1; 
      break; 
     default: 
      return false; 
     } 
     if (this.\u003Ci\u003E__0 < this.\u003C\u003Ef__this.maxEnemies) 
     { 
     this.\u003Cp\u003E__1 = this.\u003C\u003Ef__this.Porczaks[UnityEngine.Random.Range(0, this.\u003C\u003Ef__this.Porczaks.Length)]; 
     UnityEngine.Object.Instantiate((UnityEngine.Object) this.\u003Cp\u003E__1, new Vector3((float) UnityEngine.Random.Range(245, 360), 16.8f, (float) UnityEngine.Random.Range(292, 366)), Quaternion.Euler(0.0f, UnityEngine.Random.Range(0.0f, 359f), 0.0f)); 
     this.\u0024current = (object) new WaitForEndOfFrame(); 
     this.\u0024PC = 1; 
     return true; 
     } 
     this.\u0024PC = -1; 
     goto default; 
    } 

    // Method Dispose with token 060000ED 
    [/*Attribute with token 0C000070*/DebuggerHidden] 
    public void Dispose() 
    { 
     this.\u0024PC = -1; 
    } 

    // Method Reset with token 060000EE 
    [/*Attribute with token 0C000071*/DebuggerHidden] 
    public void Reset() 
    { 
     throw new NotSupportedException(); 
    } 
} 

Scheint dotPeek nicht < und > korrekt war zu verarbeiten, aber ist dieser Code etwas wert?

+0

Das sieht tatsächlich aus, was der Compiler erzeugen würde. – Enigmativity

+0

Having said, dass JetBrains dotPeek scheint hier einen besseren Job zu machen. – Enigmativity

+0

Ich habe dotPeek überprüft und wenn Token deaktiviert sind, sieht es fast genauso aus wie Code von ILSpy, aber mit dieser Funktion wird es wirklich verwirrend. Ich habe den Code im ersten Beitrag gepostet. Macht es irgendeinen Sinn? Würde es funktionieren, wenn ich nur die Namen von ' __ + @! #' Zu etwas Normalem ändere? – Reynevan

Antwort

1

Sie sehen wirklich den Boilerplate-Code, den der Compiler generiert, um die Yield Return-Anweisung zu ersetzen. Und ja, es ist in der Tat eine Staatsmaschine.

Normalerweise sollte ein Decompiler in der Lage sein, den vom Compiler generierten Standardcode zu erkennen und ihn durch die korrekte C# -Anweisung zu ersetzen. Diese Erkennung erfolgt jedoch durch Musterabgleich, d. H. Es wird erwartet, dass der Mustercode auf eine sehr spezifische Weise strukturiert ist. Wenn der Compiler gleichwertigen Code erzeugt, jedoch mit unterschiedlicher Struktur (z. B. aufgrund von Compiler-Upgrades, Optimierungen usw.), kann der Dekompiler das Muster nicht zuordnen und erkennt die Yield-Anweisung nicht.

Sie sollten einen Fehlerbericht an die Decompiler-Teams senden, damit dieser Fehler behoben wird und Sie die Dateien nicht manuell umbenennen müssen. Haben Sie JustDecompile auf dieser Assembly ausprobiert? Scheitert es auch? Wenn ja, könntest du das in den Telerik Foren posten und wir werden uns darum kümmern.

Nebenbei bemerkt, welchen Compiler haben Sie verwendet?