- Christian-Albrechts

Werbung
Instrumentierung von Android
Anwendungen in ExplorViz
Bachelorarbeit
Jan Witzany
30. September 2016
Christian-Albrechts-Universität zu Kiel
Institut für Informatik
Arbeitsgruppe Software Engineering
Betreut durch: Prof. Dr. Wilhelm Hasselbring
M.Sc. Christian Zirkelbach
Eidesstattliche Erklärung
Hiermit erkläre ich an Eides statt, dass ich die vorliegende Arbeit selbstständig verfasst
und keine anderen als die angegebenen Quellen und Hilfsmittel verwendet habe.
Kiel, 30. September 2016
ii
Zusammenfassung
Google’s Android Betriebssystem ist das meist verwendeten Betriebssystem für Smartphones. Durch den wachsenden Markt gibt es viele Anwendungsentwickler.
Wie viel andere Programme auch, werden Android Anwendungen im Laufe der Entwicklung häufig größer und komplexer. Hinzu kommt noch, dass oftmals Programme nicht
ausreichend dokumentiert sind.
Statische Analysen über den Sourecode sind in der Regel langwierig und nicht ausreichend. Wohingegen eine dynamische Analyse viele Vorteile mit sich bringt, so wird nur
der Programmcode betrachtet, welcher tatsächlich genutzt wird. Diesen Ansatz verfolgt
das Live Trace Visualisierungs Programm ExplorViz. Durch die Online-Analyse und Live
Visualisierung gibt ExplorViz ein schnelles Feedback auf die getätigten Eingaben. In dieser
Arbeit behandeln wir das Monitoring von Android Anwendungen in ExplorViz. Wir bauen
dabei auf bestehende Komponenten auf und passen ExplorViz für Android an. Es ist
uns gelungen den Sourcecode einer Applikation mit der erstellten Monitoring-Library zu
instrumentieren und in ExplorViz visuell darzustellen. Weiterhin haben wir Ansätze für
das Instrumentieren auf Basis von APKs formuliert.
iii
Inhaltsverzeichnis
1
Einleitung
1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Ziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1
2
3
2
Grundlagen und Technologien
2.1 Android . . . . . . . . . . . . . . . . . . . .
2.2 Build-Management-Tool . . . . . . . . . . .
2.3 Instrumentierung . . . . . . . . . . . . . . .
2.3.1 Aspektorientierte Programmierung
2.4 ExplorViz . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
7
7
9
Monitoring Android Applikationen
3.1 Manuelle Instrumentierung . . . . . . . .
3.2 Instrumentation-Klasse . . . . . . . . . . .
3.3 BCEL . . . . . . . . . . . . . . . . . . . . .
3.4 Soot . . . . . . . . . . . . . . . . . . . . . .
3.5 AspectBench Compiler . . . . . . . . . . .
3.6 dex2jar . . . . . . . . . . . . . . . . . . . .
3.7 jadx . . . . . . . . . . . . . . . . . . . . . .
3.8 APKtool . . . . . . . . . . . . . . . . . . .
3.9 Auswahl der Instrumentierungs-Technik
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
12
12
13
13
13
14
14
14
15
3
.
.
.
.
.
.
.
.
.
4
Monitoring in ExplorViz
17
4.1 Aktueller Stand im ExplorViz . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2 Entwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5
Implementierung
5.1 Sourcecode Instrumentierung . . .
5.1.1 Build-Skript . . . . . . . . .
5.2 APK Instrumentierung . . . . . . .
5.2.1 Reverse Engineering . . . .
5.2.2 Probleme . . . . . . . . . . .
5.3 Android-Monitoring in ExplorViz
5.4 Kompatibilität mit Android . . . .
5.5 Aspekte . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
23
23
25
25
25
25
26
29
v
Inhaltsverzeichnis
5.6
Variable Pointcuts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6
Evaluation
31
7
Verwandte Arbeiten
7.1 Kieker Monitoring Framework . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 SPASS-meter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 Android Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
35
35
36
8
Fazit und Ausblick
37
8.1 Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
8.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Bibliografie
39
Anhang
41
vi
Kapitel 1
Einleitung
1.1.
Motivation
Das Betriebssystem Android1 war 2015 mit einem Marktanteil von über 82% das meist
verwendete System für Smartphones [IDC 2015]. Anwendungen für das Betriebssystem werden in der Programmiersprache Java geschrieben und zu Androids eigenem Dateiformat
Android package (APK) kompiliert. Durch die hohe Verbreitung kam in den letzten Jahren
eine Vielzahl von neuen Applikationen von verschiedenen Entwicklern auf den Markt. Im
Laufe der Entwicklung einer Anwendung werden der Programmcode und die einzelnen
Module üblicherweise umfangreicher und komplexer. Häufig kommt dazu noch eine mangelhafte oder fehlende Dokumentation. Dieses Problem wird bei Legacy-Anwendungen,
welche nur noch gewartet werden und die ursprünglichen Entwickler unter Umständen
gar nicht mehr an dem Projekt beteiligt sind, verstärkt. Eine statische Quellcode-Analyse
kann sehr zeitaufwendig werden. Einen anderen Ansatz wählt ExplorViz2 .
Um das Verständnis für komplexere Anwendungen zu erleichtern, wurde ExplorViz entwickelt[Fittkau u. a. 2013a]. ExplorViz ist eine Software zum Monitoring und zur Visualisierung von Applikationen und deren internen Kommunikation zur Laufzeit, sowie das
Messen des Ressourcenverbrauchs. So wurde ExplorViz zum Beispiel für eine PerformanceAnalyse für eine in Perl geschriebene Legacy-Software eingesetzt .
Nativ wird bereits die Analyse von Java-Programmen unterstützt. Da Android Applikationen hauptsächlich in der Java geschrieben werden, wird zunächst geklärt, inwiefern die
bestehenden Monitoring Methoden für die Instrumentation verwendet werden können,
und welche spezifischen Anpassungen vorgenommen werden müssen.
1 https://www.android.com
2 https://www.explorviz.net
1
1. Einleitung
1.2.
Ziele
In diesem Kapitel werden die Ziele dieser Arbeit erläutert.
Ziel 1: Instrumentierung von Android Anwendungen mit der Monitoring Komponente von ExplorViz
Das Hauptziel dieser Arbeit besteht darin, die Monitoring-Komponente von ExplorViz so zu
erweitern, dass diese auch für das Monitoring von Android Anwendungen eingesetzt werden kann. Die Komponente soll in bereits bestehende Android-Projekten, Sourcecode oder
APK eingebunden werden und so zur Laufzeit Informationen über die Methodenaufrufe
und Systemressourcen sammeln. Diese gesammelten Informationen sollen in MonitoringRecords zusammengefasst werden und für die Analyse an den ExplorViz-Server geschickt
werden, um eine Visualisierung zu ermöglichen. Den Entwicklern soll es mit geringem
Aufwand möglich sein ihre Android Applikation instrumentieren zu können.
Ziel 1.1: Erweiterung der Monitoring Komponente von ExplorViz Die bereits bestehende Monitoring-Komponente von ExplorViz soll so erweitert werden, dass sie auch
für die Instrumentierung von Android verwendet werden kann. Es sind bereits Ansätze
dafür vorhanden. Diese sollen angepasst werden um eine einfache Instrumentierung von
Android-Anwendungen zu ermöglichen.
Ziel 1.2: Instrumentierung von Android Sourcecode Die bestehende Implementierung
von ExplorViz verwendet für die Instrumentierung einen Ansatz, der es ermöglicht zur
Laufzeit Methoden zum Messen (Probes) in den auszuführenden Code einzuweben. Diese
Möglichkeit bietet Android nicht an und das instrumentierte Programm muss bereits
zur Installation vollständig vorliegen. Für diese Arbeit muss ein anderer Ansatz gewählt
werden.
Ziel 1.3: Instrumentierung von APKs Android Anwendungen werden zwar in Java programmiert, besitzen aber ein eigenes Dateiformat. Der Sourcecode wird bei der Erstellung
zu Android packages (APK) kompiliert. Wenn der Sourcecode nicht zu Verfügung steht,
sollte es möglich sein, die App auch nur auf Grundlage der APK zu instrumentieren.
Ziel 2: Evaluation der Instrumentierung von Android Apps
Die neu erstellte Komponente für das Android-Monitoring wird an der Android Applikation Babsi getestet und die Ergebnisse ausgewertet und diskutiert. Es wird zum einen auf die
generelle Funktionalität der Monitoring-Komponente geprüft. Wie bei der Darstellung von
Java Programmen soll es ExplorViz möglich sein die, Klassen und Traces zur Laufzeit der
Applikation zu analysieren und darzustellen. Zum anderen wird auf die Usability geachtet,
2
1.3. Aufbau der Arbeit
inwiefern Entwickler ihre App ohne großen Aufwand Instrumentieren und Analysieren
können. Dabei wird die Monitoring-Komponente auch mit unterschiedlichen Android
Versionen getestet, um eine Kompatibilität zu Altsystemen zu gewährleisten.
1.3.
Aufbau der Arbeit
Im folgenden Kapitel werden zunächst einige Grundlagen zum Arbeiten mit Android
und Konzepte für die Instrumentierung erklärt. Anschließend wird im Kapitel 3 auf
unterschiedliche Ansätze zum Instrumentieren von Android Applikationen eingegangen.
Im Kapitel 4 wird der aktuelle Stand von ExplorViz und insbesondere die MonitoringKomponente dargelegt. Es wird auch ein Entwurf für das Instrumentieren von Android
Apps mit ExplorViz vorgestellt. Im nachfolgenden Kapitel 5 wird die Implementierung der
Monitoring-Komponente beschrieben. Anschließend findet im Kapitel 6 eine Evaluation
statt. Kapitel 7 behandelt verwandte Arbeiten. Das letzte Kapitel beschäftigt sich mit dem
Fazit und einem Ausblick.
3
Kapitel 2
Grundlagen und Technologien
In diesem Kapitel wird zunächst auf die Eigenschaften von Android eingegangen. Anschließend werden mit Ant und Gradle zwei Build-tools vorgestellt, welche im Laufe
dieser Arbeit für die ExplorViz-Library und das Monitoring von Android Anwendungen
verwendet werden. Danach wird auf das Programmierparadigma der Aspektorientierung
und dessen Implementierung mit AspectJ erläutert. Am Ende wird ein kurzer Überblick
über ExplorViz gegeben.
2.1.
Android
Android ist ein auf dem Linux-Kernel basierendes Betriebssystem für mobile Endgeräte.
Das im Jahre 2003 gründete Unternehmen Android, Inc. wurde 2005 von Google gekauft und
das Betriebssystem seitdem kontinuierlich weiterentwickelt. Die Anwendungen sind in der
Programmiersprache Java geschrieben, wobei nicht alle Libraries und application programming interfaces (APIs) unterstützt werden. Derzeit unterstützt die aktuelle Android-Version
die Syntax aus Java Version 7. Weiterhin können Teile der Applikation aus Effizienzgründen
auch in C oder C++ programmiert werden. In dieser Arbeit befassen wir uns allerdings mit
dem Monitoring von Applikationen basierend auf Java Sourcecode.
Im Rahmen der Weiterentwicklung des Betriebssystems unterscheiden sich die einzelnen
Versionen von ihren Eigenschaften, und die Funktionsweise wird mit unterschiedlichen
Android APIs erweitert. Um eine Abwärtskompatibilität zu gewährleisten, kann eine
Minimum- und eine Ziel-Version angegeben werden, die das Kompilerlevel bestimmt und
so eine Installation auf Geräten mit verschiedenen Android-Versionen erlaubt. Die Android
Version für die kompiliert wird, wird mit dem API Level angegeben. So hat die aktuelle
Android Version 7.0 das API Level 24.
Im Gegensatz zu einem Java-Programm, welches zu Bytecode kompiliert wird um
anschließend auf der Stack-basierten Java Virtual Machine (JVM) ausgeführt zu werden,
verfügt Android über eine eigene virtuelle Maschine, die Dalvik Virtual Machine (DVM).
Diese basiert aus Performancegründen auf Register anstelle eines Stacks. Deshalb muss der
Build-Prozess um einen Schritt erweitert werden und der Java Bytecode mit dem dx-tool zu
einer Dalvik executable (classes.dex) kompiliert werden. Die einzelnen .dex-Dateien werden
später in einem Executable zusammengefasst und mit weiteren Ressourcen und Metadaten
5
2. Grundlagen und Technologien
in das Android Dateiformat Android Package (APK) gepackt. Eine APK kann später auf
dem Android Betriebssystem installiert werden. Dabei wird der Bytecode zur Laufzeit (justin-time) in Maschinensprache übersetzt und ausgeführt. Seit dem im November 2014
erschienenen Android 5.0 wird nicht mehr die DVM, sondern die Android Runtime (ART)
verwendet. Hier wird der Bytecode nur einmalig, während der Installation der Anwendung
in Maschinencode übersetzt (ahead-of-time). Um ältere Anwendungen zu unterstützen wird
weiterhin das .dex-Format beibehalten.
Um den Autoren, der Android Applikation zu verifizieren, muss die Applikation
signiert werden [Arzt u. a. 2013]. Jedes Mal, wenn eine Änderung im Programmcode
vorgenommen wurde, muss die APK neu kompiliert werden, und anschließend mit dem
gleichen Schlüssel signiert werden. Dies dient dazu, dass sichergestellt wird, dass jede
Änderung vom Autor autorisiert ist. Wenn sich der Schlüssel ändert, wird die Applikation
vom System als eine andere Applikation angesehen.
Während der Kompilierung in Bytecode ist es möglich Programme wie zum Beispiel
ProGuard1 zu verwenden. Diese können zum einen den benötigten Speicherplatz reduzieren, indem nicht benötigte Teile des Programmes und der Libraries entfernt werden. Zum
anderen soll der Sourcecode verschleiert und so ein Reverse Engineering erschwert werden.
Dazu können manche Klassen, Methoden und Variablen umbenannt werden, um nicht
direkt von ihrem Namen auf den verwendeten Zweck schließen zu können.
2.2.
Build-Management-Tool
Um Entwicklungs- und Kompilierungsschritte zu definieren und strukturieren, können
Build-Management-Tools eingesetzt werden. Diese ermöglichen ein automatisches Kompilieren in bestimmter Ausführung und Abhängigkeit.
Apache Ant 1 ist eine in Java geschrieben Library zur Erstellung und deren Automatisierung von Anwendungen. Dafür werden einzelne Aufgaben in sogenannten Tasks
definiert, welche je nach Bedarf in gewünschter Reihenfolge ausgeführt werden können.
Es können sowohl vordefinierte als auch eigene Tasks verwendet werden. Standardmäßig
wird die Verwendung der benötigten Tasks in einem XML-Dokument mit dem Namen
build.xml angeben und dieses Skript dann ausgeführt. ExplorViz verwendet derzeit Ant
zum Erstellen der Monitoring-Library.
Gradle 3 ist ein auf Java basierendes Build-tool zum Automatisieren von Build-Prozessen.
Seit 2013 wird es offiziell von Google für die Entwicklung von Android Anwendungen
eingesetzt. Beim Erstellen eines neuen Projektes in der Entwicklungsumgebung Android
1 http://proguard.sourceforge.net
1 http://ant.apache.org/
3 https://gradle.org/
6
2.3. Instrumentierung
Studio wird automatisch ein Gradle-Skript erstellt und die Ordnerstruktur danach angepasst. Es ist aber auch möglich ältere Projekte, welche zum Beispiel noch Maven verwenden
in ein Gradle-Projekt zu importieren. Dabei hat jedes Projekt und Unterprojekt ein eigenes
Gradle-Skript. Unterprojekte erben Eigenschaften von dem hierarischen überstehenden
Projekten.
Gradle wird in einer domänenspezifische Sprache (DSL),welche auf Groovy basiert, geschrieben und akzeptiert jeden validen Groovy-Ausdruck. So können vorhandene oder auch
selbstgeschriebene Gradle-Plugins angewendet werden. Weiterhin können auch Ant Tasks
und Skripte eingelesen und ausgeführt werden.
2.3.
Instrumentierung
Beim Monitoring sollen bestimmte Teile einer Anwendung überwacht und Werte aufgezeichnet werden. Diese sollen gesammelt und anschließend analysiert werden. Dazu ist
es nötig, Funktionen zu implementieren, die diese Aufgabe übernehmen. Diesen Vorgang
nennt man Instrumentierung. Ein naiver Ansatz ist es diese Funktionen manuell an den
entsprechenden Stellen im Code einzufügen. Dies hat den Nachteil, dass jeder Messpunkt
einzeln angegeben werden muss. Zudem ist die Funktionsweise dieser Methoden häufig
sehr ähnlich, sodass redundanter Code erzeugt werden würde. Außerdem wird dabei die
Instrumentierungs-Logik mit der Implementierung des eigentlichen Programmes vermischt
und widerspricht dem Seperation of concerns. Dies kann die Wartbarkeit des Programmes
stark einschränken.
2.3.1.
Aspektorientierte Programmierung
Es ist also von Vorteil die Instrumentierung zu modularisieren und getrennt vom Sourcecode der Anwendung zu implementieren. Als Ansatz dazu hat unter anderem Kiczales, mit
Aspektorientierte Programmierung (AOP) ein Programmierparadigma eingeführt ( [Kiczales
u. a. 1997]). Hier wird unter Berücksichtigung des cross-cutting concerns der Code für die
Instrumentierung vom eigentlichen Sourcecode der Applikation getrennt. Dazu werden
die Funktionen als sogenannte Aspekte definiert. Diese werden an definierten Stellen in den
Sourcecode eingewoben.
Das Einweben kann beim Kompilieren (Compile-time weaving), nach dem Kompilieren (Postcompile weaving) oder zur Laufzeit (Load-time weaving) geschehen. Für Android ist ein
Einweben zur Laufzeit nicht möglich.
ExplorViz verwendet mit AspectJ1 [Kiczales u. a. 2001] eine Erweiterung von Java für
den aspektorientierten Ansatz. Aspekte werden in Java-Klassen geschrieben und mit
Annotationen gekennzeichnet. Die Implementierung umfasst vier Schlüsselwörter:
1 https://eclipse.org/aspectj
7
2. Grundlagen und Technologien
Join Poin beschreibt einen Punkt in der ausgeführten Anwendung an dem zusätzlicher
Code mit eingewoben werden kann.
Pointcut definiert und wählt aus, an welchem JoinPoint Code eingewoben werden soll.
Es können verschiedene Schlüsselwörter verwendet werden, sowie reguläre Ausdrücke.
So steht execution(* *..*(..) für jeden Methodenaufruf und execution(*..*.new(..)) für jeden
Konstruktoraufruf mit beliebiger Anzahl von Argumenten. Mit within kann ein package
oder auch eine spezielle Klasse angegeben werden. Außerdem stehen für die Definition
eines Pointcutes mit &&, || und ! das logische Und, Oder beziehungsweise Nicht zur
Verfügung.
Advice nennt sich der Code der zusätzlich eingewoben wird. Zusätzlich wird noch mit
angegeben, an welcher Stelle, relativ zum ausgewählten JoinPoint, der zusätzliche Code
eingeworben werden soll: before(), after(), around().
Aspekt fasst Pointcuts und Advice in einer Klasse zusammen. Ab AspectJ 5 werden
Annotationen erlaubt und es ist möglich Aspekte als Java-Klassen zu definieren. Frühere
Versionen verwendeten mit .aj eigene Dateien.
Pointcuts definieren also, an welchen Punkten (JoinPoint) in einem Programm neuer
Code (Advice) eingefügt werden soll. Das Ganze wird in einem Aspekt definiert. Listing 2.1
beschreibt beispielhaft einen solchen Aspekt.
Listing 2.1. Aspect mit Annotation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Aspect
public class Aspect{
@Pointcut("execution(* *(..) && !within(explorviz.**)")
public void methodExecution(){}
@Around("pointcut()")
public void aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
//code before execution of method
JoinPoint.proceed()
//code after execution of method
}
8
2.4. ExplorViz
Die Annotation @Aspect gibt an, dass es sich um einen Aspekt handelt. Mit @Pointcut
wird ein Pointcut definiert und in Zeile 8 angwendet. Der Around-Advice wird ausgeführt,
wenn der JoinPoint erreicht ist und hat Kontrolle darüber, wann und ob die eigentliche
Methode ausgeführt wird. Mit JoinPoint.proceed() muss explizit angeben werden, dass die
Methode ausgeführt werden soll.
2.4.
ExplorViz
ExplorViz ermöglicht eine live Trace Visualisierung von großen Softwarelandschaften [Fittkau 2015]. Die Software verfügt über zwei verschieden Perspektiven. Zum einen die Landschaftsperspektive, welche mit UML Elementen ganz Softwarelandschaften darstellen kann
und zum anderen die Applikationsperspektive, welche eine 3D-Softwarestadtmetapher
verwendet. In der Applikationsperspektive werden Packages als grüne und Klassen als
blaue Kästen dargestellt (vgl. Abbildung 2.1). Von der Höhe der Klassen-Kästen gibt die
Anzahl der aktiven Instanzen an. Die Methodenaufrufe, die außerhalb einer Klasse liegen
werden mit orangenen Linien gekennzeichnet. Die Breite der Linien drückt dabei die
Häufigkeit der entsprechenden Methode aus [Fittkau u. a. 2016]. In der Live-Ansicht kann
jeder Zeit pausiert und zu einen zurückliegenden Zeitpunkt gesprungen werden.
Abbildung 2.1. ExplorViz: Applikationsperspektive entnommen aus [Fittkau u. a. 2013a]
9
2. Grundlagen und Technologien
Das Programm besteht im Wesentlichen aus drei Komponenten: die MonitoringKomponente, die Analyse-Komponente und die Server-Komponente. Zur Laufzeit wird
mit Hilfe von AspectJ die Monitoring-Library in die Applikation eingewoben. Diese erstellt
Monitoring-Records über Methodenaufrufe und Ressourcenverbrauch des Programms. Diese
Records werden über eine TCP-Verbindung an die Analyse-Komponente geschickt. In der
Analyse-Komponente werden mit Hilfe der Records sogenannte Traces erstellt, die in einer
Visualisierung-Komponente graphisch dargestellt werden können. Durch einen Monitoring
Data Adapter lassen sich von anderen Programmen, wie zum Beispiel Kieker [van Hoorn u. a.
2012], erzeugte Records zur Offline-Analyse nutzen. So ist es auch möglich andere Sprache
als Java, wie zum Beispiel C, C++, Perl oder COBOL mit ExplorViz zu instrumentieren.
10
Kapitel 3
Monitoring Android Applikationen
Im folgenden Kapitel werden wir verschiedene Möglichkeiten aufführen um unser Ziel,
das Monitoring von Android Anwendungen, zu erreichen. Zuerst betrachten wir dafür
Techniken zum Instrumentieren von Android Anwendungen. Anschließend werden wir
uns für eine Anwendung entscheiden.
Android unterstützt nicht das Modifizieren des Bytecodes zur Laufzeit. Weiterhin erschwert
die Struktur der dex-Datei die direkte Instrumentierung. Jedoch gibt es zahlreiche Ansätze,
die mit einer zwischenform von einer dex-Datei arbeiten. Dazu betrachten wir zunächst
den Build-Prozess (Abbildung 3.1) zum Erstellen einer APK.
Abbildung 3.1. Vereinfachte Darstellung des Build-Prozess zum Instrumentieren
Die Applikation ist in Java geschrieben und liegt als unkompilierter Sourcecode vor.
11
3. Monitoring Android Applikationen
Der Java-Quellcode wird anschließend mit dem Java Compiler (javac) in Java-Bytecode
übersetzt. Um das Programm auf die Architektur von Android anzupassen, wird dieser
anschließend mit dem dx-tool in die Dalvik executable übersetzt.
Da es sich beim instrumentierten Java-Code um korrekte Java-Ausdrücke handelt, ist es
möglich die Instrumentierung vor dem Übersetzen in das Dex-Format, mit Java-Klassen
durchzuführen. Dafür kann der Java-Quellcode vor dem ersten Kompelierungsschritt
verwendet werden. Ein anderer Ansatz wäre erst die Übersetzung in Java-Bytecode vorzunehmen, und anschließend mit diesem die Instrumentierung durchzuführen.
Wir haben bereits im Abschnitt 2.3 den Ansatz der aspektorientierten Programmierung
kennengelernt. Die dazu vorgestellte Java-Erweiterung AspektJ kann sowohl als JavaCompiler angewendet werden und Sourcecode und Aspekte zur Compile-Zeit übersetzen
und einweben, als auch mit Java-Bytecode arbeiten. Im Folgenden stellen wir eine Auswahl
an Techniken und Frameworks für das Instrumentieren für Java vor.
3.1.
Manuelle Instrumentierung
Eine Möglichkeit Java-Sourecode zu instrumentieren ist es manuell Änderungen vorzunehmen. Der Entwickler muss per Hand neuen Programmcode in den Sourcecode einfügen.
Ein Nachteil ist, dass häufig eine Vielzahl an Änderungen vorgenommen werden muss und
diese Änderungen direkt in den Source-Dateien vorgenommen wird. Dies kann recht unübersichtlich werden, da die eigentliche Logik des Programmes mit dem Monitoring-Advice
vermischt wird. Eine Fehlerquelle könnte hier sein, dass nötige Änderungen übersehen
werden. Außerdem verschlechtert dies auch die Wartbarkeit des Quellcodes.
3.2.
Instrumentation-Klasse
Android bietet seit dem API Level 1 eine Instrumentation1 Klasse an. Diese wird im AndroidManifest festgelegt und dient als eine Basisklasse für das Monitoring von Interaktionen
der Anwendung mit dem System. Das Instrumentierungs-Objekt wird vor dem Start der
Anwendung instanziiert. Jedoch ist diese Klasse nur für das Schreiben und Testen von
entwickelten Android Applikationen gedacht und bietet für unsere Ziele nicht genügen
Funktionalität, wie zum Beispiel reguläre Ausdrücke, wie es unter anderem bei dem
Pointcuts mit AspectJ möglich ist.
1 https://developer.android.com/reference/android/app/Instrumentation.html
12
3.3. BCEL
3.3.
BCEL
BCEL 2 ist ein Akronym für Byte Code Engineering Library. Das Projekt beinhaltet eine
API zum Modifizieren von Java-Bytecode. Es wird in unterschiedlichen Projekten, unter
anderem auch in dem AspectJ-Projekt, verwendet.
Hat der Entwickler nur die APK und keinen Zugriff auf den Java-Sourcecode, sind die
oben beschrieben Ansätze nicht ohne weiteres möglich. Deshalb stellten wir im Folgenden
einige Technologien zum Arbeiten mit APKs und der darin enthaltenden classes.dex.
3.4.
Soot
Das Framework Soot3 , kann zum Analysieren und Instrumentieren von Java- und AndroidProgrammen verwendet werden. Soot akzeptiert als Ein- und Ausgabe unter anderem .java,
.dex und APK Dateien, indem es intern alles zu Jimple-Zwischendarstellungen übersetzt.
Jimple ist eine vereinfachte Java Sourcecode Version mit maximal drei typisierten lokalen
Variablen pro Codezeile. Aspekte werden nicht in Java-Syntax, sondern in Jimple-Syntax
definiert.
3.5.
AspectBench Compiler
Der AspectBench Compiler (abc)4 ist eine Neuentwicklung des AspectJ Compilers (ajc).
Anders als der ajc unterstützt der abc auch das AOP für Android-Anwendungen [Arzt
u. a. 2013]. Mit dem AspectBench Compiler können APK ohne Zwischenschritt direkt
instrumentiert werden. Dazu wird für das Back-Endintern das Soot Framework verwendet.
Dies übersetzt die dex.classes in eine Zwischenform und führt darauf die Instrumentierung
aus. Für die Definition von Aspekten wird wie bei AspectJ das Dateiformat .aj verwendet.
Anschließend wird mit Soot wieder eine APK erstellt.
Allerdings ist die Entwicklung eingestellt und das letzte offizielle Release wurde im April
2008 veröffentlicht. Deshalb unterstützt der AspectBench Compiler Java nur bis zu der
Version 5 und unter anderem nicht die Annotation-Syntax für das Schreiben von Aspekten.
2 https://commons.apache.org/proper/commons-bcel
3 https://sable.github.io/soot
4 www.sable.mcgill.ca/abc
13
3. Monitoring Android Applikationen
Im Folgenden stellen wir noch ein Programm vor, welches dex-Dateien in Java-Klassen
dekompilieren kann. Es können anschließend Techniken zum Instrumentieren von JavaBytecode verwendet werden (siehe Abbildung 3.1).
3.6.
dex2jar
Das Werkzeug dex2jar5 nimmt die dex-Datei als Eingabe und dekompiliert sie zu einer
JAR. Das dex2jar Programm wurde unter anderem in [Bartel u. a. 2012] und [El-Harake
u. a. 2014] verwendet, um den Code so zu verändern, sodass Werbung innerhalb der
Applikation blockiert wird. Allerdings besteht ein bedeutender Unterschied zwischen dem
Register-basierten Dalvik VM und der Stack-basierten Java VM und das Dekompilieren
funktioniert nicht immer fehlerfrei [El-Harake u. a. 2014].
3.7.
jadx
Das Priogramm jadx6 ist ein weiteres Dekompilierungs-Tool. Es lässt sich sowohl über
die Kommandozeile, als auch über eine GUI bedienen. Anders als dex2jar, unterstützt
jadx auch das Dekompilieren von APKs in Java-Source Dateien. Das dekompilieren von
Ressourcen funktioniert jedoch nur rudimentär und es wird ein weiteres Werkzeug für
diese Aufgabe empfohlen.
3.8.
APKtool
Das APKtool 7 ist ein Werkzeug zum Reverse Engineering von Android APKs. Mit dem
APKtool ist es möglich Resourcen und das AndroidManifest zu dekompilieren. Außerdem
unterstützt es das Dekompilieren von dex-Dateien zu smali code 1 , welches eine extra für
das Dekompilieren von Android entwickelte Sprache ist. Der dekompilierte smali code
kann modifiziert und anschließend mit dem APKtool wieder in eine APK packen.
5 https://github.com/pxb1988/dex2jar
6 https://github.com/skylot/jadx
7 https://ibotpeaches.github.io/Apktool
1 https://github.com/JesusFreke/smali
14
3.9. Auswahl der Instrumentierungs-Technik
3.9.
Auswahl der Instrumentierungs-Technik
Die obige Auswahl soll zeigen, dass es einige Werkzeuge und Ansätze zum Instrumentieren
von Android gibt. Wir entscheiden uns aufgrund der Vielfältigkeit und einfachen Handhabung für AspectJ. Ein wichtiger Punkt dabei ist auch, dass ExplorViz bereits AspectJ für
die Instrumentierung verwendet.
Für das Dekompilieren wählen wir bewusst kein konkretes Werkzeug aus, da das Erzeugen
der Java-Klassen nicht immer fehlerfrei ist. In unterschiedlichen Fällen kann es sinnvoll
sein eine Dekompilierungs-Technik der anderen vorzuziehen. Wir zeigen im Laufe dieser
Arbeit, wie die benötigten Schritte mit Jadx und dem APKtool funktionieren.
15
Kapitel 4
Monitoring in ExplorViz
Im folgenden Kapitel werden wir den aktuellen Stand für ExplorViz und insbesondere
die Monitoring-Komponente erläutern. Darauf aufbauend werden wir anschließend einen
Entwurf für eine Monitoring-Komponente entwickeln, die das Monitoring von Android
unterstützt.
4.1.
Aktueller Stand im ExplorViz
Das Monitoring und Visualisierungstool ExplorViz besteht, wie in (Abbildung 4.1) beschrieben, aus drei Komponenten: Monitoring, Analyse, Webserver. In der MonitoringKomponente werden die Monitoring-Records erstellt. Dabei werden je nach verwendetem
Aspekt verschiedene Records berücksichtigt.
Abbildung 4.1. Komponentendiagramm für ExplorViz aus [Fittkau 2015]
Die Monitoring-Records werden zu der Analyse-Komponente auf dem Trace Processing
17
4. Monitoring in ExplorViz
Server gesendet, welche die Traces vorbearbeitet, um eine Überbeanspruchung der AnalyseKomponente zu verhindern. Anschließend werden die Traces zur Analyse-Komponente
an den Visualization Server geschickt. Diese ist Teil des Visualization Providers, welcher
innerhalb eines Application Servers läuft. Das visualisierte Modell wird auf Anfrage zum
Client, beziehungsweise einem Web Browser gesendet (S. 161 [Fittkau 2015]).
Monitor-Komponente
Für das Monitoring von Android Anwendungen betrachten wir die Monitoring-Komponente
genauer. Für das Monitoring von Methodenaufrufen stellt ExplorViz derzeit folgende Records zur Verfügung:
™
™
™
™
™
™
™
™
™
BeforeOperationEventRecord
AfterFailedOperationEventRecord
AfterOperationEventRecord
BeforeConstructorEventRecord
AfterConstructorEventRecord
AfterFailedConstructorEventRecord
BeforeStaticOperationEventRecord
AfterFailedStaticOperationEventRecord
AfterStaticOperationEventRecord
Diese Records ermöglichen es Zustände vor, nach, und nachdem eine Exception geworfen wurde festzuhalten. Es wird dabei zwischen unterschiedlichen Methoden-Arten
unterschieden. Mit OperationEventRecord werden die gewöhnlichen Methoden bezeichnet.
Eine weitere Unterscheidung wird bei den Konstruktoren (ConstructorEventRecord) und
statischen Methoden (StaticOperationEventRecord) gemacht.
In ExplorViz werden sie in der Klasse AbstractAspect als Aspekte mit angeben. Diese Klasse
ist die Basis-Klasse für das Monitoring von Methodenaufrufen. Hier werden die Pointcuts
angegeben und die einzufügenden Aspekte. Es handelt sich um eine abstrakte Klasse.
Die Advices verwenden den Around-Typ und rufen vor dem eigentlichen Ausführen
der Methode die Methode createEventRecords() auf. Hier werden zunächst Daten für einen
18
4.1. Aktueller Stand im ExplorViz
BeforeRecord gesammelt und in einen ThreadLocalByteBuffer gespeichert, anschließend wird
versucht die eigentliche Methode auszuführen. Wirft diese eine Exception, so wird diese
gefangen und es werden Daten für den AfterFailedRecord gesammelt und die Exception
anschließend geworfen. Wenn die Methode korrekt ausgeführt wurde, dann werden anschließend Daten für den AfterRecord in den ByteBuffer geschrieben.
ExplorViz verwendet für das einweben der Aspekte den load-time weaving Ansatz.
Dafür wird die abstrakte Klasse DistributedMonitoringAspect verwendet, welche von der
AbstractAspect erbt. Da AspectJ nur Aspekte aus konkreten Klassen einwebt, wird ein
Konfigurationsdatei aop.xml verwendet. Diese erstellt eine konkrete Klasse mit Aspekten,
indem sie die DistributedMonitoringAspect Klasse erweitert und die Pointcuts definiert. Zur
Laufzeit werden die Aspekte dann beim Laden der Klasse eingewoben. Dieser Ansatz hat
den Vorteil, dass man in der aop.xml die Pointcuts und Aspekte variabel an die gegeben
Anforderungen an das Monitoring anpassen kann. So können zum Beispiel auch andere
Klassen als DistributedMonitoringAspect als Aspekt verwendet werden.
Abbildung 4.2. Monitor-Komponenten entnommen aus [Fittkau 2015]
Die Abbildung 4.2 gibt einen Überblick über die Monitoring-Komponente. Die gesammelten Daten werden wie oben in einen ByteBuffer gespeichert und anschließend an den
Monitoring Controller geschickt. Zur Synchronisation werden die ByteBuffer in einen Ring
Buffer zwischengespeichert. Der Monitoring Writer sendet die ByteBuffers über eine TCPVerbindung an die Analyse-Komponente. Der Monitoring Write arbeitet in einen anderem
Thread und sendet die ByteBuffer. Dies kann aus zwei Gründen geschehen. Entweder ist der
ByteBuffer voll, oder wenn der Tracecounter wieder auf null ist. Das heißt, wenn bei einer
Abfolge von aufeinander aufbauenden Methodenaufrufen die initiale Methode beendet
wurde.
Neben den gesammelte Informationen über die Methoden, i.e. Methoden, statische
19
4. Monitoring in ExplorViz
Methoden und Konstruktoren werden noch weitere Daten an die Analyse-Komponente
gesendet.
™
HostApplicationMetaDataRecord
Die MetaDaten werden einmalig zum Beginn als initialer ByteBuffer gesendet und
enthalten Informationen über den Systemnamen, die IP-Adresse, den Hostnamen, die
Applikations-ID und die Sprache. Diese werden in der Visualisierung der Landschaftsperspektive später angezeigt. Diese Daten können in der explorviz.live_trace_processing.default.properties
angeben werden. Hier werden auch allgemeine Einstellungen, wie die IP-Adresse des Servers für die Analyse- und Visualisierungs-Komponente angegben.
™
SystemMonitoringRecord
Der SystemMonitoringRecord sammelt Information über die CPU-Auslastung und den
Speicherverbrauch der Anwendung. Dafür wird die Java Klasse
com.sun.management.OperatingSystemMXBean verwendet [Fittkau 2015].
Android in ExplorViz
In ExplorViz sind bereits Ansätze für die Instrumentierung von Android vorhanden. Florian
Fittkau hatte 2013 im Rahmen seiner Dissertation für die Evaluation von ExplorViz eine
Android Applikation mit ExplorViz instrumentiert (S.191 [Fittkau 2015]). Dafür wurde
ein androidMonitoring-Flag eingeführt, welches unterscheiden soll, ob es sich bei dem zu
instrumentierenden Programm um ein Java oder Android Applikation handelt.
ExplorViz baut initial direkt aus dem Main-Thread eine TCP-Verbindung mit der AnalyseKomponente aufbaut. Unter Android ist dies aus Performancegründen nicht erlaubt, da
Netzwerkkommunikation langwierig sein kann und das System zwischenzeitlich nicht
mehr reaktiv wäre.
20
4.2. Entwurf
4.2.
Entwurf
Im Verlauf dieser Arbeit beziehen wir uns auf die Monitoring-Komponente. Da die Android
Anwendungen in Java geschrieben sind, können die Records hier übernommen werden und
müssen nicht extra angepasst werden. Deshalb reicht es aus sicherzustellen, dass die erstellten Monitor-Records über eine TCP-Verbindung an die Analyse-Komponente geschickt
werden. Von dort aus werden sie genauso wie die Records von Java-Programmen behandelt.
Abbildung 4.3. Deployment-Diagramm für Android-Monitoring in ExplorViz
Abbildung 4.3 zeigt wie das spätere Deployment für das Android-Monitoring in ExplorViz aussehen wird. Der Sourcecode soll zusammen mit der ExplorViz-Komponente in einer
APK kompiliert werden. Diese wird anschließend auf dem mobilen Endgerät installiert
und zum Laufen gebracht. Die eingewobenen Advices sammeln Informationen über das
System und senden diese an die Analyse-Komponente.
Kompatibilität mit Android Zum Erstellen der Monitoring-Komponente sind einige
Punkte zu beachten. Android basiert zwar auf Java, dennoch werden nicht alle Java APIs
unterstützt. Zunächst muss einmal überprüft werden, welche Libraries nicht unter Android
funktionieren. Diese müssen anschließend entfernt und verwendete Methoden gegebenenfalls mit Alternativen ergänzt werden.
Weiterhin wird die Monitoring-Komponente derzeit mit dem Java-Compiler kompiliert. Dies ist bei der Verwendung von Aspekten in einer Library in Verbindung mit dem
post-compile weaving nicht möglich. Wenn man versuchen würde dennoch solch Aspekte
einzuweben, kommt es zur Laufzeit zu einer MethodNotFoundException: aspectOf(). Dieses
Problem kann gelöst werden, wenn anstatt des Java-Compilers der AspectJ Compiler
21
4. Monitoring in ExplorViz
verwendet wird. Dabei wird die statische aspectOf Methode mit in die kompilierte Library
gepackt. Auch muss darauf geachtet werden, dass gerade ältere Android Versionen nur bis
zu der Java Version 7 kompatible sind. Dazu kann das Ant-Build-Skript, welches ExplorViz
derzeit verwendet, angepasst werden.
Bei größeren Apps kann es zu Problemen mit der Anzahl der referenzierten Methoden
kommen. Diese sind für eine einzelne dex-Datei auf 65.536 Stück begrenzt. Dazu zählen
auch die Methoden aus den Frameworks und Bibliotheken, sowie die durch die Aspekte
eingewobenen Methoden. Allerdings ist es möglich den Programmcode auf mehrere dexDateien aufzuteilen.
22
Kapitel 5
Implementierung
In diesem Kapitel wirdf die Vorgehensweise der Instrumentierung und die Implementierung der ExplorViz-Komponente für das Monitoring von Android Applikationen beschrieben. Zunächst werden wir auf die Instrumentierung von Android Anwendungen eingehen.
Anschließend behandeln wir den Sonderfall der Instrumentierung von APKs. Danach
werden wir auf die Änderungen der Monitoring-Komponente von ExplorViz eingehen.
5.1.
Sourcecode Instrumentierung
Wenn der Entwickler den Sourcecode der zu instrumentierenden Applikation hat, ist es
möglich diese während des Build-Prozesses zu instrumentieren. Dabei können sowohl das
compile-time weaving, als auch das post-compile weaving verwendet werden.
Wie bereits in Abschnitt 3.9 angekündigt, werden wir AspectJ zur Instrumentierung
verwenden. Weiterhin verwenden wir einen Ansatz mit post-compile weaving. Dies hat
den Vorteil, dass der eigentliche Java-Compiler weiter verwendet werden kann und wir nur
einen zusätzlichen Schritt in den Build-Prozess mit einbauen müssen (siehe Abbildung 3.1).
5.1.1.
Build-Skript
Google empfiehlt seit 2013 Gradle als Build-Tool für Android zu verwenden. Im Folgenden
werden wir ein Gradle-Plugin vorstellen, welches wir dazu verwenden in den Build-Prozess
noch einen weiteren Task einzufügen. Nach dem Kompilieren des Java-Sourcecodes werden definierte Aspekte mit dem AspectJ compiler eingewoben. Anschließend wird der
Build-Prozess wie gewohnt vorgeführt.
Dazu fügen wir zunächst die ExplorViz-Monitoring-Library in das Projekt als ein
neues Modul ein. Um das Plugin nutzen zu können, müssen wir zunächst Gradle sagen,
woher er das Plugin beziehen soll. Dazu geben wir in Listing 5.1 den Klassenpfad des
Plugins in der build.gradle im Hauptprojekt-Ordner an. Dabei ist darauf zu achten, dass
die richtige Gradle-Version installiert ist. Um das Plugin verwenden zu können, wird eine
Gradle-Version von Gradle 2.1.3 oder höher benötigt.
23
5. Implementierung
Listing 5.1. Klassenpfad für das Gradle-Plugin
1 buildscript {
2
repositories { "Test"
3
jcenter()
4
}
5
dependencies {
6
classpath ’com.android.tools.build:gradle:2.1.3’
7
8
//Klassenpfad: Gradle-Plugin
9
classpath ’com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.7’
10
}
11 }
Um das Plugin anschließend in den Build-Prozess zu integrieren, muss es in dem GradleSkript des zu instrumentierenden Android-Projektes angeben werden. Anschließend geben
wir noch an, dass wir die zuvor eingebundene Monitoring-Library mit kompilieren wollen
(Listing 5.2).
Listing 5.2. Klassenpfad für das Gradle-Plugin
1 apply plugin: ’android-aspectjx’
2
3
...
4
5 dependencies {
6
compile project(":explorviz-monitoring-android")
7 }
Das Plugin durchsucht das Projekt nach Klassen, die Aspekte definiert haben, und versucht diese auf alle .class-Dateien anzuwenden. Es ist nicht immer sinnvoll jede Klasse zu
instrumentieren. So möchte man zum Beispiel vielleicht die externen Programmbibliotheken nicht instrumentieren. Es ist möglich einzelne Bibliotheken von der Instrumentierung
auszuschließen oder auch wie in Abschnitt 5.3 beschrieben generell alle .jar-Dateien.
Listing 5.3. Ausschließen von jars
1 aspectjx {
2
excludeJarFilter ’.jar’
3 }
Möchte der Entwickler bestimmte .jar-Dateien mit instrumentieren, so können diese
mit includeJarFilter explizit angeben werden.
24
5.2. APK Instrumentierung
5.2.
APK Instrumentierung
Steht der Sourcecode zur Instrumentierung nicht zu Verfügung und der Entwickler hat
nur eine APK, ist es dennoch möglich diese zu Instrumentieren. Dazu dekompilieren wir
die APK, beziehungsweise die dex-Datei daraus zu Java Sourcecode. Anschließend können
wir den Sourcecode instrumentieren und die APK erstellen.
5.2.1.
Reverse Engineering
Im Kapitel 3 wurden einige Tools zum Reverse Engineering von APKs vorgestellt. Dazu
verwenden wir im Folgenden die Programme jadx zum Dekompilieren der dex-Datei und
das APKtool zum Dekompilieren der Ressourcen und des AndroidManifest.
Mit jadx lassen sich APKs direkt bearbeiten. Die dex-Datei wird dabei herausextrahiert
und in Java-Sourcecode dekompiliert. Ähnlich verfährt auch das APK-Tool mit den Metadaten. Die übersetzten Daten können anschließend in ein neu erstelltes Gradle-Projekt
eingebunden werden.
5.2.2.
Probleme
Durch die unterschiedlichen Strukturen von Java-Bytecode und Dalvik-Bytecode lassen
sich nicht immer alle Klassen vollständig korrekt rekonstruieren. Die Dekompiler sind
anfällig und der zurückübersetzte Code muss gegebenenfalls angepasst werden.
Erschwert wird dieser Vorgang durch den vorangegangen Einsatz von ProGuard um den
Programmcode zu verschleiern. Bezeichnungen von Methoden, Parametern, Variablen,
Klassen und Packages können dabei umbenannt werden. Ein anschließendes Monitoring
mit ExplorViz wäre dadurch sinnlos.
5.3.
Android-Monitoring in ExplorViz
In diesem Abschnitt werden wir uns mit dem Erstellen der Monitoring-Komponente für
Android beschäftigen. Als Grundlage dient die Monitoring-Komponente von ExplorViz.
Zuerst strukturieren wir diese so, dass sie kompatibel zu Android ist. Anschließend
beschäftigen wir uns mit dem System-Monitoring, i.e. das Messen der CPU-Auslastung
und dem Arbeitsspeicherverbrauch des Programmes. Zum Schluss behandeln wir noch
variable Pointcuts, um dem Entwickler die Möglichkeit zu geben eigene Pointcuts für das
Monitoring zu definieren.
25
5. Implementierung
5.4.
Kompatibilität mit Android
In der Monitoring-Komponente von ExplorViz gibt es einige Klassen und Bibliotheken, die
APIs verwenden, welche nicht mit Android Kompatible 1 sind:
™
™
™
™
ActiveMQProbe, javax.jms
JAXWSProbe, javax.xml
JAXWSProbeAdder, javax.xml, javax.jws
SystemMonitorProbe, com.sun.management.OperatingSystemMXBean
Bei den ersten drei Klassen handelt es sich um Aspekte, welche nicht für das Instrumentieren der Methodenaufrufe benötigt werden. Diese können also beim Erstellen der
ExplorViz-Monitoring-Library weggelassen werden. Die letzte Klasse ist für das Erstellen
der SystemMonitorRecords zuständig.
Systemmonitoring Eine Alternative für den Arbeitsspeicherverbrauch wäre über die
Runtime den freien und den gesamten Speicher abzufragen:
™
™
Runtime.getRuntime().freeMemory()
Runtime.getRuntime().maxMemory()
Für die CPU-Auslastung nutzen wir, dass Android auf den Linux Kernel basiert. Wie
unter Linux ist es möglich, Informationen über die CPU-Auslastung aus der /proc/stat
Datei auszulesen. Dabei wird die Auslastung für das gesamte System betrachtet, also nicht
nur für die instrumentierte Applikation, sondern auch für die im Hintergrund laufenden
Prozesse.
Nicht kompatible Programmbibliotheken Folgende Klassen verwenden mit dem LMAX
Disruptor ein Library, welche nicht mit Android kompatibel ist:
™
™
™
™
ByteBufferEvent, com.lmax.disruptor
MonitoringController, com.lmax.disruptor
ThreadSleepWaitingStrategy, com.lmax.disruptor
TCPWriter, com.lmax.disruptor
Das LMAX Disruptor Framework ist ein zentraler Punkt in der Verarbeitung und
das Senden von Records in der Monitoring-Komponente. Es wird verwendet um den
RingBuffer zu implementieren. Die Library verwendet die Klasse sun.misc.Unsafe, welche
in Android nicht zur Verfügung steht. Allerdings hat sich gezeigt, dass der RingBuffer
trotzdem unter Android funktioniert, da nicht auf die Unsafe-Klasse zugegriffen wird.
1 https://developer.android.com/reference/packages.html
26
5.4. Kompatibilität mit Android
Build-Prozess Um die Monitoring-Komponente für Android bereit zu stellen, muss sie
zum einen mit dem AspectJ Compiler gebaut werden und zum anderen darf sie nicht mit
einer höheren Version als Java 7 kompiliert werden. Dazu passen wir das Build-Skript
für ExplorViz an. ExplorViz verwendet Apache Ant. Wir erweitern die build.xml um
weitere Tasks, wie in Listing 5.4 zu sehen. Der Task build-android-monitoring (Zeile 1-4) ist
der Haupttask, welcher die Abhängigkeiten der Monitoring-Komponente beschreibt. In
Zeile 13-15 wird definiert, dass die Klassen der Monitoring-Komponente mit dem AspectJ
Compiler und einen Kompilerlevel von Java 7 kompiliert werden soll. Zeile 27 schließt
die nicht kompatiblen Klassen aus der Jar aus. Das Unterprojekt common, welches Klassen
für die Monitor-Komponente bereitstellt, muss ebenfalls mit der Java Version 7 kompiliert
werden. Da aber in dem Projekt keine Aspekte sind, reicht der normale Java-Compiler aus.
27
5. Implementierung
Listing 5.4. Auszug aus dem build.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<target name="build-android-monitoring"
depends="clean,compile-ajc,monitoring-Android-jar,test-ajc"
description="Compiles and packages the Jar for Android-Monitoring">
</target>
<target name="compile-ajc" depends="build-all-common">
<mkdir dir="${build.dir}" />
<copy todir="${build.dir}">
<fileset dir="${common-monitoring.dir}/dist"/>
</copy>
<iajc srcdir="${src.dir}" destdir="${build.dir}"
classpathref="classpath"
source="1.7" target="1.7" debug="true" />
</target>
<target name="monitoring-Android-jar">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/explorviz-monitoring-android.jar">
<manifest>
<attribute name="Class-Path" value="."/>
<attribute name="Can-Redefine-Classes" value="true"/>
<attribute name="Can-Retransform-Classe" value="true"/>
</manifest>
<fileset dir="${build.dir}" excludes="*common*.jar, **/ActiveMQProbe.class, **/
JAXWSProbe*.class" />
28
29
<fileset dir="lib" includes="*LICENSE*" />
<fileset dir="${src.dir}" includes="META-INF/explorviz.live_trace_processing.
default.properties" />
30
<fileset dir="${src.dir}" includes="**/Pointcuts.java" />
31
32
<zipfileset excludes="META-INF/*.SF" src="${build.dir}/explorviz-common.jar"/>
33
<zipfileset excludes="META-INF/*.SF" src="lib/slf4j-api-1.7.5.jar"/>
34
<zipfileset excludes="META-INF/*.SF" src="lib/disruptor-3.3.0.jar"/>
35
</jar>
36 </target>
28
5.5. Aspekte
Listing 5.5. Pointcuts.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package explorviz.live_trace_processing.probe;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
// concrete Aspect for compile time weaving
@Aspect
public class Pointcuts extends AbstractAspect {
@Override
@Pointcut("execution(* *..*(..)) && within(*)")
public void monitoredOperation() {}
@Override
@Pointcut("execution(*..*.new(..)) && within(*)")
public void monitoredConstructor() {}
}
Netzwerkkommunikation Die Monitoring-Komponente sendet die Records über eine
TCP-Verbindung an die Analyse-Komponente. Damit dies möglich ist braucht die Applikation die Berechtigung Netzwerkoperationen durchzuführen. Diese Berechtigung kann in
dem AndroidManifest gesetzt werden. Außerdem muss die IP-Adresse des Servers in der
explorviz.live_trace_processing.default.properties im META-INF Ordner angeben werden. Beim
Android Emulator, welcher per USB über die Android Debug Bridge (ADB) angeschlossen ist,
ist die IP-Adresse des localhost 10.0.2.2.
5.5.
Aspekte
ExpolorViz verwendet für das load-time weaving Klassen für die Aspekte, welche zunächst abstrakt sind. Hinzu kommt, dass die Pointcuts erst in der Konfigurationsdatei
konkretisiert werden. Dies ist beim post-compile weaving nicht möglich. Deshalb brauchen
wir eine konkrete Klasse mit Pointcuts, die von der Basisklasse AbstractAspect abgeleitet
wird. AbstractAspect enthält bereits die Advices und Teile der Pointcuts. So wird generell
schon einmal zwischen Methoden und statischen Methoden unterschieden. Auch wird
die Monitoring-Komponente ausgeschlossen, damit sich die Aspekte nicht rekursiv selbst
instrumentieren. Und wir müssen nur die Pointcuts für monitoredOperation und monitoredConstructor definieren. Listing 5.5 ist die implementierte Klasse dazu. Generell werden alle
Methoden und alle Konstruktoren instrumentiert.
29
5. Implementierung
5.6.
Variable Pointcuts
Die Pointcuts im vorherigen Abschnitt sind fest in der Monitoring Library kompiliert
und so nicht mehr nachträglich änderbar. Damit man sich eigen Pointcuts definieren
kann, beziehungsweise das Instrumentieren auf einige Packages beschränken kann, muss
man sich eine eigen Klasse schreiben, welche von AbstractAspect erbt. Dazu geben wir
die unkompilierten Pointcuts.java in der Library mit. Der Entwickler kann diese aus
der Library entnehmen und nach Bedarf anpassen. Dabei sind zwei Punkte zu beachten.
Zum einen muss der Pfad, in der die Klasse liegt, zum sourcepath des Compilers gehören.
Außerdem muss das Package, in dem die Klasse befindet durch den neu definierten
Pointcut ausgeschlossen werden, da sich der Aspekt ansonsten selbst instrumentiert. Zum
Schluss muss die kompilierte Pointcuts.class aus der Library gelöscht werden, da sonst der
Aspekt ebenfalls mit eingewoben wird.
30
Kapitel 6
Evaluation
Wir wollen unsere Implementierung zum einen auf Funktionalität überprüfen. In der
Landschaftsperspektive soll Auskunft über den Namen und den Resourceverbrauch der
Applikation gegeben werden. In der Applikationsicht sollen die Klassen in Ihren Packages,
sowie die Kommunikation zwischen den Klassen dargestellt werden. Zum anderen wird
unsere Implementierung auf die Usability evaluiert. Es soll einem Entwickler möglich sein
mit der Monitoring-Komponente seine Applikation ohne viel Aufwand zu instrumentieren
und mit ExplorViz visuell darzustellen.
Versuchsaufbau
Zum Test der Monitoring-Komponente verwenden wir eine App, die 2013 von Studenten im
Rahmen des Softwareprojektes an der Christian-Albrechts-Universität zu Kiel geschrieben
wurde. Der Sourcecode ist vorhanden und wird für die Instrumentierung verwendet. Die
Zielversion der Applikation ist mit der API 19 relativ alt. Zum Test wird der Android
Emulator von Android Studio mit einer Android Version, die der API 19 entspricht,
verwendet.
Das Ergebnis wird ausgewertet und mit dem Sourcecode verglichen.
Instrumentierung mit dem Sourcecode
Das Projekt wurde mit dem Build-Tool Ant erstellt. Zum Instrumentieren auf Sourcecodebasis laden wir das Projekt als erstes in Android Studio und importieren es als GradleProjekt. Anschließend laden wir die Monitoring-Komponente als Modul in das Projekt und
instrumentieren die Applikation, wie in Abschnitt 5.1 beschrieben.
Auswertung
Das Importieren in ein Gradle-Projekt hat funktioniert. Die anschließende Instrumentierung
konnte erfolgreich durchgeführt werden und die erstellte APK auf den Emulator installiert
werden. Es ist jedoch zu beobachten, dass der ExplorViz-Server vor der App gestartet
31
6. Evaluation
werden muss. Geschieht dies nicht, startet die Applikation zwar, reagiert aber auf keine
Eingaben mehr. Es ist zu vermuten, dass die Applikation in diesem Zustand versucht sich
wiederholend mit der IP zu verbinden. Wurde der Server zuvor gestartet, wird nach kurzer
Zeit die Landschaftsperspektive, wie in Abbildung 6.1 visualisiert.
Abbildung 6.1. Babsi in der Landschaftsperspektive
Es wird korrekt die Babsi Applikation angezeigt. Beim System-Monitoring fällt auf,
dass der Total RAM mit 0GB angegeben ist. Diese Kennzahl spiegelt nicht den gesamten
Arbeitsspeicher des Gerätes wieder, sondern gibt nur den Speicher an, welcher der Android Anwendung maximal zugewiesen werden kann. Diese Grenze ist durch das Android
System gegeben. Diese liegt bei dem Emulator bei 32 Megabyte. Dies ist deutlich unter
einen Gigabyte und es ist anzunehmen, dass hier abgerundet wurde.
In der Applikationsperspektive(Abbildung 6.2) werden die einzelnen Packages und
die Klassen richtig zugeordnet. Man erkennt die Kommunikation unter den Klassen und
es lassen sich auch die Reaktionszeiten ablesen. Die Visualisierung reagiert, nach kurzer
Verzögerung auf die Eingaben, welche auf den Emulator vorgenommen wurden.
32
Abbildung 6.2. Babsi in der Applikationsperspektive
Zur Usability lässt sich feststellen, dass ein Monitoring einer eigenen Android App
ohne zusätzlichen Programmieraufwand möglich ist. Es wird im Sinne des Separation of
Concerns nicht direkt in den Sourcecode eingegriffen und die Aspekte sind klar vom Code
der eigentlichen Anwendung getrennt. Es bedarf lediglich einer Anpassung des GradleSkriptes. Auch wurde die Software mit älteren Android Versionen getestet (Android 4.4,
API 19).
33
Kapitel 7
Verwandte Arbeiten
In diesem Kapitel werden wir einige verwandte Arbeiten vorstellen. Der Fokus liegt
dabei auf der Instrumentierung von Android. Ein weiterer Aspekt ist das Monitoring des
Ressourcenverbrauches.
7.1.
Kieker Monitoring Framework
Kieker1 ist ein System zum Monitoring und zur dynamischen Softwareanalyse von Software
zur Laufzeit. Es besteht im Wesentlichen aus den zwei Komponenten Kieker.Monitoring
und Kieker.Analysis. Die Monitoringkomponente stellt Klassen und Methoden für eine
Instrumentierung und das Erzeugen von Records zu Verfügung. Die generierten Records
können an die Analyse Komponente übergeben werden und dort weiter analysiert werden.
Kieker basiert auf Java und bietet nativ die Instrumentierung für Java-Anwendung an. Das
Monitoring von Android wird derzeit nicht unterstützt. Jedoch wäre ein ähnlicher Ansatz,
wie der der in dieser Arbeit vorgestellten Sourcecode-Instrumentierung, denkbar.
Um eine Schnittstelle für andere Sprache anzubieten, wurde die Kieker Data Bridge (DKB)
entwickelt. Die KDB erlaubt es andere Programmiersprachen in Kieker zu implementieren.
7.2.
SPASS-meter
SPASS-meter2 ist ein Monitoring-Framework für das Messen des Ressourcenverbrauchs von
Java-Programmen. Es erlaubt das Monitoring von Android-Anwendungen, indem es den
Build-Prozess so verändert, dass die JAR-Datei instrumentiert wird, bevor diese zum Dalvik
Executable-Format kompiliert wird. Dazu wird die Byte Code Engineering Library (Apache
Commons BCEL)verwendet, welche das Lesen und Verändern von Java-Bytecode ermöglicht.
Mit Annotationen im Sourcecode oder durch ein XML-Datei können die Bereiche, welche
überwacht werden sollen, definiert werden. Die Weiterentwicklung im Bereich der Android
Instrumentierung ist derzeit eingestellt.
1 http://kieker-monitoring.net
2 http://sse.uni-hildesheim.de/forschung/projekte/spass-meter
35
7. Verwandte Arbeiten
7.3.
Android Monitor
Android Monitor3 ist ein Werkzeug von Android Studio. Es lassen sich zuvor definierte
Logs auslesen und die aktuelle Arbeitsspeicher-, CPU-, GPU- und Netzwerkauslastung
anzeigen. Weiterhin ist es möglich Methoden-Traces aufzuzeichnen, um diese später im
Kontext des Ressourcenverbrauches zu analysieren.
3 https://developer.android.com/studio/profile/android-monitor.html
36
Kapitel 8
Fazit und Ausblick
In diesem Kapitel werden wir die Implementierung und die Auswertung noch einmal
zusammenfassen. Im Ausblick werden Vorschläge für zukünftige Arbeiten gegeben.
8.1.
Fazit
Im Rahmen der Bachelorarbeit haben wir uns mit dem Monitoring und der Visualiserung
mit ExplorViz von Android Applikationen beschäftigt. Dabei haben wir primär den Fall
betrachtet, dass ein Entwickler seine Applikation über den Sourcecode instrumentieren
möchte. Aufgrund der einfachen Handhabung und der Tatsache, dass ExplorViz bereits
AspectJ verwendet, haben wir uns für diesen aspektorientierten Ansatz entschieden. Das
Einweben der Aspekte geschieht mit Hilfe eines Gradle-Plugins. Wir haben die MonitoringKomponente von ExplorViz für Android angepasst. Dazu haben wir nicht kompatible
Programmteile entfernt und teilweise ersetzt. Auch haben wir das Build-Skript angepasst.
Im Ansatz haben wir noch den Fall betrachtet, dass der Entwickler nur die APK der
Android App zur Verfügung hat. Wir haben einen möglichen Weg aufgezeigt, wie man
APKs mit Hilfe des Dekompilierens instrumentieren kann.
Die Evaluation am Schluss hat gezeigt, dass die Instrumentation von Android Sourcecode mit ExplorViz möglich ist. Die Monitoring-Library kann auf einem einfachen Weg in
ein aktuelles Projekt integriert werden und so das Monitoring von ExplorViz nutzen.
8.2.
Ausblick
In dieser Arbeit wurde das Monitoring der grundlegenden Methoden behandelt. Es können noch weitere Aspekte, welche bereits in ExplorViz implementiert sind, für Android
angepasst werden. So wurde unter anderem die Performance von Datenbankoperationen
in ExplorViz behandelt [Zirkelbach 2015]. In Hinblick darauf kann es auch nötig sein, eine
einfachere Möglichkeit zu haben um die Pointcuts variabel anzupassen.
Ein wichtiger Bestandteil der zukünftigen Arbeit wird es sein, die Monitoring-Komponente
an neue Android Versionen anzupassen. So wird es zum Beispiel ab Android 7.0 aufgrund
37
8. Fazit und Ausblick
von fehlenden Berechtigungen nicht mehr möglich sein, sich die CPU-Auslastung über die
/proc/stat Datei auslesen zu lassen.
38
Literaturverzeichnis
[Arzt u. a. 2013] S. Arzt, S. Rasthofer und E. Bodden. Instrumenting android and java
applications as easy as abc. In: International Conference on Runtime Verification. Springer.
2013, Seiten 364–381. (Siehe Seiten 6 und 13)
[Bartel u. a. 2012] A. Bartel, J. Klein, M. Monperrus, K. Allix und Y. L. Traon. In-Vivo
Bytecode Instrumentation for Improving Privacy on Android Smartphones in Uncertain
Environments. arXiv preprint arXiv:1208.4536 (2012). (Siehe Seite 14)
[El-Harake u. a. 2014] K. El-Harake, Y. Falcone, W. Jerad, M. Langet und M. Mamlouk.
Blocking Advertisements on Android Devices using Monitoring Techniques. In: International Symposium On Leveraging Applications of Formal Methods, Verification and Validation.
Springer. 2014, Seiten 239–253. (Siehe Seite 14)
[Fittkau 2015] F. Fittkau. Live Trace Visualization for System and Program Comprehension
in Large Software Landscapes. Dissertation. Christian-Albrechts-Universität zu Kiel,
2015, Seiten 33–34. url: http://eprints.uni-kiel.de/29511/1/diss_fittkau.pdf. (Siehe Seiten 9,
17–20)
[Fittkau u. a. 2013a] F. Fittkau, J. Waller, C. Wulf, und W. Hasselbring. Live Trace Visualization for Comprehending Large Software Landscapes: The ExplorViz Approach. In: Live
Trace Visualization for Comprehending Large Software Landscapes: The ExplorViz Approach.
Proc. 1st IEEE International Working Conference on Software Visualization, Feb. 2013a,
Seiten 80–85. (Siehe Seiten 1 und 9)
[Fittkau u. a. 2016] F. Fittkau, A. Krause und W. Hasselbring. Software landscape and
application visualization for system comprehension with ExplorViz. Information and
Software Technology (2016). (Siehe Seite 9)
[IDC 2015] IDC. International Data Corporation: Smartphone OS Market Share, 2015 Q2.
2015. url: http://www.idc.com/prodserv/smartphone-os-market-share.jsp (besucht am 04. 06. 2016).
(Siehe Seite 1)
[Kiczales u. a. 1997] G Kiczales, J Lamping, A Mendhekar, C Maeda, C Lopes, J Loingtier
und J Irwin. Aspect-oriented programming. Band 1. Springer, 1997. (Siehe Seite 7)
[Kiczales u. a. 2001] G. Kiczales, E. Hilsdale, J. Hugunin, M. Kersten, J. Palm und W. G. Griswold. An overview of AspectJ. In: European Conference on Object-Oriented Programming.
Springer. 2001, Seiten 327–354. (Siehe Seite 7)
[Van Hoorn u. a. 2012] A. van Hoorn, J. Waller und W. Hasselbring. Kieker: A Framework
for Application Performance Monitoring and Dynamic Software Analysis. In: Proceedings
of the 3rd ACM/SPEC International Conference on Performance Engineering (ICPE 2012).
ACM, Apr. 2012, Seiten 247–248. (Siehe Seite 10)
39
Literaturverzeichnis
[Zirkelbach 2015] C. Zirkelbach. Performance monitoring of database operations. Dissertation. Kiel University, 2015. (Siehe Seite 37)
40
Anhang
41
Herunterladen