Erzeugen und Testen von Dalvik-Bytecode für Android

Größe: px
Ab Seite anzeigen:

Download "Erzeugen und Testen von Dalvik-Bytecode für Android"

Transkript

1 Erzeugen und Testen von Dalvik-Bytecode für Android Generating and testing Dalvik bytecode for Android Master-Thesis von Thomas Pilot Januar 2013 SECURE SOFTWARE ENGINEERING GROUP

2 Erzeugen und Testen von Dalvik-Bytecode für Android Generating and testing Dalvik bytecode for Android Vorgelegte Master-Thesis von Thomas Pilot Prüfer: Eric Bodden, Ph.D. Betreuer: Eric Bodden, Ph.D. Tag der Einreichung:

3 Erklärung zur Master-Thesis Hiermit versichere ich nach Paragraph 22 Absatz 7 der Allgemeinen Prüfungsbestimmungen der TU Darmstadt vom 18. Juli 2012, die vorliegende Master- Thesis ohne Hilfe Dritter nur mit den angegebenen Quellen und Hilfsmitteln angefertigt zu haben. Alle Stellen, die aus Quellen entnommen wurden, sind als solche kenntlich gemacht. Diese Arbeit hat in gleicher oder ähnlicher Form noch keiner Prüfungsbehörde vorgelegen. Die Übereinstimmung von schriftlicher und elektronischer Fassung wird bestätigt. Darmstadt, den 18. Januar 2013 (Thomas Pilot)

4 Zusammenfassung Seit seiner Entstehung im Jahr 2008 hat der Marktanteil der Android-Platform auf Smartphones kontinuierlich zugenommen, drei von vier verkauften Geräten laufen unter dieser Platform. Auf diesen Smartphones sammeln sich eine Vielzahl sicherheitssensitiver Daten an, sowohl privater als auch geschäftlicher Natur. Dadurch ist die Platform ein lohnenswertes Ziel von Angreifern und sollte entsprechend überprüft werden. Neben dem zugrundeliegenden Linux-Kernel ist bei einer Sicherheitsanalyse die Android- Laufzeitumgebung von Bedeutung. Diese basiert auf der Dalvik genannten virtuellen Maschine, für die keine Werkzeuge zur umfassenden Analyse und Veränderung des Codes zur Verfügung stehen, anders als etwa für die Java Virtual Machine (JVM). In dieser Arbeit stellen wir einen neuen Ansatz vor, wie Dalvik-Bytecode mithilfe des Java- Analyse-Frameworks Soot erzeugt werden kann. Dadurch können etwa bestehende Android- Programme so verändert werden, dass sie zur Laufzeit überwacht werden. In der Arbeit gehen wir auf die Besonderheiten der registerbasierten virtuellen Maschine sowie die spezifischen Design-Ziele bei der Bytecode-Erzeugung ein. Außerdem beschreiben wir prototypisch, wie dieser Ansatz mithilfe des sogenannten Fuzz-Testings auf Implementierungsfehler getestet werden kann. Diese Methode ist auch für eine spätere Sicherheitsanalyse der Dalvik Virtual Machine selbst nützlich. Abstract Since it s initial release in 2008 the Android platform s market share for smartphones increased continuously: three out of four sold devices run on the Android platform. A multitude of security-sensitive data is accumulated on these smartphones, the data being personal or related to business. The platform therefore is a valuable target for attackers and should be inspected accordingly. Conducting a security analysis, one has to take into account the underlying Linux kernel and the new Android runtime environment. The latter is based on a virtual machine called Dalvik, for which there are no tools for analysis or code transformation, unlike for the Java Virtual Machine. In this work we present a novel approach to generate Dalvik bytecode by using the analysis framework Soot for Java. With the approach existing Android programs can be changed to being monitored at runtime, for instance. We explain the virtual machine s register-based characteristics and the specific design goals for the bytecode generation. In addition we present a prototype method to test our implementation with so called fuzz testing. This method is also useful for a security analysis of the Dalvik Virtual Machine itself.

5 Inhaltsverzeichnis 1 Einleitung Motivation Beiträge und Struktur dieser Arbeit Der Bytecode im Kontext Die Android-Platform Das Dex-Format Soot und Jimple Fuzzing als Testansatz Design Implementierung Benötigte Register einer Methode Exception-Handler Umwandlung von Jimple-Statements Umwandlung von Jimple-Ausdrücken Besonderheiten von Dex-Instruktionen Abschließende Arbeiten Unbenutzte Opcodes Testansatz Ablauf des Testens App-Installation und Code-Verifizierung App-Ausführung Evaluation Auswirkungen der App-Konvertierung Gefundene Fehler Grenzen der Methodik Abschluss Verwandte Arbeiten Offene Aufgaben Zusammenfassung Abkürzungsverzeichnis 27 Literaturverzeichnis 28 3

6 1 Einleitung 1.1 Motivation Laut dem Marktforschungsunternehmen IDC ist die Android-Platform mittlerweile auf drei von vier neu verkauften Smartphones zu finden [Cor12]. Auf diesen Geräten sammeln sich eine Vielzahl sicherheits-sensitiver Daten an, sowohl privater als auch geschäftlicher Natur. Dadurch ist die Platform ein lohnenswertes Ziel von Angreifern und sollte entsprechend überprüft werden. Android wurde in einer ersten Version im Jahr 2008 veröffentlicht, basiert aber auf dem etablierten Linux-Kernel mit seinem Dateirechte-System, der Prozess-Isolierung und sicherer Interprozess-Kommunikation [And12]. Neu ist hingegen die Dalvik genannte virtuelle Maschine, die neben einiger Bibliotheken die Laufzeitumgebung des Systems darstellt. Die Dalvik Virtual Machine (DVM) ist an die JVM angelehnt, hat aber ein eigenes Bytecode-Format und ist auf die begrenzten Ressourcen einer Smartphone-Umgebung angepasst. So läuft jedes Android- Programm wie bei Java in einer eigenen virtuellen Maschine, die Initialisierung einer solchen geht jedoch schneller vonstatten. Außerdem ist der Dalvik-Bytecode näher an realen Maschinen orientiert und arbeitet nicht auf einem Stack, sondern auf Registern. Bisher existieren kaum Studien, die die Sicherheit der Android-Platform auf Bytecode-Ebene untersuchen. Meist wurden höhere Stufen wie die der Zugriffsrechte (Permissions) bei Apps betrachtet. Andererseits existiert in der DVM-Implementierung von Google ein Verifier, der den Bytecode einer App bei der Installation und vor dem ersten Start analysiert. Ein potenzieller Angreifer auf dieser Ebene müsste deshalb Bytecode erzeugen, den der Verifier als gültig akzeptiert. Neben diesen statischen Analysen sind auch zunehmend solche zur Laufzeit von Bedeutung. Literatur zu dynamischen Analysen der DVM, wie sie in einer Java-Umgebung per Bytecode-Instrumentierung durchaus üblich sind, ist uns nicht bekannt. Es mangelt letztlich an spezifischen Werkzeugen, Dalvik-Bytecode zu generieren und die DVM zu testen. 1.2 Beiträge und Struktur dieser Arbeit Diese Arbeit beinhaltet zwei Beiträge im Bereich DVM und Dalvik-Bytecode: Zum einen stellen wir einen neuen Ansatz vor, Dalvik-Bytecode zu generieren. Dieser benutzt ein Analyse- Framework, das den Bytecode bereits in eine Zwischendarstellung einlesen kann. Somit wird es möglich, eingelesene Apps verändert wieder herauszuschreiben oder neue Programme zu erzeugen. Zum anderen beschreiben wir, wie dieser Ansatz automatisiert auf Implementierungsfehler getestet werden kann. Dies geschieht, indem eingelesene Android-Apps ohne explizite Veränderung wieder generiert werden und auf einem Emulator kontrolliert gestartet werden. Da aus der Zwischendarstellung leicht ungewöhnlicher Dalvik-Code erzeugt werden kann, eignet sich diese Methode auch für eine spätere Sicherheitsanalyse der DVM und des oben genannten Verifiers selbst. Der Rest der Arbeit ist wie folgt aufgebaut: Diese Einleitung führt noch kurz in die Architektur der Android-Platform und des Dalvik-Formates ein, gibt einen Überblick zum Analyse- Framework sowie der Zwischendarstellung und schließt mit einer allgemeinen Beschreibung des Fuzz-Testings. In Kapitel 2 beschreiben wir im Detail das Design der Implementierung und den Testansatz. In Kapitel 3 wird dieser Testansatz mit auf dem Markt vorhandenen Apps benutzt, um Implementierungsfehler zu finden und um die Grenzen dieser Methodik aufzuzeigen. Kapitel 4 schließt die Arbeit ab, indem verwandte Arbeiten und offene Aufgaben aufgeführt werden und eine Zusammenfassung gegeben wird. 4

7 1.3 Der Bytecode im Kontext Zum besseren Verständnis des Bytecodes selbst lohnt sich ein Blick auf die Umgebung, in der er vorkommt. Dazu gehört die ausführende Platform sowie das Dateiformat, in dem der Bytecode abgelegt ist Die Android-Platform Die grundlegende Architektur der Android-Platform ist in Abbildung 1 auf Seite 5 zu sehen. Apps Application Framework Activity Manager Window Manager View-System... Laufzeitumgebung Bibliotheken Dalvik VM Core Libraries libc SSL Webkit... Linux-Kernel Abbildung 1: Architektur der Android-Platform Die Platform kommuniziert durch einen Linux-Kernel mit der darunterliegenden Hardware. Darüber liegen diverse Bibliotheken und die Laufzeitumgebung, welche dann beide über ein Application Framework von den eigentlichen Apps benutzt werden. Die Laufzeitumgebung beinhaltet neben einigen Core Libraries 1 schließlich die DVM. Sie ist in C/C++ sowie Assembler geschrieben und als Open Source unter der Apache-Lizenz verfügbar 2. Die DVM ist register-basiert und damit näher an realer Hardware orientiert als die stackbasierte JVM: Operanden werden nicht auf einen Stack gelegt oder von dort geholt, sondern liegen in Registern. Dadurch müssen tendenziell weniger Instruktionen ausgeführt [SCEG08] und damit analysiert oder instrumentiert werden, andererseits steigt die Größe des Bytecodes durch die explizite Adressierung von Operanden. Letzteres vereinfacht die Analyse, macht die Codegenerierung durch die nötige Registerallokation allerdings komplexer. In der DVM können bis zu Register verwendet werden, sie sind 32 Bit breit und haben keinen speziellen Verwendungszweck (englisch general-purpose register). Die DVM führt den Bytecode von Apps aus, die normalerweise als Android Packages (APKs) vorliegen. Diese sind Zip-Archive, in denen sich neben Signatur-Dateien und sonstigen binären Ressourcen die Dateien classes.dex und AndroidManifest.xml befinden erstere enthält die Klassen für die DVM, letztere unter anderem die Definition der zu startenden Activity-Klasse. Ein Programmierer benutzt normalerweise das dx-tool, um aus beliebig vielen Java-Klassen die classes.dex für seine App zu erzeugen. Bei der Konvertierung werden viele Java-Eigenschaften (Organisation in Klassen mit Methoden und Feldern, Zugriffsmodifizierer etc.) übernommen, der Bytecode wird allerdings auf das geänderte, register-basierte Maschinenmodell angepasst. In einer.dex-datei verwenden die Klassen außerdem einen gemeinsamen Pool aus Konstanten, 1 ähnlich dem Java Runtime Environment (JRE) der Java-Platform, aber nicht vollständig kompatibel zur Microoder Standard-Edition 2 https://android.googlesource.com/platform/dalvik.git 5

