Ingeniería inversa Android Crackme01 de deurus

Hace poco me he interesado por hacer ingeniería inversa prácticamente a todo, y ahora estoy realizando ingeniería inversa a aplicaciones de Android. Y para aprender siempre viene bien recurrir a los crackme :) y la verdad es que no hay muchos por la red, espero hacerlos todos y publicar la solución de cada uno. Tras esta pequeña introducción, ¡comencemos!

Antes de nada:

  • Descargamos el Android crackme01 de deurus de la web crackmes.de.
  • Y necesitaremos también APKTool para pasar el archivo .apk a smali
  • Previamente a esto, deberíais tener el Android SDK, con su emulador, Google APIs…
  • Testsign: Es una herramienta de terceros desarrollada para “firmar” o generar certificados aleatorios para indicarle al sistema que el fichero que hemos modificado se trata de una aplicación Android.

Instalo el crackme01 en un dispositivo físico (aunque pueden hacerlo en el simulador).

adb install crackme01.apk

Y una vez instalado, ¡lo probamos para ver que hace! Esta es la pantalla recién abierta:

crackme01

Probamos a introducir un serial, he probado “mgp25” pero cuando se introduce algo de texto, la aplicación no hace nada, lo que nos hace pensar que el serial será únicamente numérico, así que probamos algo…

crackme01-badboy

Y en el título comprobamos que ahora aparece “Bad boy!”. ¡Bien! Es un primer paso.

Ahora pasaremos el .apk a smali:

apktool d crackme01.apk crackme01

apktool

Ahora se habrá creado una carpeta llamada crackme01 y dentro habrá una que se llama smali, ahi es donde vamos a ir. Vamos al archivo Screen1.smali y buscamos la cadena de texto “Bad boy!”

    .line 10032
    sget-object v0, Lkawa/standard/Scheme;->numGrt:Lgnu/kawa/functions/NumberCompare;

    sget-object v1, Lgnu/kawa/reflect/Invoke;->invoke:Lgnu/kawa/reflect/Invoke;

    sget-object v2, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit24:Lgnu/mapping/SimpleSymbol;

    invoke-static {v2}, Lcom/google/youngandroid/runtime;->lookupInCurrentFormEnvironment(Lgnu/mapping/Symbol;)Ljava/lang/Object;

    move-result-object v2

    sget-object v3, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit21:Lgnu/mapping/SimpleSymbol;

    invoke-virtual {v1, v2, v3}, Lgnu/mapping/Procedure;->apply2(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v1

    invoke-static {v1}, Lcom/google/youngandroid/runtime;->sanitizeComponentData(Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v1

    sget-object v2, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit35:Lgnu/math/IntNum;

    invoke-static {v1, v2}, Lgnu/lists/LList;->list2(Ljava/lang/Object;Ljava/lang/Object;)Lgnu/lists/Pair;

    move-result-object v1

    sget-object v2, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit36:Lgnu/lists/PairWithPosition;

    const-string v3, ">"

    invoke-static {v0, v1, v2, v3}, Lcom/google/youngandroid/runtime;->callYailPrimitive(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v0

    sget-object v1, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;

    if-eq v0, v1, :cond_0

    sget-object v0, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit0:Lgnu/mapping/SimpleSymbol;

    invoke-static {v0}, Lcom/google/youngandroid/runtime;->lookupInCurrentFormEnvironment(Lgnu/mapping/Symbol;)Ljava/lang/Object;

    move-result-object v0

    sget-object v1, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit13:Lgnu/mapping/SimpleSymbol;

    const-string v2, "Crackme01!  << by deurus >> - Good boy!"

    sget-object v3, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit14:Lgnu/mapping/SimpleSymbol;

    invoke-static {v0, v1, v2, v3}, Lcom/google/youngandroid/runtime;->$PcSetAndCoerceProperty$Ex(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v0

    :goto_0
    return-object v0

    :cond_0
    sget-object v0, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit0:Lgnu/mapping/SimpleSymbol;

    invoke-static {v0}, Lcom/google/youngandroid/runtime;->lookupInCurrentFormEnvironment(Lgnu/mapping/Symbol;)Ljava/lang/Object;

    move-result-object v0

    sget-object v1, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit13:Lgnu/mapping/SimpleSymbol;

    const-string v2, "Crackme01!  << by deurus >> - Bad boy!"

    sget-object v3, Lappinventor/ai_garikoitzmartinez/crackme01/Screen1;->Lit14:Lgnu/mapping/SimpleSymbol;

    invoke-static {v0, v1, v2, v3}, Lcom/google/youngandroid/runtime;->$PcSetAndCoerceProperty$Ex(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v0

    goto :goto_0

Como podemos observar lo que hace que vaya a “Good boy!” o “Bad boy!” es una simple condición “if-eq”. Esta en concreto es una condición sencilla, pero para ejemplos más avanzados, es recomendable echar un ojo a los Dalvik opcodes

Nosotros queremos ir a “Good boy!” y lo importante se encuentra aquí:

    sget-object v1, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;

    if-eq v0, v1, :cond_0

Lo primero que se me ocurre, es cambiar el FALSE y poner un TRUE, de esa manera no iremos a la condición cond_0 que es la que nos sacará “Bad boy!”.

    sget-object v1, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;

Ya tenemos el archivo modificado, ahora toca reconstruir el .apk a partir de nuestras modificaciones.

apktool b crackme01 crackme01-solucionado.apk

APKTool-Build

Ya tenemos creado el .apk, ahora lo firmamos con testsign.jar

java -jar testsign.jar crackme01-solucionado.apk

firmar

Ahora se debería usar zipalign sobre el .apk para que el rendimiento en el dispositivo Android sea el óptimo, pero como no es especialmente importante en este caso, me he saltado este paso, y procedo a instalarlo en el dispositivo.

adb install crackme01-solucionado.apk

instalarAPK

Ya lo tenemos instalado en nuestro dispositivo, veamos si hemos conseguido lo que queremos, introduciré el mismo número serie que al principio:

exito

¡Lo hemos conseguido! Ahora cualquier número de serie será aceptado y conseguiremos el “Good boy!”. Este crackme era muy sencillo y ya estoy haciendo algunos de más pensar, intentaré publicar todas las soluciones de los crackme que vaya haciendo.

También os dejo el crackme parcheado por si quereis probarlo vosotros mismos:

crackme01-solucionado.apk - Descargar

SHA1 checksum: e497fd05407557e8b0bad0b286a9097c4d4871ae

Un saludo :)

Updated: