
Le framework d'instrumentation binaire Redexer pour le bytecode Dalvik
Redexer est un outil de réingénierie qui manipule les binaires d'applications Android. Cet outil peut analyser un fichier DEX en une structure de données en mémoire ; identifier avec quels paramètres l'application utilise certaines permissions (nous appelons cette fonctionnalité RefineDroid) ; modifier et désanalyser cette structure de données pour produire un fichier DEX de sortie (nous appelons ces fonctionnalités Dr. Android, pour Dalvik Rewriting for Android).
Cet outil est testé sous OCaml 4.09.0 et Ruby 1.8.6(7), vous devez donc les installer (ou des versions supérieures).
Pour manipuler une signature SHA-1 (hash) au format DEX, nous utilisons la bibliothèque OCaml SHA via ocamlfind/findlib, un gestionnaire de bibliothèques OCaml. Le moyen le plus simple d'installer les deux est d'utiliser OPAM, un gestionnaire de paquets OCaml, qui propose les deux paquets---OPAM ocamlfind et OPAM sha.
Vous pouvez également compiler et/ou installer les deux paquets directement. Si vous utilisez une machine Linux, vous pouvez facilement trouver des distributions.
Sinon, par exemple sur Mac, vous devez les compiler vous-même.
Vous trouverez les codes sources originaux ici.
Compilez-les en exécutant make, puis liez le répertoire résultant dans le répertoire racine site-lib d'ocamlfind ; ou sudo make install.
Si vous utilisez un PC, vous devez d'abord installer ocamlfind/findlib et FlexDLL. Assurez-vous que vos variables d'environnement sont correctement définies comme suit :
OCAMLLIB=C:\OCaml\lib
CAML_LD_LIBRARY_PATH=%OCAMLLIB%\stublibs
FLEXLINKFLAGS=-L%MinGW%\lib -L%MinGW%\lib\gcc\mingw32\N.N.N
Paquets OPAM :
SDK Android (ou sources)
Pour décompresser et recompresser les fichiers apk, nous utilisons apktool, un outil open source de
réingénierie APK. Comme il utilise aapt, l'outil de packaging des ressources Android,
vous devez installer le SDK Android ou les sources. De plus, nous utilisons
zipalign, qui vient également du SDK Android, pour optimiser les applications réécrites.
Vous pouvez définir les chemins vers les outils Android de base en ajoutant les éléments suivants à votre profil :
ANDROID_HOME=$HOME/android-sdk # votre propre chemin ici !
export ANDROID_HOME
PATH=$PATH:$ANDROID_HOME/tools
PATH=$PATH:$ANDROID_HOME/platform-tools
PATH=$PATH:$ANDROID_HOME/build-tools/19.0.0 # numéro de version installée
export PATH
Les scripts principaux sont écrits en Ruby et nécessitent RubyGems, un gestionnaire de paquets Ruby, et Nokogiri, une bibliothèque XML pour manipuler les fichiers manifestes.
Si vous souhaitez voir des graphes (graphe d'appels, graphe de flot de contrôle, arbre de dominance, etc.), vous devez installer graphviz dot.
Pour compiler redexer, faites simplement make ! Vous pouvez voir le binaire redexer à la racine.
$ make (clean)
Avant d'utiliser l'outil, l'installation du fichier de plateforme le plus récent pour apktool incombe à l'utilisateur. Par exemple, vous devez faire
$ java -jar tools/apktool.jar if [fichier de plateforme approprié]
Vous pouvez également générer des documents API au format html.
$ make api
Vous pouvez voir toutes les options offertes par l'outil :
$ ruby scripts/cmd.rb -h
$ ruby scripts/cmd.rb --help
Comme dexdump dans le SDK Android, redexer vous permet de visualiser l'intérieur du fichier dex donné au format YAML.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd unparse [--to blah.yml]
Cette option affiche les instructions pour une méthode spécifiée.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dump_method --mtd cls.mtd
Cette fonctionnalité permet de tester les modules d'analyse et de désanalyse de redexer. Elle génère probablement un fichier dex identique.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd id [--to blah.dex]
Vous pouvez également voir des statistiques de base sur le fichier dex, par ex. # instr.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd info
Cette option affiche tous les noms de classes définis dans le fichier dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes
Cela peut être utile pour rechercher des bibliothèques tierces spécifiques, par ex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes | egrep 'apache'
Cette option affiche l'utilisation de l'API dans le fichier dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api [--sdk android.]
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api --sdk com.facebook.
N'êtes-vous pas curieux de savoir à quel point certains opcodes sont rarement utilisés dans les bytecodes Dalvik ? Cela vous montrera l'histogramme de tous les opcodes, ou vous pouvez consulter la fréquence d'utilisation d'un opcode précis dans l'application donnée.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd opstat [--op opcode1,opcode2,...]
Par exemple,
$ 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
Cette option effectue une analyse de résolution d'intent basée sur la propagation, et affiche les transitions entre les classes Activity.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd intent
Cette option génère un fichier pdf représentant un graphe d'appels du fichier donné. Si vous ne spécifiez pas le nom pdf, cg.pdf sera utilisé.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cg [--to blah.pdf] [--no-pdf]
Cette option génère un fichier pdf qui montre un graphe de flot de contrôle de la méthode donnée. Ajoutez un nom de méthode à un nom de classe avec un point : class_name.method_name
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cfg --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Cette option est similaire à la fonctionnalité ci-dessus, sauf qu'elle représente l'arbre de dominance (post).
$ ruby scripts/cmd.rb target.(apk|dex) --cmd (p)dom --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Cette option effectue une analyse classique de flux de données arrière.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd live --mtd cls.mtd
Cette option effectue une analyse classique de flux de données avant.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd const --mtd cls.mtd
Cette option effectue une analyse classique de flux de données avant.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd reach --mtd cls.mtd
Cette option trouve les dépendances entre classes.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dependants --mtd cls.mtd
Cette option affiche le nom de l'activité de lancement de l'apk donné.
$ ruby scripts/cmd.rb target.apk --cmd launcher
Cette option vous indique quels composants sont exposés à l'extérieur.
$ ruby scripts/cmd.rb target.apk --cmd exported
Ces options affichent les composants Android de base déclarés dans le manifest.
$ ruby scripts/cmd.rb target.apk --cmd [activity | service | provider | receiver]
Cette option explore les définitions de layout dans les ressources et affiche les vues personnalisées.
$ ruby scripts/cmd.rb target.apk --cmd custom_views
Cette option explore les définitions de layout dans les ressources et affiche les éléments Fragment.
$ ruby scripts/cmd.rb target.apk --cmd fragments
Cette option explore les définitions de layout dans les ressources et affiche les boutons, avec leur id (ou texte) ainsi que la méthode de rappel (si elle existe).
$ ruby scripts/cmd.rb target.apk --cmd buttons
Cette option affiche les permissions utilisées par l'apk.
$ ruby scripts/cmd.rb target.apk --cmd permissions
Cette option affiche la version SDK requise par l'apk.
$ ruby scripts/cmd.rb target.apk --cmd sdk
Si vous ne souhaitez pas décompresser le fichier apk, vous pouvez en fait faire la même chose avec une combinaison de commandes :
$ aapt dump badging target.apk | grep 'targetSdkVersion' | tr -dc 0-9.\\n
Cette option génère un fichier dex qui affiche un message simple. Ce fichier dex est créé uniquement avec les API de redexer.
$ ruby scripts/cmd.rb --cmd hello
Vérifiez son contenu.
$ dexdump -d results/classes.dex
Si vous êtes intéressé, vous pouvez tester ce fichier dex comme suit. Supposons que le chemin vers ANDROID_SDK est défini.
// créer un jar temporaire adapté à la VM Dalvik
$ aapt add temp.jar results/classes.dex
// (optionnel) si vous n'avez pas créé d'avd, créez-en un.
$ android create avd -n myAVD1 -t android-8
// lancez votre émulateur
$ emulator -avd myAVD1 &
// poussez le jar temporaire
$ adb push temp.jar /data
// connectez-vous au shell adb
$ adb shell
// enfin, exécutez le dex
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar \
-classpath /data/temp.jar Hello
Hello, DEX
#
Ceci est une variante de la fonctionnalité de réécriture. Avec cette fonctionnalité, vous pouvez journaliser
le comportement de l'application depuis des points de vue spécifiques. Le fichier dex précompilé
pour la bibliothèque de journalisation est fourni : data/logging.dex. Si vous souhaitez ajouter
plus de fonctionnalités ou d'utilitaires, compilez-le comme suit :
$ cd logging
$ gradle copyDex
$ cd ..
Ensuite, utilisez la commande suivante :
$ ruby scripts/cmd.rb target.apk --cmd logging
trim.py peut capturer les séquences d'appel-retour de l'application instrumentée. (Vous devez d'abord instrumenter l'application testée à l'aide de redexer.)
Si ces journaux sont suffisamment courts, c'est-à-dire que le téléphone (ou l'émulateur) peut contenir toutes les informations en mémoire, vous pouvez utiliser le mode hors ligne du script :
$ ./scripts/trim.py -d
Notez que tous les paramètres de ligne de commande seront passés à adb logcat, et
par défaut, org.umd.logging:I *:S est passé pour filtrer les journaux non pertinents.
Si les journaux débordent, vous devez utiliser le mode en ligne :
$ ./scripts/trim.py
Le script intercepte l'interruption clavier, vous pouvez donc terminer la journalisation via Ctrl+C.
Dans les deux modes, les journaux sont sauvegardés dans log.txt et affichés à l'écran en une fois. Ainsi, après avoir collecté les journaux, vous devrez peut-être déplacer ce fichier, par ex. :
$ mv log.txt app.scenario.txt
La fonctionnalité de journalisation ci-dessus est générale dans la mesure où vous pouvez spécifier quoi journaliser
au niveau d'une méthode. (Voir le module logging pour plus de détails.)
Cependant, cela est parfois trop verbeux et peut entraîner une dégradation des performances.
Cette fonctionnalité est conçue pour journaliser uniquement les interactions utilisateur. Avec cette fonctionnalité,
vous pouvez capturer uniquement les événements liés à l'interface utilisateur. De même, le fichier dex précompilé
pour la bibliothèque de journalisation est fourni : data/logging-ui.dex. Si vous souhaitez modifier
la verbosité des informations de l'interface utilisateur, compilez-le comme suit :
$ cd logging-ui
$ gradle copyDex
$ cd ..
Ensuite, utilisez la commande suivante :
$ ruby scripts/cmd.rb target.apk --cmd logging_ui
La bibliothèque de journalisation est héritée du service android a11y, qui nécessite
le consentement explicite de l'utilisateur. Ainsi, après avoir installé l'apk réécrite, allez dans
Paramètres/Accessibilité et activez le service UI Logging.
(Cette étape peut être considérée comme similaire à l'activation du mode de débogage de l'appareil.)
Dans le logcat, les messages avec les balises org.umd.logging_ui.* sont les interactions
entre l'utilisateur et l'application testée.
Cette option trouve les chemins de transition entre composants vers les appels de méthode cibles.
$ ruby scripts/cmd.rb target.apk --cmd directed
Vous pouvez spécifier les méthodes cibles à invoquer dans data/directed.txt
Ces chemins de transition entre composants sont utilisés pour piloter les applications afin de tester les vulnérabilités de sécurité dans les bibliothèques tierces. Plus de détails sont décrits dans l'article suivant :
* Brahmastra: Driving Apps to Test the Security of Third-Party Components.
R. Bhoraskar, et al., In 23rd Usenix Security Symposium (Security '14).
withTimeout.rb peut construire un fichier de saut pour une application automatiquement. Ce script exécute cmd.rb avec un délai d'attente spécifique, utilisé pour limiter le temps passé à instrumenter une seule classe. Il s'agit d'un contournement temporaire pour les classes occasionnelles qui se bloquent dans une boucle lors de l'instrumentation. Lorsque ce script trouve une classe qui plante, il l'ajoute au fichier de saut et continue là où il s'était arrêté. Une fois que withTimeout a terminé, il y aura un fichier appelé [nom de l'apk]-skip.txt dans le répertoire data, qui peut être utilisé pour construire une application entièrement instrumentée pour cette apk. Pour utiliser withTimeout, appelez simplement
$ ruby scripts/withTimeout.rb TIMEOUT COMMANDS
Où TIMEOUT est la durée du délai d'attente en secondes (300 est recommandé) et COMMANDS sont toutes les entrées de ligne de commande habituelles que vous passeriez à scripts/cmd.rb pour l'apk.