Désassembler une application Android (complément)

android

Cet article est un complément de celui de Julien.

Partons d’un APK Crackme01.apk. Le fichier est disponible ici.

Voici à quoi ressemble le Crack Me :
capture1Presentation

Deux methodes existent pour reverser une application android :

  1. La première avec dex2jar et jd-gui, cette méthode permet d’obtenir quasiment le code original, facile à analyser du code java et simple d’utilisation.Cependant avec cette méthode on ne peut pas modifier le code java (.class), nos ressources sont présentes sous la forme numérique uniquement dans les findviewbyid, par exemple.
  2. La seconde avec smali(assembleur) et baksmali(desassembleur), on retrouve ces outils dans apktool (d pour desassembler, b pour assembler).Lorsque l’on désassemble on obtient un code source smali, et on peut le réassembler. Une bible pour le code smali est présente ici : http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

 

Le but de ce crackme est de trouver le mot de passe pour la méthode 1.
Dans la seconde méthode, on ajoute un message rapide (Toasts) « Simple, non ? »

Methode 1 : Dex2jar et JD-GUI

On décompresse notre archive ZIP :

$ unzip Crackme01.apk 
Archive:  Crackme01.apk
  inflating: res/layout/activity_crack_me01.xml  
  inflating: res/menu/activity_crack_me01.xml  
  inflating: AndroidManifest.xml     
 extracting: resources.arsc          
 extracting: res/drawable-hdpi/ic_launcher.png  
 extracting: res/drawable-ldpi/ic_launcher.png  
 extracting: res/drawable-mdpi/ic_launcher.png  
 extracting: res/drawable-xhdpi/ic_launcher.png  
  inflating: classes.dex             
  inflating: META-INF/MANIFEST.MF    
  inflating: META-INF/CERT.SF        
  inflating: META-INF/CERT.RSA

Avant de continuer, on est obligé de vous parler de la machine Dalvik. Cette machine dalvik est une machine virtuelle utilisée par Android. Elle a été développée par Google pour ne pas utiliser la JVM. La différence notable avec la JVM est la gestion du registre. Pour la JVM, la gestion est basée sur la pile contrairement à la machine Dalvik qui est illimitée. Cette machine utilise un fichier .dex qui est le regroupement de l’ensemble des classes JAVA compilées.

Obtenons un jar de notre fichier .dex :
$ dex2jar classes.dex
dex2jar classes.dex -> classes-dex2jar.jar

Utilisons JD-GUI, afin de voir nos fichiers .class qui sont présents dans l’archive .JAR
jd-gui classes-dex2jar.jarjd-gui

Dans le fichier Crackme01.class on peut voir la ligne suivante :
final EditText localEditText = (EditText)findViewById(2131165185);

Cette ligne fait référence a un id, qui a pour intitulé motDePasse comme on peut le voir dans le fichier R.class :
public static final int motDePasse = 2131165185;

C’est l’EditText qui est utilisé pour saisir notre mot de passe.

On retourne dans le fichier Crackme01.class :

if ((localEditText.getText().toString() != null) && (localEditText.getText().toString().equals("oversimple")))
          localToast.setText(2130968580);

On voit que l’on compare notre EditText avec une chaîne de caractère « oversimple ». Cette chaine de caractère « oversimple » est notre mot de passe.

Méthode 2 : Smali & backsmali

Pour la deuxieme méthode avec smali et backsmali, on utilisera apktool qui contient un ensemble d’outils. De plus, celui ci est simple d’utilisation alors pourquoi s’en priver ?

On décompile notre APK.

$ apktool d Crackme01.apk reverseCrackme01/
I: Baksmaling...
I: Loading resource table...
I: Loaded.
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/pierre/apktool/framework/1.apk
I: Loaded.
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Done.
I: Copying assets and libs...

On obtient un répertoire reverseCrackme01 :

$ cd reverseCrackme01/
$ ls   
AndroidManifest.xml  apktool.yml  res  smali

La premiere chose a regarder est le Manifest :

$ cat AndroidManifest.xml 
<!--?xml version="1.0" encoding="utf-8"?-->

On peut voir que notre main est le fichier CrackMe01 car celui-ci possède les intents nécessaires (MAIN et LAUNCHER)

Regardons maintenant les fichiers avec le code source smali :

$ ls smali/fr/oversimple/crackme01/
BuildConfig.smali  CrackMe01$1.smali  CrackMe01.smali  R$attr.smali  R$drawable.smali  R$id.smali  R$layout.smali  R$menu.smali  R$string.smali  R$style.smali  R.smali

Si on regarde dans le fichier CrackMe01\$1.smali, on peut voir la méthode onClick. Cette méthode correspond à un clic sur le bouton « Valider ». Voici un bref aperçu du code smali :

invoke-interface {v0}, Landroid/text/Editable;-&gt;toString()Ljava/lang/String;
move-result-object v0
const-string v1, "oversimple"
invoke-virtual {v0, v1}, Ljava/lang/String;-&gt;equals(Ljava/lang/Object;)Z
move-result v0

Ce bout de code permet de comparer notre mot de passe « oversimple » avec notre EditText(dans le but de simplifier, on affiche uniquement le retour du toString)

