IO — Ivan Labs

Disassemblierten Code lesen, wenn du seit Jahren keinen Assembler geschrieben hast

3 Min. Lesezeit
Reverse Engineering

Du musst Assembler nicht aus einem Lehrbuch neu lernen, um produktiv im Lesen von disassembliertem Code zu werden — du musst eine Handvoll wiederkehrender Muster erkennen.

Zuerst dekompilierter Pseudocode, dann roher Assembler

Moderne Tools (Ghidra, IDAs Hex-Rays-Dekompilierer) wandeln Assembler automatisch zurück in C-ähnlichen Pseudocode um. Fang dort an — er ist weit lesbarer als roher Assembler, und für die meisten Analyseaufgaben ist er für sich genommen genau genug.

Wechsle spezifisch zu rohem Assembler, wenn: die Ausgabe des Dekompilierers falsch oder unvollständig aussieht, du exaktes Verhalten auf Anweisungsebene brauchst (Timing, spezifische Registernutzung), oder du es mit stark optimiertem oder verschleiertem Code zu tun hast, bei dem der Dekompilierer Schwierigkeiten hat.

Muster, die es wert sind erkannt, nicht auswendig gelernt zu werden

  • Funktionsprolog/-epilog — eine erkennbare Sequenz am Anfang und Ende der meisten Funktionen, die den Stack-Frame auf- und abbaut. Du wirst dieselbe Form wiederholt sehen; sie zu erkennen sagt dir "hier beginnt/endet eine Funktion", ohne jede Anweisung darin zu verstehen.
  • Vergleiche gefolgt von bedingten Sprüngen — so sieht eine if-Anweisung auf Assembler-Ebene aus. Eine Vergleichsanweisung gefolgt von einem Sprung-wenn-gleich (oder ähnlich) ist die Disassembly-Version einer Verzweigung.
  • Schleifen als Sprung zurück zu einer früheren Adresse — eine Schleife im Quellcode wird auf Assembler-Ebene zu einem Vergleich und einem Sprung zurück zu einem früheren Punkt im Code.
  • String-Referenzen — Dekompilierer und Disassembler zeigen dir normalerweise den tatsächlichen String, auf den ein Codestück verweist (eine Fehlermeldung, eine URL, ein Formatstring). Das ist oft der schnellste Weg, sich in unbekanntem Code zu orientieren — suche nach einem String, den du erkennst, und arbeite von dort aus nach außen.

Eine praktische Lesestrategie

  1. Schau dir zuerst den dekompilierten Pseudocode an, nicht rohen Assembler.
  2. Finde erkennbare Strings und arbeite rückwärts von wo sie referenziert werden — das bringt dich oft schneller zur relevanten Logik als von oben nach unten zu lesen.
  3. Folge Funktionsaufrufen nach außen von einem Einstiegspunkt, statt jede Funktion isoliert zu lesen — Kontext vom Aufrufer klärt oft, was eine Funktion tut, bevor du ihren Körper vollständig gelesen hast.
  4. Vergleiche mit Code, den du selbst geschrieben hast (siehe unseren Einstiegsleitfaden zu Reverse Engineering), wann immer ein Muster unbekannt aussieht — ein minimales Beispiel nachzubauen und es selbst zu kompilieren ist oft schneller, als es nur aus Dokumentation herauszudenken.

Was tatsächlich auswendig gelernt werden muss (eine kurze Liste)

Realistisch nur: wie ein Vergleich-dann-Sprung aussieht, wie ein Funktionsaufruf/-rückgabe aussieht, und wie man eine Schleife erkennt. Alles andere — spezifische Anweisungs-Mnemonics, Register-Konventionen — wirst du allmählich einfach durch wiederholte Exposition aufnehmen, genauso wie das Lesen einer Fremdsprache mit Menge leichter wird statt mit vorherigem Auswendiglernen.

Häufige Fragen

Muss ich Assembler schreiben, um ihn gut zu lesen?

Nein — Lesen und Schreiben sind wirklich unterschiedliche Fähigkeiten, und Reverse Engineering hängt fast ausschließlich von ersterem ab. Du kannst produktiv im Lesen von Disassembly werden, ohne jemals eine Zeile Assembler selbst schreiben zu müssen.

Sollte ich rohen Assembler oder dekompilierten Pseudocode lesen?

Beginne mit dekompiliertem Pseudocode (von Ghidra oder IDAs Hex-Rays), wann immer verfügbar — er ist dramatisch leichter zu lesen und normalerweise genau genug für Analysen. Wechsle zu rohem Assembler, wenn die Ausgabe des Dekompilierers unklar ist oder wenn du genaues Verhalten auf Anweisungsebene verstehen musst, das er abstrahiert.

Was ist der schnellste Weg, sich damit vertraut zu machen?

Kompiliere kleine, bekannte Programme selbst (siehe unseren Einstiegsleitfaden zu Reverse Engineering) und vergleiche deinen Quellcode mit der disassemblierten/dekompilierten Ausgabe nebeneinander — Muster zu erkennen, für die du bereits die Antwort kennst, ist viel schneller, als zu versuchen, unbekannten Code kalt zu durchdenken.

Brauchst du Hilfe dabei?

Melde dich, und ich helfe dir weiter.

Kontaktiere mich

Ähnliche Artikel

Teilen:X / TwitterLinkedIn