8 also z.b. Strings, Methoden- und Feld-Identifier. Dadurch reduziert sich die Größe der.dex-datei im Vergleich zur Verwendung separater Pools Das Dex-Format Eine Datei im Dex-Format besteht aus einem Header, Indexstrukturen und ansonsten im Wesentlichen aus einer Liste von Klassendefinitionen. Abbildung 2 auf Seite 6 zeigt den logischen Aufbau einer Klasse im Dex-Format. Für eine vollständige, hier nicht benötigte Definition des Formates sei auf [Pro12] verwiesen. Class Data Item Class Def Item Bytecode Code Item Encoded Method Exception Handler... Method ID Access Flags Encoded Method... Encoded Field... Encoded Field... Class Access ID Flags Super Class Interfaces... Abbildung 2: Logischer Aufbau einer Klasse im Dex-Format Eine Klassendefinition (Class Def Item) besteht aus dem eigentlichen Inhalt einer Klasse (Class Data Item) sowie einigen Meta-Daten wie Klassen-Identifier, Zugriffsmodifizierern, Superklasse, Liste der implementierten Interfaces etc. Ein Class Data Item wiederum enthält eine Liste von statischen und Instanzen-Feldern (Encoded Field) sowie eine Liste von direkten und virtuellen Methoden. Direkte Methoden sind die nicht überschreibbaren (statische und private sowie Konstruktoren), virtuelle alle anderen. Eine Methode selbst besteht aus Informationen zum Code (Code Item), einem Methoden-Identifier und den Zugriffsmodifizierern. Das Code Item enthält schließlich den Bytecode als Array aus Instruktionen sowie Informationen zu Exception-Handlern und andere Informationen. Der Bytecode kann unter anderem Referenzen auf Methoden, Felder und Klassen enthalten. Diese sowie andere Referenzen in einer Dex-Datei könnten auch Ziel eines Angreifers sein, indem er etwa eine Feldreferenz auf ein nicht existentes Feld verweisen lässt. Da sich diese Arbeit jedoch auf den Bytecode selbst beschränkt, werden solche Referenzen in andere Bereiche einer Dex-Datei immer als gültig angenommen. Listing 1 auf Seite 6 zeigt ein Hello World -Programm aus Dex-Instruktionen 3. 1 sget object v0, // Ljava / lang / System ;. out : Ljava / i o / PrintStream ; 2 const string v1, // " Hello world! " 3 invoke virtual {v0, v1 }, // Ljava / i o / PrintStream ;. p r i n t l n : ( Ljava / lang / S t r i n g ; ) V 4 return void Listing 1: Hello World als Dex-Bytecode-Mnemonics 3 Zur besseren Übersicht ist nur der Bytecode der main-methode dargestellt, keine weiteren Methoden- oder Klasseninformationen. 6

9 Der Bytecode besteht aus vier Instruktionen: Zunächst wird eine Referenz auf das statische Feld System.out in Register v0 geladen, dann der (konstante) String Hello world! nach Register v1. Die dritte Instruktion ruft die Methode java.io.printstream.println(string) auf dem Object in v0 auf, dabei wird der String in v1 als Parameter benutzt. Schließlich wird der Kontrollfluss von der Methode an den Aufrufer zurückgegeben, ohne Rückgabewert. 1.4 Soot und Jimple Der Beitrag dieser Arbeit, Dalvik-Bytecode zu generieren, basiert auf dem Analyse-Framework Soot [VRCG + 99]. Dieses wurde um die Jahrtausendwende veröffentlicht und war ursprünglich dazu gedacht, Java-Bytecode zu analysieren und zu transformieren. Mittlerweile unterstützt es diverse Ein- und Ausgabeformate, Analysen und Zwischendarstellungen. Das Framework ist in Java geschrieben und kann etwa um eigene Code-Transformationen erweitert werden. Soot kann aus Dex-Dateien Code in der Jimple-Zwischendarstellung generieren [BKLTM12]. Jimple- Instruktionen arbeiten in der Regel auf maximal drei typisierten lokalen Variablen (englisch three address code). Ein Hello World -Programm in Jimple zeigt Listing 2 auf Seite 7. 1 public c l a s s HelloWorld extends java. lang. Object { 2 public s t a t i c void main ( java. lang. S t r i n g [ ] ) { 3 j a v a. lang. S t r i n g [] args ; 4 j a v a. i o. PrintStream out ; 5 6 args : java. lang. S t r i n g [ ] ; 7 out = <j a v a. lang. System : j ava. i o. PrintStream out >; 8 v i r t u a l i n v o k e out.< java. i o. PrintStream : void p r i n t l n ( j a v a. lang. S t r i n g )>(" Hello world! " ) ; 9 return ; 10 } 11 } Listing 2: Hello World in einer Jimple-Zwischendarstellung Zunächst werden die benötigten lokalen Variablen deklariert. Man beachte, dass in Zeile 6 auch der Methoden-Parameter args zunächst in einer lokalen Variable gespeichert wird 4. Dann wird das System.out -Objekt in einer lokalen Variable gespeichert und schließlich auf dieser Variablen die println(string) -Methode aufgerufen der konstante Parameter benötigt keine Variable. Zuletzt wird der Kontrollfluss wieder zurückgegeben. 1.5 Fuzzing als Testansatz Um die Bytecode-Generierung auf Implementierungsfehler zu testen, haben wir einen Fuzz- Testing-Ansatz benutzt. Dazu erhält die zu testende Komponente hier: die Jimple-nach-Dex- Konvertierung mehr oder weniger zufällig veränderte Eingabedaten. Diese ge fuzz ten Daten sollen die Implementierung an ihre Grenzen führen und so Fehler aufdecken. Da unsere Eingabedaten Android-Apps sind, bot sich ein Ansatz an, der die Apps einliest, den Jimple-Code verändert und wieder als Dex-Code rausschreibt. Wenn letzteres gelingt, deutet das auf eine robuste Implementierung hin. Nebenbei kann durch diesen Ansatz auch die DVM selbst getestet werden, da die so generierten Apps weiterhin lauffähig sein sollten. 4 Eine im Beispiel nicht vorhandene this -Referenz würde ebenso zu einer Variablen transformiert. 7

10 Da die Vorarbeiten zum Fuzzing länger dauerten als gedacht, ist derzeit nur ein solcher verändernder Prototyp realisiert, weitere müssen als offene Aufgabe verbleiben (siehe Abschnitt 4.2). Grundsätzlich hat die Art der Veränderungen großen Einfluss auf die Effektivität des Testansatzes. Sind diese zu wahllos, entsteht Code, der bereits syntaktisch falsch ist und so wahrscheinlich gar nicht zur Ausführung kommt. Gezieltere Veränderungen sind aufwendiger und können auch dazu führen, dass ungewöhnliche Fälle nicht in Betracht gezogen werden. Einen umfassenden Überblick über das sogenannte Mutation Testing bietet [JH11]. 2 Design 2.1 Implementierung Die Implementierung der Jimple-nach-Dex-Konvertierung basiert auf einer Bibliothek des smali/baksmali -Projektes [Sma12]. Smali/baksmali ist ein in Java geschriebener Assembler beziehungsweise Disassembler für das Dex-Format, er beinhaltet deshalb auch eine Bibliothek zum Lesen und Schreiben von Dex-Dateien. Von dieser sogenannten dexlib werden auch die Datenstrukturen für die einzelnen zu speichernden Information genutzt, sodass sich unsere Implementierung nicht mit dem byteweisen Aufbau einer Dex-Datei befassen muss. Soot kommuniziert mit der Implementierung über die Klasse soot.todex.dexprinter. Der DexPrinter wird aufgerufen, nachdem das Framework alle Analysen und Transformationen der übergebenen Klassen 5 durchgeführt hat. Durch dexlib ist es allerdings nötig, dass beim Schreiben von Jimple-Klassen diese einzeln hinzugefügt werden und erst anschließend in eine Datei geschrieben werden können. Dies ergibt sich aus dem Dex-Format, da dort ja mehrere Klassen in einer Datei gespeichert werden, anders als bei den sonstigen von Soot unterstützten Ausgabeformaten. Eine Klasse wird vom DexPrinter mit den entsprechend Abbildung 2 auf Seite 6 benötigten Informationen verarbeitet. Dabei sind nur geringe Anpassungen der von Soot bereitgestellten Informationen nötig. So ist eine Umwandlung der Typbezeichner in das unter [Pro12] beschriebene Format nötig, außerdem entsprechen die Zugriffsmodifizierer von Methoden im Dex-Format nicht ganz denen in Java: Es gibt einen Modifizierer, der Konstruktoren markiert, und synchronisierte, nicht-native Methoden werden mit declared_synchronized markiert, nicht mit synchronized Benötigte Register einer Methode Das in Abschnitt erwähnte Code Item einer Methode beinhaltet ebenfalls einige Dexspezifische Informationen: Die Anzahl der von der Methode benötigten Register sowie die Menge der sogenannten in- und out-register. Um diese drei Angaben zu verstehen, lohnt sich ein Blick auf die Aufrufkonvention der DVM, wie sie in Abbildung 3 auf Seite 9 dargestellt ist. Die Register eines Methoden-Frames lassen sich in drei Kategorien einteilen, wie unter (1.) zu sehen: Register für lokale Variablen (lokal0-1), Register für die Parameter der Methode (in0-2) und Register für die Parameter aufzurufender Methoden (out0-1). Da die Größe eines Frames nach dessen Erstellung nicht mehr verändert wird, müssen auch letztere schon zu Beginn feststehen, auch wenn nicht alle out-register bei jedem Methodenaufruf verwendet werden. Es sind auch nur die in- und local-register für den Aufrufer verfügbar, im Beispiel als v Die Klassen liegen zu diesem Zeitpunkt als SootClass vor, welche Java-basiert sind. Bei den Methoden wird ein valider JimpleBody angenommen. 8