Et le test de comparaison final :

if-eqz v0, :cond_0
 
.line 29
iget-object v0, p0, Lfr/oversimple/crackme01/CrackMe01$1;-&gt;val$toast:Landroid/widget/Toast;
const v1, 0x7f040004
invoke-virtual {v0, v1}, Landroid/widget/Toast;-&gt;setText(I)V
 
.line 33
:goto_0
iget-object v0, p0, Lfr/oversimple/crackme01/CrackMe01$1;-&gt;val$toast:Landroid/widget/Toast;
invoke-virtual {v0}, Landroid/widget/Toast;-&gt;show()V
 
.line 34
return-void
 
.line 31
:cond_0
iget-object v0, p0, Lfr/oversimple/crackme01/CrackMe01$1;-&gt;val$toast:Landroid/widget/Toast;
const v1, 0x7f040005
invoke-virtual {v0, v1}, Landroid/widget/Toast;-&gt;setText(I)V
goto :goto_0

Si l’instruction if-eqz est égale à 0 alors nous allons à la condition cond_0. sinon on continue la suite donc .line 29.
Pour information, les valeurs qui nous intéressent se trouvent dans le fichier R$string.smali :
.field public static final ok:I = 0x7f040004
.field public static final ko:I = 0x7f040005

Le but de la deuxième méthode n’étant pas forcement de voir le mot de passe mais d’ajouter un message au démarrage de l’application.

Dans le fichier CrackMe01.smali, ligne 37 et après nous avons :

const-string v4, ""
 
const/4 v5, 0x1
 
invoke-static {v3, v4, v5}, Landroid/widget/Toast;-&gt;makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
 
move-result-object v1

Nous souhaitons juste ajouter notre message, donc à la place de «  » mettons : « Simple, non ? » et appelons la méthode afin de le rendre visible :
invoke-virtual {v1}, Landroid/widget/Toast;->show()V

Ce qui donne :

const-string v4, "Simple, non ?"
 
const/4 v5, 0x1
 
invoke-static {v3, v4, v5}, Landroid/widget/Toast;-&gt;makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
 
move-result-object v1
 
invoke-virtual {v1}, Landroid/widget/Toast;-&gt;show()V

On reconstruit l’application avec apktool b, il faut se placer dans le répertoire racineCrackme01 (ou ce trouve le fichier apktool.yml)

$ apktool b 
I: Checking whether sources has changed...
I: Smaling...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...

Un nouveau repertoire apparait dist/

On crée une clé afin de signer notre application :
keytool -genkey -v -keystore oversimple.keystore -alias oversimple -keyalg RSA -validity 25000

Une fois la clé créée, on signe notre application :
jarsigner -digestalg SHA1 -sigalg MD5withRSA -verbose -keystore oversimple.keystore dist/Crackme01.apk oversimple

Notre apk est signée de source inconnu.

On envoie notre apk :

adb install dist/Crackme01.apk 
978 KB/s (184902 bytes in 0.184s)
	pkg: /data/local/tmp/Crackme01.apk
Success

Un article suivant présentera les commandes utiles de ADB.

Résultat au démarrage de notre APK :

resultatFinal

Conclusion

Pour cette introduction au reverse d’application Android, rien de bien difficile, plusieurs articles en tête, notammennt un article sur les commandes adb et les pouvoirs de cette commande 😉

Sources

dex2jar : http://code.google.com/p/dex2jar/
jd-gui : http://java.decompiler.free.fr/?q=jdgui
apktool : http://code.google.com/p/android-apktool/

It’s oversimple isn’t it?

Décompiler une application android

android

On trouve de nombreux malwares sous android. Ceux ci utilisent généralement des applications payantes crackées pour se diffuser.

Nous allons aujourd’hui voir comment décompiler et visualiser une apk.
Pour cela nous allons utiliser deux outils :

  • JD-GUI
  • dex2jar

La machine de Dalvik

La machine de Dalvik est une machine virtuelle présente sur les téléphones android. Elle est très proche d’une JVM.
D’après Wikipédia, « Un outil appelé dx est utilisé pour convertir quelques .class Java en .dex ».
Si on ouvre un apk avec gestionnaire d’archive on obtient quelque chose comme ça :

archiveAPK

Le fichier classe.dex est celui que nous allons décompiler.

dex2jar

Le logiciel dex2jar est téléchargeable à l’adresse suivante : http://code.google.com/p/dex2jar/downloads/list

Pour l’utiliser il suffit de décompresser le fichier et pour l’utiliser :

$ ./dex2jar.sh classes.dex

On obtient alors un fichier jar. Pour visualiser le .jar, utilisons le logiciel JD-GUI.

JD-GUI

Le logiciel JD-GUI permet d’afficher les fichiers d’un .jar. Les fichiers .class sont alors affichés d’une manière user friendly.

DecompAPK

Conclusion

Il est tellement simple d’observer le contenu d’un apk qu’il serait stupide de s’en passer. Si vous souhaitez en savoir plus sur le langage utilisé par la machine de Dalvik, je vous recommande l’article suivant de Virtualabs :
http://virtualabs.fr/Reversing-d-applications-Android

It’s oversimple isn’t it?