Rétroingénierie d’applications Android 101

  1. Introduction
  2. Fondements des applications Android
  3. Début de la rétroingénierie d’applications Android
    • Exercice 1
  4. Rétroingénierie d’applications Android -… Bytecode DEX
    • Exercice 2
    • Exercice 3
    • Exercice 4
  5. Reverse Engineering Android Apps – Bibliothèques natives
    • Exercice 5
    • Exercice 6
  6. Reverse Engineering Android Apps – Obfuscation
    • Exercice 7
  7. Conclusion

Construire une application

L’une de mes plus grandes suggestions pour les gens qui cherchent à faire du reverse engineering, quelles qu’elles soient, est d’essayer de construire ce que vous voulez inverser. Dans le cas d’Android, vous avez de la chance car il y a tellement de ressources gratuites disponibles pour construire votre première application. Si vous n’avez jamais construit d’application Android, je vous suggère de commencer par là. Choisissez parmi les didacticiels et les vidéos disponibles ceux qui suscitent votre intérêt et commencez à construire. Lorsque vous comprenez comment un développeur construit quelque chose, il est beaucoup plus facile de comprendre comment le rétroconcevoir.

Revue des fondamentaux

Génial ! Vous avez construit une application ou appris les principes de base du développement d’applications Android. Voici une revue de certains des points importants. Cette page « Fondamentaux des applications » dans les docs des développeurs Android est une excellente revue.

  • Les applications Android sont au format de fichier APK. APK est fondamentalement un fichier ZIP. (Vous pouvez renommer l’extension du fichier en .zip et utiliser unzip pour ouvrir et voir son contenu.)
  • Contenu de l’APK (non exhaustif)
    • AndroidManifest.xml
    • META-INF/
      • Le certificat vit ici !
    • classes.dex
      • Bytecode Dalvik pour l’application dans le format de fichier DEX. C’est le code Java (ou Kotlin) que l’application exécutera par défaut.
    • lib/
      • Les bibliothèques natives de l’application, par défaut, vivent ici ! Sous le répertoire lib/, on trouve les répertoires spécifiques aux cpu. Ex : armeabi, mips,
    • assets/
      • Tout autre fichier pouvant être nécessaire à l’application.
      • Des bibliothèques natives supplémentaires ou des fichiers DEX peuvent être inclus ici. Cela peut arriver notamment lorsque les auteurs de logiciels malveillants veulent essayer de « cacher » du code supplémentaire, natif ou Dalvik, en ne l’incluant pas dans les emplacements par défaut.

Dalvik & Smali

La plupart des applications Android sont écrites en Java. Kotlin est également supporté et interopérable avec Java. Par facilité, pour le reste de cet atelier, lorsque je fais référence à « Java », vous pouvez supposer que je veux dire « Java ou Kotlin ». Au lieu d’exécuter le code Java dans la machine virtuelle Java (JVM) comme les applications de bureau, dans Android, Java est compilé au format bytecode Dalvik Executable (DEX). Pour les versions antérieures d’Android, le bytecode était traduit par la machine virtuelle Dalvik. Pour les versions plus récentes d’Android, on utilise l’Android Runtime (ART).
Si les développeurs, écrivent en Java et que le code est compilé en bytecode DEX, pour faire de la rétro-ingénierie, on travaille dans le sens inverse.

Smali est la version lisible par l’homme du bytecode Dalvik. Techniquement, Smali et baksmali sont le nom des outils (assembleur et désassembleur, respectivement), mais dans Android, nous utilisons souvent le terme « Smali » pour désigner les instructions. Si vous avez fait du reverse engineering ou de l’architecture informatique sur du code C/C++ compilé. SMALI est comme le langage d’assemblage : entre le code source de plus haut niveau et le bytecode.

Pour le code Java Hello World suivant :

public static void printHelloWorld() {System.out.println("Hello World")}

Le code Smali serait :

.method public static printHelloWorld()V.registers 2sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;const-string v1, "Hello World"invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)Vreturn-void.end method