11 niedrige Adressen hohe Adressen (1.) Frame des (2.) Aufrufers (out0) (out1) v0 = local0 v1 = local1 v2 = in0 v3 = in1 v4 = in2 invoke(v1,v4) Frame des Aufrufers out0 = v1 out1 = v4 v0 = local0 v1 = local1 v2 = in0 v3 = in1 v4 = in2 Frame des Aufgerufenen v0 = local0 v1 = in0 v2 = in1 Abbildung 3: Register in den Aufruf-Frames von Dalvik Ein Aufruf mit einem der invoke -Opcodes und z.b. zwei Parametern, deren Werte etwa in v1 und v4 liegen, hat zwei Konsequenzen. Zunächst kopiert die DVM die Werte von v1 und v4 in die out-register 0 und 1 des Aufrufers (englisch caller) damit sie vom Aufgerufenen (callee ) dann unabhängig verwendet werden können und im Speicher in jedem Fall hintereinander liegen. Dann wird ein neues Aufruf-Frame für den Aufgerufenen erstellt, in dem es wieder local-, in- und out-register gibt. Die in-register sind dabei die letzten Register (im Beispiel: v1 und v2). Sie liegen an der gleichen Speicherstelle wie die entsprechenden out-register des Aufrufers, womit aus Sicht des Aufgerufenen also in v1 der Wert des v1-registers des Aufrufers liegt, sowie in v2 der des v4-registers des Aufrufers. Die Menge der in-register ist deshalb also die Summe der für die Parameter einer Methode benötigten Register. long- und double-parameter brauchen zwei statt einem Register und bei nicht-statischen Methoden ist das erste in-register noch für die Referenz auf this freizuhalten. Die Menge der out-register ist dagegen das Maximum der für die Parameter eines Methodenaufrufs nötigen Register. Wenn eine Methode keine andere aufruft, ist sie also gleich null. Für die für einen Parameter benötigten Register gelten natürlich die gleichen Regeln wie bei den in-registern. Die Anzahl der benötigten Register schließlich ist von den Instruktionen im Methodenrumpf abhängig, mindestens jedoch gleich der Anzahl der in-register. Der Rückgabewert einer Methode steht dem Aufrufer übrigens nicht über ein Register zur Verfügung, sondern per move-result-opcode, der auf einen speziellen Speicherort in der DVM zugreift Exception-Handler Bevor wir nun die Bytecode-Generierung für die einzelnen Instruktionen beschreiben, sei noch auf die Exception-Handler hingewiesen, die in einem Code Item definiert werden. Diese stammen aus den try-catch-blöcken der Methode, wie sie in der linken Spalte in Abbildung 4 auf Seite 10 gezeigt sind. Ein Try-Block wird im Dex-Format als TryItem abgebildet, welches die Adresse seiner ersten Bytecode-Instruktion, die Anzahl der Instruktionen im Block und einen Verweis auf einen EncodedCatchHandler enthält. Dieser beschreibt die zugehörigen Catch-Blöcke als Liste von EncodedTypeAddrPairs, die jeweils aus dem Typ der zu fangenden Exception und der Adresse der ersten Instruktion des Catch-Blockes bestehen. Im Dex-Format ist auch noch ein sogenannter 9

12 1 try { 2 c = b / a; 3 } 4 catch (ArithmeticException ae) { 5 log(ae); 6 } 7 catch (Exception e) { 8 throw new Error(e); 9 } Adresse zu Instruktion 2 Anzahl Instruktionen im try- Block TryItem EncodedTypeAddrPair Arithmetic Exception Adresse zu Instruktion 5 EncodedCatchHandler EncodedTypeAddrPair Exception Adresse zu Instruktion 8 catchall- Handler (-1) Abbildung 4: Links ein beispielhafter try-catch-block in Java-Syntax, rechts sein Abbild im Dex- Format CatchAll-Handler vorgesehen, der alle Exceptions fängt. Im entsprechenden Feld steht ebenfalls die Adresse der ersten Instruktion. Ein solcher Handler kann bei der Behandlung von finally-blöcken nützlich sein 6. Mangels spezieller CatchAll-Handler-Unterstützung in Soot (er wird als normaler Handler konstruiert, der java.lang.throwable fängt) setzen wir das Feld jedoch konstant auf -1, was kein Handler vorhanden bedeutet Umwandlung von Jimple-Statements Die einzelnen Jimple-Instruktionen werden nacheinander abgearbeitet und in eine oder mehrere Dex-Instruktionen umgewandelt. Anschließend müssen noch einige Informationen aktualisiert werden, denn erst danach stehen z.b. die Adressen im Bytecode fest, zu denen gesprungen werden soll (siehe Abschnitt 2.1.6). Wenn eine Jimple-Instruktion umgewandelt werden soll, wird zunächst eine Pseudo-Instruktion an die bisherige Dex-Liste angefügt. Sie belegt später keinen Platz im Bytecode und dient als Ziel für Sprünge oder die in Abbildung 4 auf Seite 10 gezeigten Adressen für das Exception-Handling. Da sie die originale Jimple-Instruktion enthält, muss keine separate Datenstruktur für das Mapping gepflegt werden, welche Jimple-Instruktion aus welcher Dex-Instruktion entstanden ist. Diese Information wird für die Arbeiten benötigt, die nach der Umwandlung durchgeführt werden. Die eigentliche Umwandlung erfolgt dann im soot.todex.stmtvisitor, der die fünfzehn verschiedenen Arten von Jimple-Statements abhandelt. Innerhalb dieser Statements gibt es verschiedene Unterstrukturen wie Ausdrücke, lokale Variablen, Konstanten und sogenannte Immediates (Oberbegriff für lokale Variablen und Konstanten). Ausdrücke werden durch einen soot.todex.exprvisitor verarbeitet (siehe Abschnitt 2.1.4), lokale Variablen erhalten bei ihrer ersten Verwendung ein eigenes Register und Konstanten werden per const-opcode in ein Register geladen. Im Einzelnen umgewandelt werden: AssignStmt Ein AssignStmt besteht aus einer linken und einer rechten Seite, die diverse Typen haben können. Grundsätzlich soll mit diesem Statement die rechte Seite der linken zugewiesen werden. Wenn ein Immediate einer Feld- oder Arrayreferenz 7 zugewiesen werden soll, wird der 6 In neueren javac-versionen wird der Code des finally-blockes mehrmals in den Bytecode hineinkopiert (code inlining), z.b. an das Ende der try- und catch-blöcke. In diesen Blöcken, außerhalb des kopierten Bytecodes, kann eine Exception auftreten. Sie kann potenziell weitergeworfen werden, muss also nicht von der Methode behandelt werden. Durch einen Exception-Handler, der alle Exceptions fängt, kann so sichergestellt werden, dass der kopierte finally-bytecode trotzdem noch vor Verlassen der Methode ausgeführt wird. 7 StaticFieldRef, InstanceFieldRef beziehungsweise ArrayRef 10

13 entsprechende put-opcode aus Dex verwendet. Soll umgekehrt eine solche Referenz in eine lokale Variable kopiert werden, verwendet die Implementierung den entsprechenden get- Opcode. Stehen auf beiden Seiten lokale Variablen, resultiert das in einem move-befehl, steht rechts eine Konstante und links eine lokale Variable, entsteht eine const-instruktion. Der Fall rechts ein Ausdruck, links eine lokale Variable wird an den ExprVisitor delegiert (siehe Abschnitt 2.1.4). Falls der Ausdruck ein Methodenaufruf war, wird anschließend noch eine moveresult-instruktion angehängt, um die tatsächliche Zuweisung des Methodenaufrufs (genauer: des Rückgabewertes der Methode) an eine lokale Variable abzubilden. BreakpointStmt Ein BreakpointStmt wird nicht umgewandelt, da im Dex-Format keine Breakpoints vorgesehen sind. EnterMonitorStmt / ExitMonitorStmt Diese Statements reservieren ein Lock auf einem Objekt in einer lokalen Variable bzw. geben es wieder frei. Sie werden in Dex mit den entsprechenden monitor-enter- und monitor-exit- Opcodes umgesetzt. GotoStmt Das GotoStmt stellt einen unbedingen Sprung an ein enthaltenes anderes Statement dar. Es wird für das Dex-Format in eine goto-instruktion umgewandelt. Das Ziel wird dabei zunächst als Jimple-Statement gespeichert, die Auflösung zu einer konkreten Adresse im Bytecode erfolgt später (siehe Abschnitt 2.1.6). IdentityStmt Ein IdentityStmt ist eine besondere Form von Zuweisung. Damit werden in Jimple die besonderen Speicherorte für gefangene Exceptions, this und Methoden-Parameter abgebildet 8. Da die letzten beiden in Dex laut Aufrufkonvention schon in Registern vorhanden sind 9, ist in diesen Fällen keine Dex-Instruktion nötig. Wir speichern allerdings die dafür in Jimple verwendeten lokalen Variablen (die linken Seiten solcher Zuweisungen ), damit andere Dex-Instruktionen auf diese Speicherorte mit der richtigen Registernummer zugreifen können. Gefangene Exceptions benötigen dagegen ein neues Register, sie werden per move-exception-opcode dorthin kopiert. IfStmt Ein IfStmt stellt einen bedingten Sprung dar und besteht aus einem Ausdruck und einem anderen Statement. Wertet der Ausdruck zur Laufzeit zu wahr aus, wird das Statement angesprungen. Die Umwandlung in eine Dex-Instruktion übernimmt der ExprVisitor, er generiert die passende if-instruktion. Das Sprungziel wird wie beim GotoStmt zunächst als Jimple-Statement gespeichert und später zu einer Adresse aufgelöst. InvokeStmt Ein InvokeStmt besteht aus einer InvokeExpr. Sie wird mit dem ExprVisitor behandelt und resultiert in einem der invoke-befehle. 8 als CaughtExceptionRef, ThisRef beziehungsweise ParameterRef 9 Siehe die Abbildung 3 auf Seite 9 und die Erklärung dazu. 11

14 LookupSwitchStmt Dieses Statement stellt das Switch-Case-Konstrukt dar, wobei die Fall-Labels (case labels ) als Schlüssel-Ziel-Paare abgebildet sind. Diese Form eines Switches ist dann sinnvoll, wenn die Labels zahlenmäßig eher weiter voneinander entfernt sind. Im LookupSwitchStmt liegen die Schlüssel als Integer-Konstanten vor, die Ziele sind andere Statements, genauso wie das default-ziel. Der Wert, der für die Auswahl eines Cases benutzt wird, liegt als Immediate vor. Das Statement wird mit dem sparse-switch-opcode implementiert. Dieser enthält das Register für den Immediate und die Adresse für den sogenannten Payload. Der Payload wird ans Ende des Bytecodes angefügt (siehe Abschnitt 2.1.6) und enthält die Fälle als Integer-Statement-Paare. Im default-fall wird nicht zum Payload gesprungen, weshalb nach dem sparse-switch-opcode noch ein unbedingter Sprung zum default-ziel eingefügt wird, per goto. NopStmt Ein NopStmt steht dafür, dass die virtuelle Maschine an dieser Stelle keine Operation durchführen soll. Es wird in einen nop-opcode umgewandelt. RetStmt RetStmt ist ein veraltetes Jimple-Konstrukt und hat auch keine Entsprechung im Dex-Format. Aus diesen beiden Gründen wirft die Implementierung einen Fehler aus, falls sie auf ein RetStmt stößt. ReturnStmt Durch ein ReturnStmt kehrt der Kontrollfluss von einer Methode zu ihrem Aufrufer zurück, mit dem Rückgabewert als Immediate. Es wird mit einem return-opcode umgesetzt. ReturnVoidStmt Ein ReturnVoidStmt beendet ebenfalls eine Methode, allerdings ohne einen Rückgabewert zu übermitteln. Dies wird in Dex durch den return-void-opcode realisiert. TableSwitchStmt Dieses Statement stellt wie ein LookupSwitchStmt (s.o.) ein Switch-Case-Konstrukt dar. Es wird allerding genutzt, wenn die Labels zahlenmäßig nahe beieinander liegen, da sie dann als Index in eine Tabelle verwendet werden können: Das erste Label hat sein Ziel in der ersten Zeile usw. Lücken in dem Intervall verbrauchen also auch Tabellenzeilen. Ein TableSwitchStmt wird mit dem packed-switch-opcode umgesetzt. Ansonsten gilt die Beschreibung für das Lookup- SwitchStmt, nur im Payload werden nun eben nur der erste Schlüssel und alle Ziele gespeichert, statt Schlüssel-Ziel-Paaren. ThrowStmt Das ThrowStmt wirft eine Exception, die zuvor in einem Immediate gespeichert wurde. In Dex entspricht das einer throw-instruktion Umwandlung von Jimple-Ausdrücken Wie oben dargelegt, enthalten einige Statements noch Ausdrücke. die mit einem ExprVisitor behandelt werden. Falls der Ausdruck Teil einer Zuweisung ist, bekommt er vom StmtVisitor das 12

