Learn · concepts

Was ist ASM (Java-Bytecode)? Bibliotheks-Erklärung

ASM ist eine Java-Bibliothek zum Lesen und Schreiben von JVM-Bytecode zur Laufzeit. Hier ist, was sie tut, wie sie funktioniert und warum Minecraft-Mods darauf angewiesen sind.

TRtrolPublished 4 min read

Was ist ASM in der Minecraft-Modifizierung?

ASM ist eine Java-Bibliothek zum Lesen, Ändern und Schreiben von JVM-Bytecode. Sie arbeitet mit kompilierten .class-Dateien anstelle von Quellcode, sodass sie eine Klasse inspizieren oder umschreiben kann, ohne sie neu kompilieren zu müssen. Minecraft-Mods stützen sich darauf, weil sie es ihnen ermöglichen, das Spiel zur Laufzeit zu patchen, nachdem es bereits kompiliert wurde.

Warum Bytecode-Patching existiert

Das Minecraft-Spiel wird als kompilierter Bytecode und nicht als Quellcode ausgeliefert. Das bedeutet, dass ein Mod-Autor den Quellcode nicht ändern und das gesamte Spiel neu kompilieren kann: der Quellcode existiert nicht. Der einzige Weg, Code zu patchen, den man nicht besitzt, ist, auf Bytecode-Ebene einzugreifen, dem Befehlssatz, den die Java Virtual Machine tatsächlich ausführt. ASM ist das praktische Werkzeug für diese Aufgabe.

Wie ASM funktioniert

ASM wandelt eine kompilierte Klasse in etwas um, das ein Programm bearbeiten kann. Eine .class-Datei ist lediglich Bytecode, die Anweisungen, die die Java Virtual Machine ausführt. ASM analysiert diesen Bytecode, übergibt Ihnen die Methoden und Felder und ermöglicht es Ihnen, Anweisungen hinzuzufügen, zu entfernen oder zu ändern. Anschließend schreibt es eine neue, gültige Klasse zurück.

Reines Java kann dies nicht von selbst. Der Compiler wandelt Ihren Quellcode einmal in Bytecode um, und danach ist der Bytecode fixiert. ASM greift auf Bytecode-Ebene ein, die Schicht unterhalb des Quellcodes liegt, den Sie normalerweise schreiben.

Das Visitor-Muster und die Tree-API

ASM liest eine Klasse mit einem ClassReader und schreibt eine mit einem ClassWriter. Zwischen den beiden durchläuft dein Code die Teile der Klasse und entscheidet, was geändert werden soll. Es gibt zwei Ansätze:

Der Visitor-Ansatz durchläuft die Klasse Element für Element. Er ist schnell und benötigt wenig Speicher, da er die gesamte Klasse nie auf einmal hält. Der Tree-Ansatz lädt die Klasse in Objekte, die du frei durchlaufen und bearbeiten kannst, was für größere Änderungen leichter nachzuvollziehen ist, aber mehr Speicher verbraucht.

AnsatzFunktionsweiseAm besten geeignet für
Visitor APIStreamt Klasse-Ereignisse während des LesensKleine, schnelle Änderungen mit wenig Speicher
Tree APIErstellt ein bearbeitbares Objektmodell der KlasseGrößere oder komplexere Umschreibungen

Warum Minecraft-Mods ASM verwenden

Mods müssen Spielcode ändern, den sie nicht geschrieben haben und nicht neu kompilieren können. Das Spiel wird als kompilierte Klassen ausgeliefert, sodass der einzige Weg hinein auf Bytecode-Ebene führt, und genau das bietet ASM. Ein Mod kann einen Hook in eine Spielmethode einfügen, einen Aufruf umleiten oder ein Feld hinzufügen, alles zur Laufzeit.

Die meisten Modder rufen ASM nicht manuell auf. Sie verwenden Mixin, ein höherwertiges Framework, das auf ASM aufbaut und einfache Annotationen in Bytecode-Änderungen unter der Haube verwandelt. Du schreibst eine kleine Java-Klasse, die die Änderung beschreibt, und das Framework erledigt die Low-Level-Arbeit mit ASM für dich. Insbesondere Fabric-Mods verlassen sich auf diese Kette.

Wann du direkt mit ASM arbeitest

Selten schreibst du als Mod-Autor direkt ASM-Code. Er taucht auf, wenn ein Tool mehr Kontrolle benötigt, als eine Annotation ausdrücken kann, wie beispielsweise ein Loader, ein Obfuskator oder ein Patcher, der Klassen komplett neu schreibt. Für alltägliche Mods reicht die Annotationsschicht darüber aus, und sie ist weitaus weniger fehleranfällig.

Häufig gestellte Fragen