480 likes | 569 Views
Bytecodemanipulation. Vortrag im Rahmen des Seminars Generatives Computing 16.06.2004 Ronald Kutschke Daniel Haag Mirko Bleyh Markus Block. [ Einleitung ]. Übersicht. Motivation Classfile Format Java Virtual Machine Möglichkeiten Vor- / Nachteile Beispiel: Framework BCEL
E N D
Bytecodemanipulation Vortrag im Rahmen des Seminars Generatives Computing 16.06.2004 Ronald Kutschke Daniel Haag Mirko Bleyh Markus Block
[ Einleitung ] Übersicht • Motivation • Classfile Format • Java Virtual Machine • Möglichkeiten • Vor- / Nachteile • Beispiel: Framework BCEL • Weitere Anwendungsgebiete • Fazit • Quellen
[ Einleitung ] Motivation Warum Bytecodemanipulation? • Kein Sourcecode vorhanden • Änderung am Bytecode einfacher, als am Sourcecode
[ Classfile Format ] Classfile Format
[ Classfile Format ] Aufbau
[ Classfile Format ] Beispiel (1)
[ Classfile Format ] Beispiel (2)
[ Classfile Format ] Beispiel (3)
[ Classfile Format ] Constantpool (1)
[ Classfile Format ] Constantpool (2)
[ Classfile Format ] Constantpool (3)
[ Classfile Format ] Inhalt Constantpool
[ Classfile Format ] Methodendefinition
[ Classfile Format ] Security class Login{ private String passwort = “xyz“; ... public void login(String eingabe){ if(passwort.equals(eingabe)) { //login durchführen } } ... }
[ Classfile Format ] Optimierung (1)
[ Classfile Format ] Optimierung (2)
[ JVM ] Java Virtual Machine • Zentrales Element der Java Technologie • Verantwortlich für Plattform-Unabhängigkeit • Abstrakte Rechenmaschine mit fester Anzahl an Instruktionen (Opcodes), die auf verschiedenen Speicherbereichen operiert • Kennt keine Java Programmiersprache, lediglich das Bytecode-Format • Kann in Hardware oder in Software realisiert werden
[ JVM ] JVM Details Spezifizierte Aufgaben einer JVM: • Lesen von Bytecode • Ausführen der definierten Operationen • Alles weitere ist dem Entwickler überlassen, also z.B. • Speicheranordnung der Runtime Data Areas • Algorithmus der Garbage-Collection • Ausführungsart der Operationen (Interpretieren oder in nativen Code kompilieren und dann ausführen)
[ JVM ] JVM-Architektur
[ Class Loader ] Motivation • Speicherort der Klassen kann sehr unterschiedlich sein: • Lokales Dateisystem • Entferntes Dateisystem • Datenbank • Internet • Zentraler Punkt zum Laden von Klassen • Erhöhte Sicherheit
[ Class Loader ] Aufgaben Um eine Klasse verwenden zu können, muss Folgendes von der VM bzw. dem Class Loader erledigt werden: • Dynamisches Laden der Klasse: • Finden der binären Repräsentation der Klasse (Bytecode) und erzeugen einer Klasse aus diesem • Linken der Klasse: • Verifizieren • Reservieren und Initialisieren von Speicher für Klassenvariablen • Transformieren von symbolischen Referenzen in direkte Referenzen • Initialisieren der Klasse: • Ausführen der <clinit> Methode der Klasse, Initialisieren der Klassenvariablen
[ Class Loader ] Bootstrap Class Loader Problem: Der Class Loader selber ist auch eine Java Klasse! Wer lädt diesen? • Antwort: • Der Bootstrap Class Loader: • Er ist Teil der JVM • Er ist zumeist in der selben Sprache wie die VM geschrieben • Wird beim Hochfahren der VM geladen • Lädt alle weiteren Class Loader und die Klassen des Java API • Nur vom ihm geladene Klassen werden als vertrauenswürdig eingestuft • JDK1.1: Benötigt unter Windows die CLASSPATH Umgebungsvariable • JDK1.2: System Class Loader durchsucht den CLASSPATH selber
[ Class Loader ] public class SimpleClassLoader extends ClassLoader { public synchronized Class loadClass(String name, boolean resolve) { Class c = findLoadedClass(name); if (c != null) return c; try { c = findSystemClass(name); if (c != null) return c; } catch (ClassNotFoundException e) {} try { RandomAccessFile file = new RandomAccessFile("test/" + name + ".class", "r"); byte data[] = new byte[(int)file.length()]; file.readFully(data); c = defineClass(name, data, 0, data.length); } catch (IOException e) {} if (resolve) resolveClass(c); return c; } }
[ Class Loader ] Parent Delegation Model Bezeichnet die Arbeitsteilung der verschiedenen Class Loader innerhalb einer JVM: • Seit JDK 1.2 vorgeschlagen, bereits in java.lang.ClassLoader realisisert • Jeder Class Loader besitzt Referenz auf Parent (ausser BCL) • Anfrage zum Laden einer Klasse wird immer erst an den Parent weitergegeben • Wenn Parent Klasse nicht finden, versucht es der CL selber
[ JVM ] JVM-Architektur
[ Runtime Data Areas ] • Method Area: • Enthält alle Klassen-Informationen (Name, Superklasse, Constant Pool, Methoden-Informationen und –Bytecode, Exception-Table, Klassenvariablen, etc.) • Gehört logisch zum Heap • Heap: • Hier werden alle Objekt-Instanzen und Array gespeichert (d.h. Objekt-Referenzen zeigen auf Speicherbereiche im Heap): • Instanzvariablen der Klasse des Objekts und aller Superklassen • Zeiger auf den Speicherbereich der Klassendaten in der Method Area • Für alle Threads gemeinsam
[ Runtime Data Areas ] • PC Register: • Jeder Thread hat eigenen PC Register • PC Register ist ein Wort groß • Enthält „Adresse“ (nativer Pointer oder Offset des Bytecodes) der aktuell ausführenden Instruktion bzw. ist undefiniert beim Ausführen von nativem Code • Native Method Stack: • Führt Programm-Code aus, der nicht in Java geschrieben ist • Optional
[ Runtime Data Areas ] • Java Stack: • Jeder Thread hat eigenen Stack • Nur zwei mögliche Operationen: PUSH und POP • Stack besteht aus einzelnen Stack Frames: • zu jeder Methode gibt es einen Frame • immer genau ein Frame ist aktuell (aktuelle Methode) • bei Methodenaufruf wird ein Frame erzeugt und zum neuen aktuelle Frame am Stack (push) • bei Methodenende (return oder Exception) wird der aktuelle Frame verworfen und der vorherige Frame wird zum aktuellen Frame (pop) • ein Thread kann nur auf seinen Stack zugreifen !
[ Runtime Data Areas ] • Lokale Variablen: • Als 0-basiertes Array aus Wörtern organisiert • Enthält Parameter und lokale Variablen der jeweiligen Methode • Stack Frame • Operanden-Stack: • Als 0-basiertes Array aus Wörtern organisiert • Lediglich PUSH und POP erlaubt (keine Indizierung möglich!) • Hauptspeicherort von Operanden für Instruktionen • Frame Daten: • Referenz auf Constant Pool der Klasse der Methode • Daten zur Wiederherstellen des vorherigen Frames bei normalem Methodenende • Exception Behandlung (Referenz auf Exception-Table der Methode) • Weitere Daten...
[ JVM ] JVM-Architektur
[ Execution Engine ] • Abstrakte Spezifikation: • für jede Bytecode Instruktion wird spezifiziert, was gemacht werden soll, aber nicht wie! 3 unterschiedliche Bedeutungen: • Konkrete Implementierung: • Interpretation, JIT-Kompilierung, etc. • Laufzeit-Instanz: • Jeder Thread ist eine Instanz einer Execution Engine
[ Execution Engine ] Implementierungen • Interpretation • sehr einfach (1. Generation der VMs) • Just-in-Time Kompilierung • 1. Ausführung einer Methode → nativer Code • Adaptive Optimierung • Mischung aus Interpretation und JIT Kompilierung • Code-Ausführung wird beobachtet • 80 - 90 % der CPU Zeit → 10 - 20 % des Codes • wird z.B. in Suns HotSpot VM verwendet
[ JVM ] Funktionsweise der JVM Applet Demo...
[ Möglichkeiten ] Möglichkeiten • Einfügen von Debuginformationen • Einfügen von Tracinginformationen • Besseres Handling von NullPointerExceptions • Umbenennen von Variablen- und Methodennamen um Bytecode unleserlich zu machen (Obfuskator) • Einfügen von Code zur Serialisierung (JDO) • Bytecodeoptimierung
[ Vor- / Nachteile ] Vorteile • Sourcecode muss nicht vorliegen • Code kann dynamisch zur Ladezeit verändert werden • Einfügen von fest vorgegebenem Code, der von Programmierern nicht verändert werden kann
[ Vor- / Nachteile ] Nachteile • Aufwändig • Genaue Kenntnis des Classfile-Formats, der Opcodes und der VM sind Voraussetzung • Fehlen von Kommentaren • Fehler erscheinen erst zur Laufzeit
[ BCEL ] Byte Code Engineering Library (BCEL) • Objektorientierte Bearbeitung des prozeduralen Bytecodes • Mappen sämtlicher Opcodes in Java Klassen • Getrennte Packages zum • Analysieren und Inspizieren • Modifizieren und Erzeugen • Manipulation nach der Compile- oder zur Ladezeit • Bytecode Verifier • Disassembler
[ BCEL ] Verwendung von BCEL • Einlesen und parsen des Classfiles -> JavaClass • Auslesen der Klassenparameter (Methoden, Constant Pool, Felder, …) • Generatoren der Klassenparameter erzeugen • Manipulation über die Generator Objekte • Ersetzen der alten Parameter durch die neuen aus den Generatorobjekten • Zurückschreiben des Classfiles auf Festplatte
[ BCEL ] Aufruf von statischen Methoden • Hinzufügen der Methode zum Constant Pool • Sichern der Referenz zur Methode • Parameter auf den Stack legen • Die Methode mit INVOKESTATIC(Methodenref) aufrufen • Rückgabewert liegt nach dem Aufruf auf dem Stack
[ BCEL ] Aufruf von nicht-statischen Methoden • Hinzufügen der Methode zum Constant Pool • Sichern der Referenz zur Methode • Referenz des Methodenobjektes auf den Stack legen • Parameter auf den Stack legen • Die Methode mit INVOKEVIRUTAL(Methodenref) aufrufen • Rückgabewert liegt nach dem Aufruf auf dem Stack
[ BCEL ] Einfügen der Methodenaufrufe • Gewünschte Methode finden • Generator Objekt davon erstellen • Codestelle innerhalb der Methode zum Einfügen finden • Gewünschte Aufrufe einfügen
[ BCEL ] Beispiel • Einfügen von „Hello from „ + Methodensignatur beim Aufruf jeder Methode einer Klasse (nach Compile Time) • Einfügen von Tracing und Logging Informationen beim Aufruf und Verlassen jeder Methode einer Klasse (zur Loading Time)
[ Frameworks ] Weitere Frameworks • BCEL • Jikes Bytecode Toolkit (JikesBT) • Javassist • Ermöglicht abstraktere Bytecode Manipulation über Method.append("System.out.println(\"Test\");");
[ Fazit ] Fazit • Bytecodemanipulation ermöglicht die Erweiterung, Optimierung und Anpassung von Classfiles • Es ersetzt jedoch nicht das herkömmliche Programmieren in Java, da die Komplexität bedeutend höher ist
[ Quellen ] Quellen (1) • Analysis Of The Java Class File (Denis N. Antonioli, Markus Pilz)ftp://ftp.ifi.unizh.ch/pub/techreports/TR-98/ifi-98.04.ps.gz • The JavaTM Virtual Machine Specification Second Edition(Tim Lindholm, Frank Yellin)http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html • Inside the Java 2 Virtual Machine (Bill Venners) + Appletshttp://www.artima.com/insidejvm/appletshttp://www.artima.com/insidejvm/ed2/jvm.html
[ Quellen ] Quellen (2) • Java Programming Dynamics (Dennis M. Sosnoski)http://www-106.ibm.com/developerworks/java/library/j-dyn0429 • BCEL Homepagehttp://jakarta.apache.org/bcel • Beispiele für BCELhttp://bcel.sourceforge.net • Javassist Homepagehttp://www.jboss.org/developers/projects/javassist.html • JikesBT Homepagehttp://www.alphaworks.ibm.com/tech/jikesbt
Kontakt • Ronald Kutschke rk10@hdm-stuttgart.de • Daniel Haag dh12@hdm-stuttgart.de • Mirko Bleyh mb49@hdm-stuttgart.de • Markus Block mb48@hdm-stuttgart.de