15 Zielregister, bei einem bedingten Sprung aufgrund eines Ausdruckes bekommt er das Sprungziel mitgeteilt. In Jimple gibt es 32 verschiedene Ausdrücke, die wie folgt zusammengefasst und umgewandelt werden können: Berechnende binäre Ausdrücke Diese Ausdrücke 10 verknüpfen zwei numerische oder boolsche Operanden und speichern das Ergebnis der Operation in einem Register ab. Dabei gibt es im Dex-Format für drei Situationen optimierte Opcodes: Wenn der zweite Operand eine Integer-Konstante ist, kann dieser direkt in der Instruktion gespeichert werden, womit nur ein statt zwei Quellregister benötigt wird. Diese Opcodes enden auf /lit16 für 16-Bit-Konstanten und /lit8 für welche mit 8 Bit. Die andere Optimierung wird mit /2addr-Opcodes erreicht: Wenn das Register des ersten Operanden gleichzeitig das Zielregister ist, müssen für diese Instruktion nur zwei statt drei Register angegeben werden, was den Bytecode verkleinert. Die dritte Optimierung betrifft das Xor mit -1, wenn der andere Operand ein int oder long ist dies entspricht der Erzeugung des Einerkomplements, wofür es die speziellen Opcodes not-int bzw. not-long gibt. Vergleichende binäre Ausdrücke Hierbei werden die Inhalte zweier Register miteinander verglichen, im Falle von Ganzzahlen 11 wird bei positivem Vergleich zu einem anderen Statement gesprungen, bei Gleitkommazahlen 12 wird das Ergebnis des Vergleichs in ein drittes Register geschrieben. Letzterer Vergleich passiert mit den cmp-opcodes, der Ganzzahlen-Vergleich mit if-instruktionen. Dort gibt es auch eine Optimierungsmöglichkeit: Ist die zweite Ganzzahl 0, kann mit den if-z-befehlen ein Register eingespart werden. Dies ist etwa für den Vergleich einer Objektreferenz mit null von Bedeutung. Methodenaufrufe Es gibt in Jimple fünf verschiedene Ausdrücke, um Methodenaufrufe darzustellen: DynamicInvokeExpr, SpecialInvokeExpr, VirtualInvokeExpr, InterfaceInvokeExpr und StaticInvokeExpr. DynamicInvoke ist mit dem Java Development Kit (JDK) 7 hinzugekommen und wird von Dex nicht unterstützt, weshalb unsere Implementierung einen Fehler ausgibt, wenn sie einen solchen Ausdruck findet. Die anderen Ausdrücke werden alle ähnlich nach Dex umgewandelt. SpecialInvokes sind Aufrufe von Konstruktoren (auch von Superklassen) und von privaten Methoden. Die Ausdrücke haben eine Referenz auf die Methode, die aufzurufen ist, Informationen zu den Parametern (als Immediate) und eine Referenz auf das Objekt, auf dem die Methode aufgerufen wird (als lokale Variable). Ein Aufruf einer super -Methode erhält den invoke-super-opcode, die Aufrufe von privaten Methoden und sonstigen Konstruktoren den Opcode invoke-direct. VirtualInvokes stellen die Aufrufe von überschreibbaren Methoden dar, enthalten dieselben Informationen wie SpecialInvokes und werden per invoke-virtual abgehandelt. InterfaceInvokes sind Methodenaufrufe auf Interfaces, d.h. ähnlich wie bei den VirtualInvokes muss die virtuelle Maschine den Aufruf noch zu einer konkreten Methode auflösen. Auf Bytecode-Ebene unterscheiden sie sich von diesen nur im Opcode, der hier invoke-interface ist. StaticInvokes schließlicht rufen statische Methoden auf. Neben dem Opcode invoke-static unterscheiden 10 AddExpr, SubExpr, MulExpr, DivExpr, RemExpr, AndExpr, OrExpr, XorExpr, ShlExpr, ShrExpr und UshrExpr 11 EqExpr, GeExpr, GtExpr, LeExpr, LtExpr und NeExpr 12 CmpExpr, CmpgExpr und CmplExpr 13

16 sie sich lediglich insofern, als sie natürlich keine Referenz auf ein Objekt enthalten, auf dem die Methode aufgerufen werden soll. Unäre Ausdrücke Bei einer LengthExpr wird die Länge eines Arrays in eine lokale Variable geschrieben. In Dex benutzen wir dazu den array-length-opcode, der die Länge eines in einem Register abgelegten Arrays in ein anderes schreibt. Der andere Ausdruck mit nur einem Parameter, NegExpr, negiert den Wert eines Immediate. Die neg-opcodes in Dex machen genau das. Ausdrücke zu Typen Die InstanceOfExpr stellt den Typcheck dar, mit dem eine Referenz überprüft wird. In Dex gibt es dafür den instance-of-opcode, der 1 oder 0 in ein Register schreibt, wenn die Referenz in einem anderen Register eine Instanz des gegebenen Types ist bzw. nicht ist. Die Typumwandlung geschieht mittels CastExpr, für die es im Dex-Format verschiedene Opcodes gibt. Quelle ist in Jimple immer ein Immediate, in Dex also ein Register. Wenn der Typ, zu dem gecastet werden soll, keine Referenz ist, wird ein primitiver Cast generiert. Je nach Quell- und Cast-Typ ist das einer der X-to-Y -Opcodes. Falls ein primitiver Typ mangels passendem Opcode nicht direkt zu casten ist, erstellt unsere Implementierung zwei Cast-Operationen über ein temporäres Register. Dieses ist nötig, damit die Typen der Dalvik-Register nicht verändert werden es könnte ja zwischen beiden Casts ein Fehler entstehen, wodurch der ursprüngliche Cast nur halb ausgeführt werden würde. Eine weitere Besonderheit ergibt sich aus einer gewissen Typ-Toleranz von Dalvik: So muss etwa ein byte nicht in einen int konvertiert werden, es gibt auch keinen entsprechenden Opcode. Stattdessen reicht ein einfacher move-befehl von Quell- zu Zielregister. Ebenfalls keinen echten Cast benötigen Referenzen: Es wird einfach der check-cast-opcode verwendet, evtl. auch über ein temporäres Zwischenregister (wegen der Typen, s.o.). Der Opcode bewirkt zur Laufzeit des Programmes eine ClassCastException, falls die Typen nicht zusammenpassen. Ansonsten ist eine tatächliche Umwandlung nicht nötig, das erfolgreich gecastete Objekt muss höchstens noch in ein anderes Register verschoben werden. Objekterzeugung Um in Jimple eine neue Instanz eines Types zu erzeugen, gibt es die NewExpr. Sie wird in Dex mit dem new-instance-opcode abgebildet. Da damit keine Array-Typen erzeugt werden können, gibt es noch die NewArrayExpr bzw. new-array. Sie benötigen natürlich noch ein Immediate bzw. ein Register, um die gewünschte Größe des Arrays angeben zu können. Für mehrdimensionale Arrays existiert darüber hinaus NewMultiArrayExpr bzw. filled-new-array. Für Dex hängen wir nach letzterer Instruktion noch eine move-result-object-instruktion an, damit das neue Array in ein Register verschoben wird, wo es dann genutzt werden kann Besonderheiten von Dex-Instruktionen Das Dex-Format hat noch einige Besonderheiten, die bei einer konkreten Implementierung nicht zu vernachlässigen sind. Die bisherige Erwähnung von Dex-Opcodes ignorierte der Übersichtlichkeit halber Unter-Opcodes für verschiedene Typen. So kann etwa eine normale AddExpr eigentlich zu den Opcodes add-int, add-long, add-float und add-double führen. Andererseits kann man auch nicht einfach blind den Typen nehmen, der in Jimple definiert ist, da es z.b. kein add-byte gibt stattdessen muss man in dem Fall add-int verwenden. Z.B. bei den 14

17 vergleichenden binären Ausdrücken muss auch beachtet werden, dass in Dex (Object)null == (int)0 gilt, in Jimple aber die Null-Konstante etwas anderes ist als die Integer-Konstante 0. Eine Null-Konstante muss deshalb vor Weiterverwendung in die Integer-Konstante geändert werden. Weiterhin sei hier erwähnt, dass long- und double-werte immer zwei aneinanderhängende Register benötigen. Opcodes mit diesen Typen enden auf -wide. Bei einem Methodenaufruf belegt ein long oder double konsequenterweise auch zwei Parameter. Erwähnenswert ist noch, dass jedem Opcode ein Instruktionsformat zugeordnet ist 13 und dass hierbei das Format 3rc hervorsticht. Es wird für die filled-new-array/range- und die fünf invoke-*/range-opcodes verwendet. Ersterer kommt zum Einsatz, wenn das zu erstellende Array mehr als fünf Dimensionen hat, letztere bei Methodenaufrufen mit mehr als fünf Parametern. Die normalen Opcodes haben nämlich Instruktionsformate, die maximal fünf Register zulassen. Das Format 3rc erlaubt bis zu 256 Register. Dies wird dadurch erreicht, dass man ein Startregister und die Anzahl der folgenden Register angibt, eben eine Range. Die verwendeten Register müssen also fortlaufend sein Abschließende Arbeiten Nachdem nun prinzipiell alle Dex-Instruktionen erstellt wurden, sind noch einige Aspekte zu aktualisieren, bevor sie an die dexlib weitergereicht werden können. Zunächst müssen noch die zwischengespeicherten Payloads der Switch-Statements (siehe Abschnitt 2.1.3) angehängt werden. Diese sollen einer Empfehlung nach am Ende eines Methoden-Bytecodes liegen: Die Dex-Spezifikation verbietet, dass die Payloads durch normalen Kontrollfluss erreicht werden. Um nicht umständlich um einen Payload in der Mitte springen zu müssen, empfiehlt sie eine Platzierung am Ende. Zu dieser Zeit stehen nun auch alle Ziele im Dex-Bytecode fest, die von bedingten und unbedingten Sprüngen und Switch-Konstrukten verwendet werden können. Also erhalten alle Instruktionen einen Offset gemäß ihrer Größe, beginnend bei 0. Anschließend werden diese Offsets in den Instruktionen eingetragen, in denen sie als Ziele verwendet werden. Ein weiterer Aspekt sind die verwendeten Register: Bisher wurden die Registernummern bei der Erstellung durch den soot.todex.registerallocator einfach hochgezählt. Erst, wenn alle Instruktionen vorliegen, kann deren Verwendung optimiert werden. Dabei müssen verschiedene Dex-spezifische Bedingungen eingehalten werden: Methodenparameter müssen die höchstnummerierten Register im Bytecode einer Methode sein. In Jimple standen die entsprechenden Statements für die Parameter (siehe Abschnitt 2.1.3) am Anfang des Codes, außerdem war noch nicht abzusehen, wieviele weiteren Register benötigt werden long- und double-werte benötigen zwei Register, die aufeinanderfolgend nummeriert sein müssen Instruktionen im 3rc -Format erlauben bis zu 256 Register, die ebenfalls aufeinanderfolgend nummeriert sein müssen (siehe Abschnitt 2.1.5) die meisten Opcodes können aufgrund ihres Instruktionsformates nicht mit der vollen Registerbandbreite ( ) arbeiten, da das Format nur vier oder acht Bit für ein Register vorsieht