Le jeu d’instructions Smali est disponible ici.

La plupart du temps, lors de la rétroconception d’applications Android, vous n’aurez pas besoin de travailler en Smali. La plupart des applications peuvent être remontées à un niveau encore plus élevé, le Java décompilé. Comme tous les outils, les décompilateurs Java peuvent avoir des bogues. Je vous suggère de regarder la sortie Smali chaque fois que la sortie Java décompilée semble douteuse. Travaillez ligne par ligne avec la référence de l’instruction pour comprendre ce que fait le code.

Pour obtenir le Smali de DEX, vous pouvez utiliser l’outil baksmali (désassembleur) disponible à https://github.com/JesusFreke/smali/wiki. L’outil smali vous permettra de réassembler le smali en DEX.

Points d’entrée de l’application

Un des points les plus importants de la rétro-ingénierie est de savoir où commencer votre analyse et les points d’entrée pour l’exécution du code en est une partie importante.

Activité du lanceur

L’activité du lanceur est ce que la plupart des gens pensent être le point d’entrée d’une application Android. L’activité du lanceur est l’activité qui est lancée lorsqu’un utilisateur clique sur l’icône d’une application. Vous pouvez déterminer l’activité du lanceur en consultant le manifeste de l’application. L’activité du lanceur aura les intents MAIN et LAUNCHER suivants énumérés.

N’oubliez pas que toutes les applications n’auront pas une activité de lanceur, en particulier les applications sans interface utilisateur. Des exemples d’applications sans interface utilisateur (et donc une activité de lanceur) sont les applications préinstallées qui exécutent des services en arrière-plan, comme la messagerie vocale.

<activity android:name=".LauncherActivity"><intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity>

Services

Les services s’exécutent en arrière-plan sans interface utilisateur. Il y a une myriade de façons dont ils peuvent être démarrés et constituent ainsi un point d’entrée pour les applications. La façon par défaut dont un service peut être démarré comme point d’entrée d’une application est à travers les Intents.

Lorsque l’API startService est appelée pour démarrer un service, la méthode onStart du service est exécutée.

Récepteurs de diffusion

Les diffusions peuvent être considérées comme un système de messagerie et les récepteurs de diffusion sont les auditeurs. Si une application a enregistré un récepteur pour une diffusion spécifique, le code dans ce récepteur est exécuté lorsque le système envoie la diffusion. Il y a 2 façons pour une application d’enregistrer un récepteur : dans le manifeste de l’application ou enregistré dynamiquement dans le code de l’application en utilisant l’appel d’API registerReceiver().

Dans les deux cas, pour enregistrer le récepteur, les filtres d’intention du récepteur sont définis. Ces filtres d’intention sont les diffusions qui doivent déclencher le récepteur.

Lorsque les diffusions spécifiques pour lesquelles le récepteur est enregistré sont envoyées, onReceive dans la classe BroadcastReceiver est exécutée.

Composants exportés (Services & Activités)

Les services et les activités peuvent également être « exportés », ce qui permet à d’autres processus sur l’appareil de démarrer le service ou de lancer l’activité. Les composants sont exportés en définissant un élément dans le manifeste comme ci-dessous. Par défaut, android:exported="false"à moins que cet élément soit défini à true dans le manifeste ou que des filtres d’intention soient définis pour l’activité ou le service.

<service android:name=".ExampleExportedService" android:exported="true"/><activity android:name=".ExampleExportedActivity" android:exported="true"/>

Sous-classe d’application

Les applications Android peuvent définir une sous-classe d’application. Les applications peuvent, mais ne sont pas obligées de définir une sous-classe personnalisée d’Application. Si une application Android définit une sous-classe d’Application, cette classe est instanciée avant toute autre classe de l’application.

Si la méthode attachBaseContext est définie dans la sous-classe d’Application, elle est appelée en premier, avant la méthode onCreate.

NEXT > 3. Démarrage de l’inversion des applications Android

.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.