
Das Redexer-Framework zur binären Instrumentierung von Dalvik-Bytecode
Redexer ist ein Reengineering-Werkzeug, das Android-App-Binärdateien manipuliert. Dieses Tool kann eine DEX-Datei in eine speicherresidente Datenstruktur parsen; ermitteln, mit welchen Parametern die App bestimmte Berechtigungen verwendet (wir nennen diese Funktion RefineDroid); diese Datenstruktur modifizieren und entparsen, um eine ausgegebene DEX-Datei zu erzeugen (wir nennen diese Funktionen Dr. Android, was für Dalvik Rewriting for Android steht).
Dieses Tool wurde unter OCaml 4.09.0 und Ruby 1.8.6(7) getestet, daher müssen Sie diese (oder neuere Versionen) installieren.
Zur Manipulation einer SHA-1-Signatur (Hash) im DEX-Format verwenden wir die OCaml SHA-Bibliothek über ocamlfind/findlib, einen OCaml-Bibliotheksmanager. Der einfachste Weg, beide zu installieren, ist die Verwendung von OPAM, einem OCaml-Paketmanager, der beide Pakete enthält: OPAM ocamlfind und OPAM sha.
Sie können beide Pakete auch direkt erstellen und/oder installieren. Wenn Sie einen Linux-Rechner verwenden, finden Sie leicht Distributionen.
Andernfalls, z. B. auf einem Mac, müssen Sie sie selbst erstellen.
Den Originalquellcode finden Sie hier.
Erstellen Sie ihn mit make und verlinken Sie das resultierende Verzeichnis in
das Root-Site-lib-Verzeichnis von ocamlfind; oder sudo make install.
Wenn Sie einen PC verwenden, müssen Sie zuerst ocamlfind/findlib und FlexDLL installieren. Stellen Sie sicher, dass Ihre Umgebungsvariablen korrekt gesetzt sind, wie folgt:
OCAMLLIB=C:\OCaml\lib
CAML_LD_LIBRARY_PATH=%OCAMLLIB%\stublibs
FLEXLINKFLAGS=-L%MinGW%\lib -L%MinGW%\lib\gcc\mingw32\N.N.N
OPAM-Pakete:
Android SDK (oder Quellen)
Zum Entpacken und Neupacken von APK-Dateien verwenden wir apktool, ein Open-Source-APK-Reengineering-Tool.
Da es aapt, das Android Asset Packaging Tool, verwendet, müssen Sie
das Android SDK oder die Quellen installieren. Außerdem verwenden wir
zipalign, das ebenfalls aus dem Android SDK stammt, um umgeschriebene Apps zu optimieren.
Sie können Pfade zu den Android-Basiswerkzeugen festlegen, indem Sie Folgendes zu Ihrem Profil hinzufügen:
ANDROID_HOME=$HOME/android-sdk # Ihr eigener Pfad hier!
export ANDROID_HOME
PATH=$PATH:$ANDROID_HOME/tools
PATH=$PATH:$ANDROID_HOME/platform-tools
PATH=$PATH:$ANDROID_HOME/build-tools/19.0.0 # Installierte Versionsnummer
export PATH
Die Hauptskripte sind in Ruby geschrieben und benötigen RubyGems, einen Ruby-Paketmanager, sowie Nokogiri, eine XML-Bibliothek zur Bearbeitung von Manifest-Dateien.
Wenn Sie Graphen sehen möchten (z. B. Call-Graph, Kontrollflussgraph, Dominator-Baum usw.), müssen Sie graphviz dot installieren.
Um redexer zu erstellen, einfach make ausführen! Die redexer-Binärdatei befindet sich dann auf der obersten Ebene.
$ make (clean)
Vor der Verwendung des Tools muss der aktuellste Plattform-Datei für apktool vom Benutzer installiert werden. Zum Beispiel:
$ java -jar tools/apktool.jar if [geeignete Plattform-Datei]
Sie können auch API-Dokumentation im HTML-Format erstellen.
$ make api
Sie können alle vom Tool bereitgestellten Optionen anzeigen:
$ ruby scripts/cmd.rb -h
$ ruby scripts/cmd.rb --help
Wie dexdump im Android SDK ermöglicht redexer Ihnen, die Interna der angegebenen DEX-Datei im YAML-Format anzuzeigen.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd unparse [--to blah.yml]
Diese Option gibt Befehle für eine bestimmte Methode aus.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dump_method --mtd cls.mtd
Diese Funktion dient zum Testen der Parse- und Dump-Module von redexer. Sie erzeugt wahrscheinlich eine identische DEX-Datei.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd id [--to blah.dex]
Sie können auch grundlegende Statistiken über die DEX-Datei anzeigen, z. B. # instr.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd info
Diese Option gibt alle in der DEX-Datei definierten Klassennamen aus.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes
Das kann nützlich sein, um nach bestimmten Drittanbieter-Bibliotheken zu suchen, z. B.:
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes | egrep 'apache'
Diese Option gibt die API-Nutzung in der DEX-Datei aus.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api [--sdk android.]
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api --sdk com.facebook.
Sind Sie nicht neugierig, wie selten einige Opcodes in Dalvik-Bytecodes verwendet werden? Es zeigt Ihnen das Histogramm aller Opcodes, oder Sie können nachschlagen, wie oft der genaue Opcode in der gegebenen App verwendet wird.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd opstat [--op opcode1,opcode2,...]
Beispiel:
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat --op div-int/lit16,nop
Diese Option führt eine ausbreitungsbasierte Intent-Auflösungsanalyse durch und gibt Übergänge zwischen Activity-Klassen aus.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd intent
Diese Option erzeugt eine PDF-Datei, die einen Call-Graphen der gegebenen Datei darstellt. Wenn Sie keinen PDF-Namen angeben, wird cg.pdf verwendet.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cg [--to blah.pdf] [--no-pdf]
Diese Option erzeugt eine PDF-Datei, die einen Kontrollflussgraphen der angegebenen Methode zeigt. Hängen Sie einen Methodennamen mit Punkt an den Klassennamen an: class_name.method_name
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cfg --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Diese Option ist ähnlich wie die obige, mit dem Unterschied, dass sie den (Post-)Dominator-Baum darstellt.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd (p)dom --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Diese Option führt eine klassische rückwärtsgerichtete Datenflussanalyse durch.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd live --mtd cls.mtd
Diese Option führt eine klassische vorwärtsgerichtete Datenflussanalyse durch.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd const --mtd cls.mtd
Diese Option führt eine klassische vorwärtsgerichtete Datenflussanalyse durch.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd reach --mtd cls.mtd
Diese Option findet Klassenabhängigkeiten.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dependants --mtd cls.mtd
Diese Option gibt den Namen der Start-Activity der gegebenen APK aus.
$ ruby scripts/cmd.rb target.apk --cmd launcher
Diese Option teilt Ihnen mit, welche Komponenten nach außen hin sichtbar sind.
$ ruby scripts/cmd.rb target.apk --cmd exported
Diese Optionen geben die im Manifest deklarierten Android-Basiskomponenten aus.
$ ruby scripts/cmd.rb target.apk --cmd [activity | service | provider | receiver]
Diese Option durchsucht Layout-Definitionen in Ressourcen und gibt benutzerdefinierte Views aus.
$ ruby scripts/cmd.rb target.apk --cmd custom_views
Diese Option durchsucht Layout-Definitionen in Ressourcen und gibt Fragment-Elemente aus.
$ ruby scripts/cmd.rb target.apk --cmd fragments
Diese Option durchsucht Layout-Definitionen in Ressourcen und gibt Buttons aus, zusammen mit ihrer ID (oder ihrem Text) sowie der Callback-Methode (falls vorhanden).
$ ruby scripts/cmd.rb target.apk --cmd buttons
Diese Option gibt die von der APK verwendeten Berechtigungen aus.
$ ruby scripts/cmd.rb target.apk --cmd permissions
Diese Option gibt die SDK-Version aus, die die APK benötigt.
$ ruby scripts/cmd.rb target.apk --cmd sdk
Wenn Sie die APK-Datei nicht entpacken möchten, können Sie dasselbe auch mit einer Kombination von Befehlen erreichen:
$ aapt dump badging target.apk | grep 'targetSdkVersion' | tr -dc 0-9.\\n
Diese Option erzeugt eine DEX-Datei, die eine einfache Nachricht ausgibt. Diese DEX-Datei wird nur mit den APIs von redexer erstellt.
$ ruby scripts/cmd.rb --cmd hello
Überprüfen Sie deren Inneres:
$ dexdump -d results/classes.dex
Wenn Sie interessiert sind, können Sie diese DEX-Datei wie folgt testen. Angenommen, der Pfad zum ANDROID_SDK ist gesetzt.
// Erstellen Sie ein temporäres Jar, das für die Dalvik-VM geeignet ist
$ aapt add temp.jar results/classes.dex
// (optional) Wenn Sie kein AVD erstellt haben, erstellen Sie eines.
$ android create avd -n myAVD1 -t android-8
// Starten Sie Ihren Emulator
$ emulator -avd myAVD1 &
// Übertragen Sie das temporäre Jar
$ adb push temp.jar /data
// Verbinden Sie sich mit der adb-Shell
$ adb shell
// Führen Sie schließlich die DEX aus
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar \
-classpath /data/temp.jar Hello
Hello, DEX
#
Dies ist eine Variante der Umschreibungsfunktion. Mit dieser Funktion können Sie
das App-Verhalten aus bestimmten Perspektiven protokollieren. Die vorgefertigte DEX-Datei
für die Logging-Bibliothek wird bereitgestellt: data/logging.dex. Wenn Sie weitere
Funktionen oder Hilfsprogramme hinzufügen möchten, erstellen Sie sie wie folgt:
$ cd logging
$ gradle copyDex
$ cd ..
Verwenden Sie dann den folgenden Befehl:
$ ruby scripts/cmd.rb target.apk --cmd logging
trim.py kann die Call-Return-Sequenzen der instrumentierten App erfassen. (Sie sollten die zu testende App zuerst mit redexer instrumentieren.)
Wenn diese Logs kurz genug sind, d. h. das Telefon (oder der Emulator) alle Informationen im Speicher halten kann, können Sie den Offline-Modus des Skripts verwenden:
$ ./scripts/trim.py -d
Beachten Sie, dass alle Befehlszeilenparameter an adb logcat übergeben werden, und
standardmäßig wird org.umd.logging:I *:S übergeben, um irrelevante Logs zu filtern.
Wenn Logs überlaufen, sollten Sie den Online-Modus verwenden:
$ ./scripts/trim.py
Das Skript fängt Tastaturunterbrechungen ab, sodass Sie das Logging mit Strg+C beenden können.
In beiden Modi werden Logs in log.txt gespeichert und gleichzeitig auf dem Bildschirm angezeigt. Nach dem Sammeln der Logs müssen Sie diese Datei möglicherweise verschieben, z. B.:
$ mv log.txt app.scenario.txt
Die obige Logging-Funktion ist allgemein, da Sie festlegen können, was auf Methodenebene
protokolliert werden soll. (Weitere Einzelheiten finden Sie im Modul logging.)
Dies ist jedoch manchmal zu ausführlich und kann zu Leistungseinbußen führen.
Diese Funktion ist darauf ausgelegt, nur Benutzerinteraktionen zu protokollieren. Mit dieser
Funktion können Sie nur UI-bezogene Ereignisse erfassen. Ebenso wird die vorgefertigte DEX-Datei
für die Logging-Bibliothek bereitgestellt: data/logging-ui.dex. Wenn Sie die Ausführlichkeit
der UI-Informationen ändern möchten, erstellen Sie sie wie folgt:
$ cd logging-ui
$ gradle copyDex
$ cd ..
Verwenden Sie dann den folgenden Befehl:
$ ruby scripts/cmd.rb target.apk --cmd logging_ui
Die Logging-Bibliothek wird vom Android a11y-Dienst geerbt, der die ausdrückliche
Zustimmung des Benutzers erfordert. Gehen Sie daher nach der Installation der umgeschriebenen APK zu
Einstellungen/Barrierefreiheit und aktivieren Sie den Dienst UI Logging.
(Dieser Schritt kann mit dem Aktivieren des Gerätedebug-Modus verglichen werden.)
Im logcat werden Nachrichten mit den Tags org.umd.logging_ui.* als Interaktionen
zwischen dem Benutzer und der getesteten App angezeigt.
Diese Option findet Komponentenübergangspfade zu Zielmethodenaufrufen.
$ ruby scripts/cmd.rb target.apk --cmd directed
Sie können Zielmethoden angeben, die in data/directed.txt aufgerufen werden sollen.
Diese Komponentenübergangspfade werden verwendet, um Apps zu treiben, um Sicherheitslücken in Drittanbieter-Bibliotheken zu testen. Weitere Details werden in der folgenden Veröffentlichung beschrieben:
* Brahmastra: Driving Apps to Test the Security of Third-Party Components.
R. Bhoraskar et al., In 23rd Usenix Security Symposium (Security '14).
withTimeout.rb kann automatisch eine Überspringdatei für eine App erstellen. Dieses Skript führt cmd.rb mit einem bestimmten Timeout aus, um die Zeit zu begrenzen, die für die Instrumentierung einer einzelnen Klasse aufgewendet wird. Dies ist eine vorübergehende Problemumgehung für gelegentliche Klassen, die während der Instrumentierung in einer Schleife hängen bleiben. Wenn dieses Skript eine Klasse findet, die abstürzt, fügt es sie zur Überspringdatei hinzu und setzt dort fort, wo es aufgehört hat. Sobald withTimeout beendet ist, befindet sich eine Datei namens [apk name]-skip.txt im Datenverzeichnis, die zum Erstellen einer vollständig instrumentierten App für diese APK verwendet werden kann. Um withTimeout zu verwenden, rufen Sie einfach auf:
$ ruby scripts/withTimeout.rb TIMEOUT COMMANDS
Wobei TIMEOUT die Länge des gewünschten Timeouts in Sekunden ist (300 wird empfohlen) und COMMANDS alle regulären Befehlszeileneingaben sind, die Sie an scripts/cmd.rb für die APK übergeben würden.