18 Bei einer Registeroptimierung in diesem Kontext sollte auch das übergeordnete Ziel der Implementierung beachtet werden: Optimalerweise sollte eine Dex-Datei, wenn sie von Soot eingelesen wurde und keine sonstigen Transformationen durchläuft, wieder genauso ausgegeben werden, damit Analyseergebnisse nicht durch diese Round Trip -Konvertierung beeinflusst werden. Wie in den vorherigen Abschnitten gesehen, treten bei der Konvertierung von Jimple nach Dex bisher kaum Veränderungen auf 14. Allerdings verletzt der Bytecode durch die naive Konvertierung an vielen Stellen noch die oben genannten Bedingungen. Optimierung kann hier also nicht bedeuten, möglichst schnellen Code zu erzeugen, oder z.b. (trotz virtueller Maschine) die Anzahl der verwendeten Register zu minimieren vielmehr soll korrekter, möglichst originalgetreuer Bytecode entstehen. Deshalb verwendet die Implementierung (in soot.todex.registerassigner) an dieser Stelle keinen der üblichen Algorithmen zur Registerallokation, sondern lehnt sich sehr stark an das dx-tool an. Dieses ist im Android-Software Development Kit (SDK) enthalten und konvertiert.class-dateien in das Dex-Format. Die Registerallokation ist dort in der Klasse com.android.dx.dex.code.outputfinisher zu finden. Registerallokation im Detail Der RegisterAssigner geht nun wie folgt vor, um die Register unter den genannten Bedingungen final zuzuweisen: Zunächst werden die Register für die Parameter hinter die anderen geschoben, sodass sie die mit den höchsten Nummern sind. Am unteren Ende werden anschließend in einem Fixpunktverfahren solange neue Register angefügt, bis keine weiteren benötigt werden. D.h. die Registernummern werden z.b. alle um 2 inkrementiert, weil aktuell zwei zusätzliche Register benötigt werden. Diese haben dann die Nummern 0 und 1. Durch die Inkrementierung könnten alte Register ungültig werden. Deshalb prüft das Verfahren am Anfang der nächsten Iteration wieder, wieviele inkompatible Register es gibt, und ob die bisher reservierten neuen Register für sie ausreichen. In einem zweiten Schritt werden dann alle Instruktionen mit inkompatiblen Register korrigiert. Dies kann auf zwei Weisen geschehen: Entweder wird die Instruktion durch eine passende ersetzt: Zum Beispiel kann eine const/4-instruktion (Registernummer muss kleiner 16 sein) durch eine mit const/16 (Nummer kleiner 256) ersetzt werden. Oder es werden vor und gegebenenfalls nach der Instruktion neue moves hinzugefügt, die die Registerinhalte in niedrigere, kompatible Register verschieben bzw. von dort wieder herausholen. Abbildung 5 auf Seite 16 zeigt ein einfaches Beispiel: invoke-super v19, v move v0, v19 3 move v1, v20 4 invoke-super v0, v Abbildung 5: links: invoke-super-instruktion mit inkompatiblen Registern: maximal v15 wäre jeweils erlaubt, da nur je 4 Bit zur Verfügung stehen. rechts: durch Einfügen zweier moves behobener Code 14 Eine mögliche Beeinflussung durch das Einlesen, also die Dex-nach-Jimple-Konvertierung soll hier außen vor bleiben, da wir darauf im Rahmen dieser Arbeit keinen Einfluss haben. 16

19 Eine Instruktion kann ein Register nicht nur lesen, sondern als sogenanntes Ergebnis-Register auch schreiben. Wenn das Ergebnis-Register inkompatibel ist, muss nach der Instruktion ein weiterer move eingefügt werden, wie Abbildung 6 auf Seite 17 zeigt: iget v16, v move v0, v19 3 iget v0, v0 4 move v16, v Abbildung 6: links: iget-instruktion mit inkompatiblen Registern. rechts: durch Einfügen zweier moves behobene Instruktion Im Beispiel sieht man eine iget-instruktion mit inkompatiblen Registern. Es ist jeweils maximal v15 erlaubt, da nur je 4 Bit zur Verfügung stehen. Die iget-instruktion speichert eine Instanzvariable aus dem Objekt in Register v19 in das Register v16, das also ein Ergebnis- Register ist. Durch Einfügen des oberen moves wurde das Objekt-Register korrigiert, mit dem unteren das Ergebnis-Register. Die Registerallokation ist abgeschlossen, nachdem jede Instruktion mit inkompatiblen Registern ersetzt oder durch moves korrigiert wurde. Bedingte und unbedingte Sprünge Auch die Offsets in den Sprüngen können Instruktionsformate verletzen: Bei den if- und goto -Opcodes gibt es welche, die für das Sprungziel nur 8 oder 16 Bit erlauben. Bei den Switches tritt das Problem nicht auf, da dort die vollen 32 Bit möglich sind. Um die Offsets zu korrigieren, wird ebenfalls ein Fixpunkt-Verfahren angewandt: Der Algorithmus initialisiert die Offsets neu und geht dann einmal durch alle Instruktionen und behebt währenddessen fehlerhafte Sprünge. Solange dabei Instruktionen verändert wurden, werden diese beiden Schritte wiederholt. Dies ist nötig, da durch die Korrektur auch neue Instruktionen hinzukommen können, wodurch Offsets wieder ungültig werden können. Einfach zu beheben sind unbedingte Sprünge: Es gibt für sie die Opcodes goto, goto/16 und goto/32. Wie die Namen vermuten lassen, kann eine fehlerhafte goto-instruktion (für 8- Bit-Offsets) durch eine mit goto/16 (16 Bit) ersetzt werden, diese wiederum durch eine mit goto/32 (32 Bit). Komplexer ist die Korrektur bei if-instruktionen, die Offsets bis 16 Bit zulassen und keine alternativen Opcodes haben. Unsere Implementierung bedient sich dabei einer Transformation, die in Abbildung 7 auf Seite 17 dargestellt ist. 1 if (test) goto bar 2 foo: bar: 5... max. 16 Bit 1 if (!test) goto foo 2 goto bar 3 foo: bar: 6... max. 16 Bit max. 32 Bit Abbildung 7: links: Bedingter Sprung mit potenziell zu großem Sprung-Offset. rechts, gleichwertig: Durch Negation der Bedingung gewonnener, unbedingter Sprung mit der Möglichkeit eines größeren Offsets. 17

20 Der bedingte Sprung von Zeile 1 nach bar in Zeile 4 erlaubt einen maximalen Offset von 16 Bit. Wenn nicht gesprungen wird, geht die Ausführung bei foo in Zeile 2 weiter. Wenn wir die Bedingung für den Sprung negieren, muss dieser nun zum sehr nahen foo zeigen. Das ursprüngliche bar erreichen wir durch einen unbedingten Sprung, der neu hinter die if-instruktion, aber vor foo eingefügt wird. Dieser Sprung wird ja gerade ausgeführt, wenn die Bedingung nicht zutrifft, also genau dann wenn unsere ursprüngliche, nicht negierte es täte. Nach diesen Arbeiten werden die Datenstrukturen unserer Implementierung in die der dexlib umgewandelt und dorthin weitergereicht. Damit kann sie nun den Bytecode und damit den letzten benötigten Teil einer Klassendefinition gemäß Abbildung 2 auf Seite 6 erzeugen Unbenutzte Opcodes Einige für Dex-Bytecode definierte Opcodes werden von der Implementierung bewusst nicht benutzt. Unterschiedlichste Gründe führen dazu, dass niemals Instruktionen mit diesen Opcodes generiert werden: rsub-int und rsub-int/lit8 Diese Opcodes führen die sogenannte umgekehrte Substraktion (englisch reverse substraction) auf zwei Ganzzahlen a und b durch: Statt wie im three address code üblich für die Anweisung minus c, a, b den Wert c = a minus b zu berechnen, wird c = b minus a ausgeführt. Eine solche Operation kann auf Jimple-Ebene nicht erkannt werden. const/high16 und const-wide/high16 Diese beiden Opcodes laden eine 16-Bit-Ganzzahl in die höhere Hälfte eines Registers bzw. Register-Paares, die untere Hälfte wird dabei mit Nullen aufgefüllt. Für unsere Implementierung konnte keine sinnvolle Verwendung dafür gefunden werden. fill-array-data Dieser Opcode ermöglicht es, Arrays effizient mit Daten zu initialisieren. Er benutzt dafür einen Payload mit zusätzlichen Daten, ähnlich der beiden Switch-Opcodes. Da Soot bei seiner Konvertierung die Array-Initialisierung in kleinere Operationen aufteilt, gibt es hierfür ebenfalls keine Verwendung. const-string/jumbo Ein Jumbo-Opcode ermöglicht es, bei Referenzen einen besonders großen Index anzugeben (statt 16 Bit ist Platz für bis zu 32 Bit). Da die dexlib diese Referenzen verwaltet, wandelt sie bei Bedarf einen normalen const-string-opcode auch selbst in const-string/jumbo um. 2.2 Testansatz Um nun die in Abschnitt 2.1 beschriebene Implementierung zu testen, werden Android-Apps durch Soot eingelesen, wieder rausgeschrieben und kontrolliert auf einem Android-Emulator installiert und gestartet. Einen Überblick über die verwendeten Komponenten bietet Abbildung 8 auf Seite 19. Das Test-Framework besteht hauptsächlich aus Soot, das die zu testende Implementierung todex und Dexpler zum Einlesen von Dex-Dateien enthält. Daneben enthält es Code, um den 18

3 Objektorientierte Konzepte in Java

3 Objektorientierte Konzepte in Java 3 Objektorientierte Konzepte in Java 3.1 Klassendeklarationen Fragen an die Klassendeklaration: Wie heißt die Klasse? Wer darf auf die Klasse und ihre Attribute/Methoden zugreifen? Ist die Klasse eine

Mehr

Tooldemo: Soot. Softwareanalyse SS 2011 Veranstalter: Prof. Dr. Klaus Ostermann Tillmann Rendel, M.Sc. Von Kim Maurice Nuspl

Tooldemo: Soot. Softwareanalyse SS 2011 Veranstalter: Prof. Dr. Klaus Ostermann Tillmann Rendel, M.Sc. Von Kim Maurice Nuspl Softwareanalyse SS 2011 Veranstalter: Prof. Dr. Klaus Ostermann Tillmann Rendel, M.Sc. Tooldemo: Soot (http://www.sable.mcgill.ca/soot/) Von Kim Maurice Nuspl Gliederung: Was ist Soot? Eclipse Plugin Grundlagen

Mehr

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf 16 Exceptions Zur Behandlung unerwarteter Situationen bietet Java Unterstützung in Form von Exceptions oder Ausnahmen. Den Sinn von Exceptions können wir Ihnen an einem kleinen Beispiel klarmachen. Nehmen

Mehr

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden. Grundwissen Informatik Objekt Attribut Methoden Als Objekte bezeichnet man alle Gegenstände, Dinge, Lebewesen, Begriffe oder Strukturen unserer Welt ( Autos, Räume, Bakterien, Lehrer, Schüler, Kunden,

Mehr

Smartphone Entwicklung mit Android und Java

Smartphone Entwicklung mit Android und Java Smartphone Entwicklung mit Android und Java predic8 GmbH Moltkestr. 40 53173 Bonn Tel: (0228)5552576-0 www.predic8.de info@predic8.de Was ist Android Offene Plattform für mobile Geräte Software Kompletter

Mehr

Java für C++ Programmierer

Java für C++ Programmierer Java für C++ Programmierer Alexander Bernauer bernauer@inf.ethz.ch Einführung in die Übungen zu Informatik II (D ITET) FS2010 ETH Zürich Ziel Allgemeiner Überblick Kennenlernen der Suchbegriffe Warum Java?

Mehr

Java Virtual Machine (JVM) Bytecode

Java Virtual Machine (JVM) Bytecode Java Virtual Machine (JVM) durch Java-Interpreter (java) realisiert abstrakte Maschine = Softwareschicht zwischen Anwendung und Betriebssystem verantwortlich für Laden von Klassen, Ausführen des Bytecodes,

Mehr

App-Entwicklung für Android

App-Entwicklung für Android App-Entwicklung für Android Einleitung - Systemarchitektur Hochschule Darmstadt WS15/16 1 Inhalt Historie Systemarchitektur Sandbox 2 Motivation Kontra Pro Limitierte Größe Begrenzte Ressourcen Kein Standardgerät

Mehr

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1 Kapitel 11 Fehler und Ausnahmen Fehler und Ausnahmen 1 Ziele Fehlerquellen in Programmen und bei der Programmausführung verstehen Das Java-Konzept der Ausnahmen als Objekte kennenlernen Ausnahmen auslösen

Mehr

Primitive Datentypen

Primitive Datentypen Primitive Datentypen 2 Arten von Datentypen: primitive Datentypen (heute) Objekte (später) Java ist streng typisiert, d.h. für jede Variable muß angegeben werden was für eine Art von Wert sie aufnimmt.

Mehr

Praktikum Compilerbau Sitzung 9 Java Bytecode

Praktikum Compilerbau Sitzung 9 Java Bytecode Praktikum Compilerbau Sitzung 9 Java Bytecode Prof. Dr.-Ing. Gregor Snelting Matthias Braun und Sebastian Buchwald IPD Snelting, Lehrstuhl für Programmierparadigmen KIT Universität des Landes Baden-Württemberg

Mehr

Java Einführung Methoden in Klassen

Java Einführung Methoden in Klassen Java Einführung Methoden in Klassen Lehrziel der Einheit Methoden Signatur (=Deklaration) einer Methode Zugriff/Sichtbarkeit Rückgabewerte Parameter Aufruf von Methoden (Nachrichten) Information Hiding

Mehr

Java Einführung Programmcode

Java Einführung Programmcode Java Einführung Programmcode Inhalt dieser Einheit Programmelemente Der erste Programmcode Die Entwicklungsumgebung: Sun's Java Software Development Kit (SDK) Vom Code zum Ausführen des Programms 2 Wiederholung:

Mehr

Kompilieren und Linken

Kompilieren und Linken Kapitel 2 Kompilieren und Linken Bevor wir uns auf C++ selbst stürzen, brauchen wir einiges Vorgeplänkel, wie man komfortabel ein größeres C++- kompilieren kann. Mit Java stellt sich der Kompiliervorgang

Mehr

5.4 Klassen und Objekte

5.4 Klassen und Objekte 5.4 Klassen und Objekte Zusammenfassung: Projekt Figuren und Zeichner Figuren stellt Basisklassen für geometrische Figuren zur Verfügung Zeichner bietet eine übergeordnete Klasse Zeichner, welche die Dienstleistungen

Mehr

J.5 Die Java Virtual Machine

J.5 Die Java Virtual Machine Java Virtual Machine Die Java Virtual Machine 22 Prof. Dr. Rainer Manthey Informatik II Java-Compiler und Java Virtual Machine Quellcode-Datei class C... javac D.java Java-Compiler - Dateien class class

Mehr

Programmieren I. Die Programmiersprache Java. www.kit.edu. Institut für Angewandte Informatik

Programmieren I. Die Programmiersprache Java. www.kit.edu. Institut für Angewandte Informatik Programmieren I Die Programmiersprache Java KIT Universität des Landes Baden-Württemberg und nationales Großforschungszentrum in der Helmholtz-Gemeinschaft www.kit.edu Eigenschaften von Java Java ist eine

Mehr

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9 Prof. Dr. Wilhelm Schäfer Paderborn, 15. Dezember 2014 Christian Brenner Tristan Wittgen Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9 Aufgabe 1 Codegenerierung

Mehr

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung Übersicht 3.1 Modell Konto 3.2 Modell Konto - Erläuterungen 3.3 Benutzer Ein- und Ausgabe mit Dialogfenster I 3.4 Benutzer Ein- und Ausgabe mit Dialogfenster II 3.5 Klassen- und Objekteigenschaften des

Mehr

Exceptions. Prof. Dr. Margarita Esponda SS 2012. M. Esponda-Argüero

Exceptions. Prof. Dr. Margarita Esponda SS 2012. M. Esponda-Argüero Exceptions Prof. Dr. Margarita Esponda SS 2012 1 Ausnahmen Eine Ausnahme (Exception) ist ein Fehler oder ein nicht geplantes Ereignis, das während der Ausführung eines Programms vorkommt und dessen normalen

Mehr

3 Objektorientierte Konzepte in Java

3 Objektorientierte Konzepte in Java 3 Objektorientierte Konzepte in Java Bisherige Beobachtungen zu Objekten: werden in Klassen zusammengefasst besitzen Eigenschaften und Verhalten verbergen private Informationen werden geboren, leben und

Mehr

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Inhalt dieser Einheit Variablen (Sinn und Aufgabe) Bezeichner Datentypen, Deklaration und Operationen Typenumwandlung (implizit/explizit) 2 Variablen

Mehr

Kontrollstrukturen, Pseudocode und Modulo-Rechnung

Kontrollstrukturen, Pseudocode und Modulo-Rechnung Kontrollstrukturen, Pseudocode und Modulo-Rechnung CoMa-Übung III TU Berlin 29.10.2012 CoMa-Übung III (TU Berlin) Kontrollstrukturen, Pseudocode und Modulo-Rechnung 29.10.2012 1 / 1 Themen der Übung 1

Mehr

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions

Gliederung Grundlagen Schlüsselworte try-catch Fehlerobjekte Fehlerklassen Schlüsselwort finally Schlüsselwort throws selbst erstellte Exceptions try-catch Schlüsselworte try-catch e Schlüsselwort Schlüsselwort selbst erstellte ermöglichen die Behandlung von Fehlern, die zur Laufzeit entstehen. try-catch in C: Fehler führt immer zum Abbruch des

Mehr

PIWIN 1 Übung Blatt 5

PIWIN 1 Übung Blatt 5 Fakultät für Informatik Wintersemester 2008 André Gronemeier, LS 2, OH 14 Raum 307, andre.gronemeier@cs.uni-dortmund.de PIWIN 1 Übung Blatt 5 Ausgabedatum: 19.12.2008 Übungen: 12.1.2009-22.1.2009 Abgabe:

Mehr

Software Engineering Klassendiagramme Einführung

Software Engineering Klassendiagramme Einführung Software Engineering Klassendiagramme Einführung Prof. Adrian A. Müller, PMP, PSM 1, CSM Fachbereich Informatik und Mikrosystemtechnik 1 Aufgabe Erstellen Sie eine Klasse Person in Java. Jede Person verfügt

Mehr

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java: Technische Informatik für Ingenieure (TIfI) WS 2005/2006, Vorlesung 9 II. Grundlagen der Programmierung Ekkart Kindler Funktionen und Prozeduren Datenstrukturen 9. Datenstrukturen Daten zusammenfassen

Mehr

Variablen manipulieren per JDI

Variablen manipulieren per JDI Variablen manipulieren per JDI Zusammenfassung Jede moderne Java IDE verfügt über eine mächtige und dennoch meist einfach zu bedienende Benutzeroberfläche die das finden von Fehlern in lokalen oder entfernt

Mehr

1 Polymorphie (Vielgestaltigkeit)

1 Polymorphie (Vielgestaltigkeit) 1 Polymorphie (Vielgestaltigkeit) Problem: Unsere Datenstrukturen List, Stack und Queue können einzig und allein int-werte aufnehmen. Wollen wir String-Objekte, andere Arten von Zahlen oder andere Objekttypen

Mehr

Die Programmiersprache Java. Dr. Wolfgang Süß Thorsten Schlachter

Die Programmiersprache Java. Dr. Wolfgang Süß Thorsten Schlachter Die Programmiersprache Java Dr. Wolfgang Süß Thorsten Schlachter Eigenschaften von Java Java ist eine von der Firma Sun Microsystems entwickelte objektorientierte Programmiersprache. Java ist......a simple,

Mehr

Diplomarbeit Antrittsvortrag

Diplomarbeit Antrittsvortrag Diplomarbeit Antrittsvortrag Christian Müller Run-time byte code compilation, interpretation and optimization for Alice Betreuer: Guido Tack Verantwortlicher Prof.: Gert Smolka Die nächsten 15 Minuten...

Mehr

Erste Schritte mit Eclipse

Erste Schritte mit Eclipse Erste Schritte mit Eclipse März 2008, KLK 1) Java Development Kit (JDK) und Eclipse installieren In den PC-Pools der HAW sind der JDK und Eclipse schon installiert und können mit dem Application Launcher

Mehr

Ogre Einführung Teil 1

Ogre Einführung Teil 1 Inhalt -Einleitung -Installieren und Einrichten von Ogre -Die erste Anwendung Ogre Einführung Teil 1 Einleitung Eine 3D Engine ist eine sehr komplexe Software und besteht aus mehreren tausend Zeilen Programmcode.

Mehr

Javakurs für Anfänger

Javakurs für Anfänger Javakurs für Anfänger Einheit 02: Klassen & Objekte Lorenz Schauer Lehrstuhl für Mobile und Verteilte Systeme Heutige Agenda 1. Teil: Klassen Grundstruktur einer Java-Klasse Eigenschaften (Attribute) Variablen

Mehr

AKTUEL ZU JAVA 8 PROGRAMMIEREN IN JAVA. 7. Auflage. Im Internet: Alle Beispielprogramme und Lösungen

AKTUEL ZU JAVA 8 PROGRAMMIEREN IN JAVA. 7. Auflage. Im Internet: Alle Beispielprogramme und Lösungen L AKTUEL ZU fritz JOBST JAVA 8 PROGRAMMIEREN IN JAVA 7. Auflage Im Internet: Alle Beispielprogramme und Lösungen 4 1 Der Einstieg in Java keinem Fall zulässig. Die Schreibweisen Hello.java für den Namen

Mehr

Informatik. Studiengang Chemische Technologie. Michael Roth WS 2012/2013. michael.roth@h-da.de. Hochschule Darmstadt -Fachbereich Informatik-

Informatik. Studiengang Chemische Technologie. Michael Roth WS 2012/2013. michael.roth@h-da.de. Hochschule Darmstadt -Fachbereich Informatik- Informatik Studiengang Chemische Technologie Michael Roth michael.roth@h-da.de Hochschule Darmstadt -Fachbereich Informatik- WS 2012/2013 Inhalt Teil VII Einstieg in Java I Michael Roth (h_da) Informatik

Mehr

Repetitorium Informatik (Java)

Repetitorium Informatik (Java) Repetitorium Informatik (Java) Tag 6 Lehrstuhl für Informatik 2 (Programmiersysteme) Übersicht 1 Klassen und Objekte Objektorientierung Begrifflichkeiten Deklaration von Klassen Instanzmethoden/-variablen

Mehr

Klassendefinitionen verstehen

Klassendefinitionen verstehen Klassendefinitionen verstehen Java-Programme bestehen aus Klassendefinitionen und sonst nichts! 1 1.0 Konzepte Felder Konstruktoren Methoden Parameter Zuweisungen ( = ) Anweisungen bedingte Anweisungen

Mehr

1. Java Grundbegriffe

1. Java Grundbegriffe 1. Java Grundbegriffe Geschichte von Java Programmieren mit Java Interpretieren vs. Kompilieren Java Byte-Code Jave Virtual Machine Arbeitsmaterialien Allgemeine Informatik 2 SS09 Folie 1.1 Java, eine

Mehr

i n g e n i e u r b ü r o f ü r s o f t w a r e t e c h n o l o g i e w w w. v o e l t e r. d e Servlet Debugging

i n g e n i e u r b ü r o f ü r s o f t w a r e t e c h n o l o g i e w w w. v o e l t e r. d e Servlet Debugging Servlet Debugging Markus Völter, voelter@acm.org, www.voelter.de Bei der Arbeit mit Servlets kommt man recht schnell an den Punkt, an dem man Servlets vernünftig testen oder debuggen will. Mit Hilfe des

Mehr

Kapitel 12: Übersetzung objektorienter Konzepte

Kapitel 12: Übersetzung objektorienter Konzepte Kapitel 12: Übersetzung objektorienter Konzepte Themen Klassendarstellung und Methodenaufruf Typüberprüfung Klassenhierarchieanalyse Escape Analyse 12.1 Klassendarstellung bei Einfachvererbung class Punkt

Mehr

Objektorientierte Programmierung

Objektorientierte Programmierung Objektorientierte Programmierung 1 Geschichte Dahl, Nygaard: Simula 67 (Algol 60 + Objektorientierung) Kay et al.: Smalltalk (erste rein-objektorientierte Sprache) Object Pascal, Objective C, C++ (wiederum

Mehr

ObjectBridge Java Edition

ObjectBridge Java Edition ObjectBridge Java Edition Als Bestandteil von SCORE Integration Suite stellt ObjectBridge Java Edition eine Verbindung von einem objektorientierten Java-Client zu einer fast beliebigen Server-Komponente

Mehr

Programmentwicklung ohne BlueJ

Programmentwicklung ohne BlueJ Objektorientierte Programmierung in - Eine praxisnahe Einführung mit Bluej Programmentwicklung BlueJ 1.0 Ein BlueJ-Projekt Ein BlueJ-Projekt ist der Inhalt eines Verzeichnisses. das Projektname heißt wie

Mehr

Objects First With Java A Practical Introduction Using BlueJ. Mehr über Vererbung. Exploring polymorphism 1.0

Objects First With Java A Practical Introduction Using BlueJ. Mehr über Vererbung. Exploring polymorphism 1.0 Objects First With Java A Practical Introduction Using BlueJ Mehr über Vererbung Exploring polymorphism 1.0 Zentrale Konzepte dieses Kapitels Methoden-Polymorphie statischer und dynamischer Typ Überschreiben

Mehr

Tutorium Java Ein Überblick. Helge Janicke

Tutorium Java Ein Überblick. Helge Janicke Tutorium Java Ein Überblick Helge Janicke 26. Oktober 2000 1 VORRAUSSETZUNGEN ZUM PROGRAMMIEREN MIT JAVA. 1 1 Vorraussetzungen zum Programmieren mit Java. Was braucht man, wenn man mit Java programmieren

Mehr

Tutorium Rechnerorganisation

Tutorium Rechnerorganisation Woche 2 Tutorien 3 und 4 zur Vorlesung Rechnerorganisation 1 Christian A. Mandery: KIT Universität des Landes Baden-Württemberg und nationales Grossforschungszentrum in der Helmholtz-Gemeinschaft www.kit.edu

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen Tafelübung 04 Referenzen, Overloading, Klassen(hierarchien) Clemens Lang T2 18. Mai 2010 14:00 16:00, 00.152 Tafelübung zu AuD 1/13 Organisatorisches Nächster Übungstermin

Mehr

Einführung in die Programmierung

Einführung in die Programmierung Technische Universität München WS 2003/2004 Institut für Informatik Prof. Dr. Christoph Zenger Testklausur Einführung in die Programmierung Probeklausur Java (Lösungsvorschlag) 1 Die Klasse ArrayList In

Mehr

Programmieren in Java

Programmieren in Java Programmieren in Java objektorientierte Programmierung 2 2 Zusammenhang Klasse-Datei In jeder *.java Datei kann es genau eine public-klasse geben wobei Klassen- und Dateiname übereinstimmen. Es können

Mehr

Übungen zur Vorlesung Einführung in die Informatik Wintersemester 2010/11

Übungen zur Vorlesung Einführung in die Informatik Wintersemester 2010/11 Übungen zur Vorlesung Einführung in die Informatik Wintersemester 2010/11 Fakultät für Informatik Lehrstuhl 1 Dr. Lars Hildebrand Carla Delgado-Battenfeld Fatih Gedikli Tobias Marschall Benjamin Schowe

Mehr

JMangler. Frithjof Kurtz. Universität Bonn, Seminar Softw aretechnologie WS 03/04, Jmangler Frithjof Kurtz 1

JMangler. Frithjof Kurtz. Universität Bonn, Seminar Softw aretechnologie WS 03/04, Jmangler Frithjof Kurtz 1 JMangler Frithjof Kurtz Universität Bonn, Seminar Softw aretechnologie WS 03/04, Jmangler Frithjof Kurtz 1 JMangler Vortragsgliederung Motivation Java Grundlagen JMangler Grundlagen Transformationen Algorithmen

Mehr

Prinzipien Objektorientierter Programmierung

Prinzipien Objektorientierter Programmierung Prinzipien Objektorientierter Programmierung Valerian Wintner Inhaltsverzeichnis 1 Vorwort 1 2 Kapselung 1 3 Polymorphie 2 3.1 Dynamische Polymorphie...................... 2 3.2 Statische Polymorphie........................

Mehr

Effiziente Java Programmierung

Effiziente Java Programmierung Effiziente Java Programmierung Seminar Implementierung moderner virtueller Maschinen am Beispiel von Java SS 2009 von Reinhard Klaus Losse 20. Mai 2009 Gliederung Definition Effizienz Werkzeuge zum Messen

Mehr

II.1.1. Erste Schritte - 1 -

II.1.1. Erste Schritte - 1 - ! 1. Grundelemente der Programmierung! 2. Objekte, Klassen und Methoden! 3. Rekursion und dynamische Datenstrukturen! 4. Erweiterung von Klassen und fortgeschrittene Konzepte II.1.1. Erste Schritte - 1

Mehr

Mobile Application Development

Mobile Application Development Mobile Application Development Android: Einführung Jürg Luthiger University of Applied Sciences Northwestern Switzerland Institute for Mobile and Distributed Systems Lernziele Der/die Kursbesucher/in kann

Mehr

JDroidLib mit Eclipse (Mac/Linux/Windows)

JDroidLib mit Eclipse (Mac/Linux/Windows) JDroidLib mit Eclipse (Mac/Linux/Windows) Version 1.3, 25. März 2013 (Unter Windows besser die ADT-Bundle Version installieren, siehe entsprechende Anleitung) Vorbereitungen: 1. JDK SE neuste Version installieren,

Mehr

Vorkurs C++ Programmierung

Vorkurs C++ Programmierung Vorkurs C++ Programmierung Klassen Letzte Stunde Speicherverwaltung automatische Speicherverwaltung auf dem Stack dynamische Speicherverwaltung auf dem Heap new/new[] und delete/delete[] Speicherklassen:

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung Kapitel 6 Vererbung Vererbung 1 Ziele Das Vererbungsprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen

Mehr

Apps-Entwicklung mit Eclipse

Apps-Entwicklung mit Eclipse JDroid mit Eclipse Seite 1 Apps-Entwicklung mit Eclipse Version 1.1, 30. April 2013 Vorbereitungen: 1. JDK installieren JDK SE neuste Version (64 oder 32 Bit) herunterladen und installieren (http://www.oracle.com/technetwork/java/javase/downloads/index.html)

Mehr

C# im Vergleich zu Java

C# im Vergleich zu Java C# im Vergleich zu Java Serhad Ilgün Seminar Universität Dortmund SS 03 Gliederung Entstehung von C# und Java Überblick von C# und Java Unterschiede und Gemeinsamkeiten Zusammenfassung und Ausblick Entstehung

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung 1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben

Mehr

Bearbeitungszeit: 120 Minuten. Kommentare kosten Zeit; kommentieren Sie ihr Programm nur da, wo der Code alleine nicht verständlich wäre.

Bearbeitungszeit: 120 Minuten. Kommentare kosten Zeit; kommentieren Sie ihr Programm nur da, wo der Code alleine nicht verständlich wäre. Fakultät IV Elektrotechnik/Informatik Klausur Einführung in die Informatik I für Elektrotechniker Name:... Matr.-Nr.... Bearbeitungszeit: 120 Minuten Bewertung (bitte offenlassen : ) Aufgabe Punkte Erreichte

Mehr

Vererbung & Schnittstellen in C#

Vererbung & Schnittstellen in C# Vererbung & Schnittstellen in C# Inhaltsübersicht - Vorüberlegung - Vererbung - Schnittstellenklassen - Zusammenfassung 1 Vorüberlegung Wozu benötigt man Vererbung überhaubt? 1.Um Zeit zu sparen! Verwendung

Mehr

Dynamische Sprachen auf der JVM

Dynamische Sprachen auf der JVM Dynamische Sprachen auf der JVM Christian Müller Leibniz Universität Hannover 1 Einführung Der Begriff dynamische Sprache ist nicht genau definiert, sehr oft wird er lediglich mit dynamischer Typprüfung

Mehr

Kapitel 6. Vererbung

Kapitel 6. Vererbung 1 Kapitel 6 2 Ziele Das sprinzip der objektorientierten Programmierung verstehen Und in Java umsetzen können Insbesondere folgende Begriffe verstehen und anwenden können: Ober/Unterklassen Subtyping Überschreiben

Mehr

CADEMIA: Einrichtung Ihres Computers unter Linux mit Oracle-Java

CADEMIA: Einrichtung Ihres Computers unter Linux mit Oracle-Java CADEMIA: Einrichtung Ihres Computers unter Linux mit Oracle-Java Stand: 21.02.2015 Java-Plattform: Auf Ihrem Computer muss die Java-Plattform, Standard-Edition der Version 7 (Java SE 7) oder höher installiert

Mehr

Javakurs 2013 Objektorientierung

Javakurs 2013 Objektorientierung Javakurs 2013 Objektorientierung Objektorientierte Programmierung I Armelle Vérité 7 März 2013 Technische Universität Berlin This work is licensed under the Creative Commons Attribution-ShareAlike 3.0

Mehr

Von der UML nach C++

Von der UML nach C++ 22 Von der UML nach C++ Dieses Kapitel behandelt die folgenden Themen: Vererbung Interfaces Assoziationen Multiplizität Aggregation Komposition Die Unified Modeling Language (UML) ist eine weit verbreitete

Mehr

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests. Universität Osnabrück 1 Problemstellung 3 - Objektorientierte Programmierung in Java Vorlesung 24: Reflection 1 SS 2006 Prof. Dr. Frank M. Thiesing, FH Osnabrück Um ein Objekt anzulegen, eine seiner Methoden

Mehr

Technische Dokumentation SilentStatistikTool

Technische Dokumentation SilentStatistikTool Technische Dokumentation SilentStatistikTool Version 1.0 Marko Schröder 1115063 Inhalt Einleitung... 3 Klasse Program... 3 Klasse ArgumentHandler... 3 Bereitgestellte Variablen... 3 Bereitgestellte Methoden...

Mehr

2. Hintergrundverarbeitung in Android: Services und Notifications

2. Hintergrundverarbeitung in Android: Services und Notifications 2. Hintergrundverarbeitung in Android: Services und Notifications Übersicht 2. Hintergrundverarbeitung in Android: Services und Notifications Übersicht: In Mobis 1: Threads; hier genauerer Blick auf Services

Mehr

Funktionen in PHP 1/7

Funktionen in PHP 1/7 Funktionen in PHP 1/7 Vordefinierte Funktionen in PHP oder vom Entwickler geschriebene Funktionen bringen folgende Vorteile: gleiche Vorgänge müssen nur einmal beschrieben und können beliebig oft ausgeführt

Mehr

Einführung in die Cross-Plattform Entwicklung Das Intel XDK

Einführung in die Cross-Plattform Entwicklung Das Intel XDK Einführung in die Cross-Plattform Entwicklung Das Intel XDK Einführung Dieses Hands-on-Lab (HOL) macht den Leser mit dem Intel XDK vertraut. Es wird Schritt für Schritt die erste eigene Hybrid-App entwickelt

Mehr

Java-Schulung Grundlagen

Java-Schulung Grundlagen Java-Schulung Grundlagen Java 2 Standard Edition JDK 5 / 6 31.05.2008 Marcel Wieczorek 1 Themenübersicht Basiswissen Objektorientierung Datentypen Fehlerbehandlung Sonstiges Einführung Klassen, Strings

Mehr

Programmieren in C. Operatoren, Variablen und deren Sichtbarkeit. Prof. Dr. Nikolaus Wulff

Programmieren in C. Operatoren, Variablen und deren Sichtbarkeit. Prof. Dr. Nikolaus Wulff Programmieren in C Operatoren, Variablen und deren Sichtbarkeit Prof. Dr. Nikolaus Wulff Auswertung von Ausdrücken Was passiert wenn ein Ausdruck wie z. B. int y,x=2; y = ++x * x++; im Computer abgearbeitet

Mehr

5.1 Bestehende Projekte bearbeiten 79 5.2 Neue Projekte erstellen 85

5.1 Bestehende Projekte bearbeiten 79 5.2 Neue Projekte erstellen 85 Projekte per DOM bearbeiten KAPITEL 5 5.1 Bestehende Projekte bearbeiten 79 5.2 Neue Projekte erstellen 85 Bisher haben wir uns angesehen, wie List & Label mit Ihren Daten bekannt gemacht werden kann und

Mehr

Einführung in die Java- Programmierung

Einführung in die Java- Programmierung Einführung in die Java- Programmierung Dr. Volker Riediger Tassilo Horn riediger horn@uni-koblenz.de WiSe 2012/13 1 Wichtig... Mittags keine Pommes... Praktikum A 230 C 207 (Madeleine + Esma) F 112 F 113

Mehr

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden. Einfache Ein- und Ausgabe mit Java 1. Hallo-Welt! Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden. /** Die Klasse hello sendet einen

Mehr

Programmieren I. Prinzipieller Ablauf. Eigenschaften von JAVA. Source-Code Javac Bytecode. Java Virtual Machine (Java, Browser, Appletviewer)

Programmieren I. Prinzipieller Ablauf. Eigenschaften von JAVA. Source-Code Javac Bytecode. Java Virtual Machine (Java, Browser, Appletviewer) Programmieren I Grundlagen von JAVA Dr. Klaus Höppner Hello World in JAVA Hochschule Darmstadt WS 2007/2008 Elementare Datentypen 1 / 17 2 / 17 Eigenschaften von JAVA Prinzipieller Ablauf Plattform-und

Mehr

Hochschule Niederrhein Grundlagen der Prof. Dr. Nitsche Fachbereich 03 Java Programmierung Bachelor Informatik SS 2015 Übung 1. Grundlagen von Java

Hochschule Niederrhein Grundlagen der Prof. Dr. Nitsche Fachbereich 03 Java Programmierung Bachelor Informatik SS 2015 Übung 1. Grundlagen von Java Grundlagen von Java Aufgabe 1: Typen und Zuweisungen in Java Welche der folgenden Java-Anweisungen sind fehlerhaft? Handelt es sich um einen Compiler- oder einen Laufzeitfehler? Anmerkung: Folgefehler

Mehr

Unterprogramme, Pointer und die Übergabe von Arrays

Unterprogramme, Pointer und die Übergabe von Arrays Unterprogramme, Pointer und die Übergabe von Arrays Unterprogramme Wie schon im Abschnitt über Funktionen erwähnt, versteht man unter einem Unterprogramm im engeren Sinn eine Prozedur, welche die Werte

Mehr

Institut fu r Informatik

Institut fu r Informatik Technische Universita t Mu nchen Institut fu r Informatik Lehrstuhl fu r Bioinformatik Einfu hrung in die Programmierung fu r Bioinformatiker Prof. B. Rost, L. Richter WS 2013 Aufgabenblatt 3 18. November

Mehr

Java: Eine Übersicht. Dennis Giffhorn. Lehrstuhl für Programmierparadigmen Universität Karlsruhe

Java: Eine Übersicht. Dennis Giffhorn. Lehrstuhl für Programmierparadigmen Universität Karlsruhe Java: Eine Übersicht Dennis Giffhorn Lehrstuhl für Programmierparadigmen Universität Karlsruhe Allgemeines Objektorientiert Syntaxfamilie von C/C++ Statisch getypt Entwickelt von Sun Microsystems class

Mehr

Dr. Monika Meiler. Inhalt

Dr. Monika Meiler. Inhalt Inhalt 5 Referenzdatentypen - Felder... 5-2 5.1 Eindimensionale Felder - Vektoren... 5-3 5.1.1 Vereinbarung... 5-3 5.1.2 Referenzen sind keine Felder... 5-4 5.1.3 Kopieren eindimensionaler Felder... 5-6

Mehr

Probeklausur: Programmierung WS04/05

Probeklausur: Programmierung WS04/05 Probeklausur: Programmierung WS04/05 Name: Hinweise zur Bearbeitung Nimm Dir für diese Klausur ausreichend Zeit, und sorge dafür, dass Du nicht gestört wirst. Die Klausur ist für 90 Minuten angesetzt,

Mehr

Grundlagen der Programmiersprache C++

Grundlagen der Programmiersprache C++ / TU Braunschweig Grundlagen der Programmiersprache C++ Um den Studierenden den Einstieg in die FE-Programmierung zu erleichtern werden die wesentlichen Elemente eines C-Programmes beschrieben, soweit

Mehr

Zero Effort Backup (ZEB) automatische Datensicherung über das Internet

Zero Effort Backup (ZEB) automatische Datensicherung über das Internet Ralph Lehmann. Computerservice und IT-Beratung. Kochstraße 34. 04275 Leipzig Ralph Lehmann Computerservice und IT-Beratung Kochstraße 34 04275 Leipzig Ralph Lehmann Computerservice und IT-Beratung Tel.:

Mehr

5. Tutorium zu Programmieren

5. Tutorium zu Programmieren 5. Tutorium zu Programmieren Dennis Ewert Gruppe 6 Universität Karlsruhe Institut für Programmstrukturen und Datenorganisation (IPD) Lehrstuhl Programmierparadigmen WS 2008/2009 c 2008 by IPD Snelting

Mehr

4 Codierung nach Viginere (Lösung)

4 Codierung nach Viginere (Lösung) Kapitel 4 Codierung nach Viginere (Lösung) Seite 1/14 4 Codierung nach Viginere (Lösung) 4.1 Einführung Blaise de Vigenère lebte von 1523 bis 1596 in Frankreich und war nach dem Studium bei verschiedenen

Mehr

Objektorientierte Programmierung. Kapitel 12: Interfaces

Objektorientierte Programmierung. Kapitel 12: Interfaces 12. Interfaces 1/14 Objektorientierte Programmierung Kapitel 12: Interfaces Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2012/13 http://www.informatik.uni-halle.de/ brass/oop12/

Mehr

Innere Klassen in Java

Innere Klassen in Java Innere Klassen in Java SS 2012 Prof. Dr. Margarita Esponda Innere Klassen Klassen- oder Interfacedefinitionen können zur besseren Strukturierung von Programmen verschachtelt werden Eine "Inner Class" wird

Mehr

Erstellung von Bibliotheken in CoDeSys V3

Erstellung von Bibliotheken in CoDeSys V3 Dokument Version 2.0 3S - Smart Software Solutions GmbH Seite 1 von 10 INHALT 1 EINFÜHRUNG 3 2 BIBLIOTHEKSKONZEPT IM DETAIL 4 2.1 Kategorien von Bibliotheken 4 2.1.1 System 4 2.1.2 Internal 4 2.1.3 Application

Mehr

Objective-C CheatSheet

Objective-C CheatSheet App-Templates: Erstellt automatisch einen Navigation Controller mit editierbarem UITableView und DetailView, der bei Klick auf einzelne UITableViewCell angezeigt wird. Kreiert einen GLKitViewController

Mehr

Die Programmiersprache C99: Zusammenfassung

Die Programmiersprache C99: Zusammenfassung Die Programmiersprache C99: Zusammenfassung Jörn Loviscach Versionsstand: 7. Dezember 2010, 19:30 Die nummerierten Felder sind absichtlich leer, zum Ausfüllen in der Vorlesung. Videos dazu: http://www.youtube.com/joernloviscach

Mehr

Einführung in die Programmierung Arrays, Zeiger, Strings. Arvid Terzibaschian

Einführung in die Programmierung Arrays, Zeiger, Strings. Arvid Terzibaschian Einführung in die Programmierung Arvid Terzibaschian 1 Arrays 2 Arrays: Motivation Gegeben: monatliche Durchschnittstemperaturen der letzten 5 Jahre Gesucht: Mittelwerte für Jahre, Monate, Jahreszeiten,

Mehr

Inhalt. Max Lini. ax. inie. Einleitung... VII

Inhalt. Max Lini. ax. inie. Einleitung... VII rst Inhalt Einleitung....................................................... VII 1 Schöne neue Welt: Objektorientierte Programmierung in PHP 5.............. 1 Klassen, Interfaces und Objekte...................................

Mehr

Anzeige des Java Error Stack in Oracle Forms

Anzeige des Java Error Stack in Oracle Forms Anzeige des Java Error Stack in Oracle Forms (Version 2.0) Juni 2008 Autoren: Jürgen Menge / Thomas Robert Seite 1 von 7 Oracle Forms bietet seit der Version 6i die Möglichkeit, serverseitig Java-Klassen

Mehr

Vorkurs Informatik WiSe 15/16

Vorkurs Informatik WiSe 15/16 Java 1 Dr. Werner Struckmann / Stephan Mielke, Jakob Garbe, 12.10.2015 Technische Universität Braunschweig, IPS Überblick Organisatorisches Arbeitsablauf Hello! 12.10.2015 Dr. Werner Struckmann / Stephan

Mehr

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck Javadoc Programmiermethodik Eva Zangerle Universität Innsbruck Überblick Einführung Java Ein erster Überblick Objektorientierung Vererbung und Polymorphismus Ausnahmebehandlung Pakete und Javadoc Spezielle

Mehr