Smali - Decompiling/[Modifying]/Compiling

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

A veces es interesante modificar el c贸digo de la aplicaci贸n para acceder a informaci贸n oculta para ti (quiz谩s contrase帽as o flags bien ofuscados). Entonces, podr铆a ser interesante decompilar el apk, modificar el c贸digo y recompilarlo.

Referencia de Opcodes: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Forma R谩pida

Usando Visual Studio Code y la extensi贸n APKLab, puedes decompilar autom谩ticamente, modificar, recompilar, firmar e instalar la aplicaci贸n sin ejecutar ning煤n comando.

Otro script que facilita mucho esta tarea es https://github.com/ax/apk.sh

Decompilar el APK

Usando APKTool puedes acceder al c贸digo smali y recursos:

bash
apktool d APP.apk

Si apktool te da alg煤n error, intenta instalar la 煤ltima versi贸n

Algunos archivos interesantes que deber铆as revisar son:

  • res/values/strings.xml (y todos los xml dentro de res/values/*)
  • AndroidManifest.xml
  • Cualquier archivo con extensi贸n .sqlite o .db

Si apktool tiene problemas decodificando la aplicaci贸n, echa un vistazo a https://ibotpeaches.github.io/Apktool/documentation/#framework-files o intenta usar el argumento -r (No decodificar recursos). Entonces, si el problema estaba en un recurso y no en el c贸digo fuente, no tendr谩s el problema (tampoco descompilar谩s los recursos).

Cambiar c贸digo smali

Puedes cambiar instrucciones, cambiar el valor de algunas variables o agregar nuevas instrucciones. Yo cambio el c贸digo Smali usando VS Code, luego instalas la extensi贸n smalise y el editor te dir谩 si alguna instrucci贸n es incorrecta.
Algunos ejemplos se pueden encontrar aqu铆:

O puedes ver a continuaci贸n algunos cambios en Smali explicados.

Recompilar el APK

Despu茅s de modificar el c贸digo, puedes recompilar el c贸digo usando:

bash
apktool b . #In the folder generated when you decompiled the application

Compilar谩 el nuevo APK dentro de la carpeta dist.

Si apktool lanza un error, intenta instalar la 煤ltima versi贸n

Firma el nuevo APK

Luego, necesitas generar una clave (se te pedir谩 una contrase帽a y algo de informaci贸n que puedes llenar aleatoriamente):

bash
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>

Finalmente, firma el nuevo APK:

bash
jarsigner -keystore key.jks path/to/dist/* <your-alias>

Optimizar nueva aplicaci贸n

zipalign es una herramienta de alineaci贸n de archivos que proporciona una optimizaci贸n importante a los archivos de aplicaci贸n de Android (APK). More information here.

bash
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk

Firma el nuevo APK (驴de nuevo?)

Si prefieres usar apksigner en lugar de jarsigner, debes firmar el apk despu茅s de aplicar la optimizaci贸n con zipalign. PERO TEN EN CUENTA QUE SOLO TIENES QUE FIRMAR LA APLICACI脫N UNA VEZ CON jarsigner (antes de zipalign) O CON aspsigner (despu茅s de zipalign).

bash
apksigner sign --ks key.jks ./dist/mycompiled.apk

Modificando Smali

Para el siguiente c贸digo Java Hello World:

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

El c贸digo Smali ser铆a:

java
.method public static printHelloWorld()V
.registers 2
sget-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;)V
return-void
.end method

El conjunto de instrucciones Smali est谩 disponible aqu铆.

Cambios ligeros

Modificar valores iniciales de una variable dentro de una funci贸n

Algunas variables se definen al principio de la funci贸n utilizando el opcode const, puedes modificar sus valores, o puedes definir nuevos:

bash
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"

Operaciones B谩sicas

bash
#Math
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
mul-int v0,v2,0x2 #v2*0x2 and save in v0

#Move the value of one object into another
move v1,v2

#Condtions
if-ge #Greater or equals
if-le #Less or equals
if-eq #Equals

#Get/Save attributes of an object
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o

#goto
:goto_6 #Declare this where you want to start a loop
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
goto :goto_6 #Always go to: :goto_6

Cambios Mayores

Registro

bash
#Log win: <number>
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
move-result-object v1 #Move to v1
const-string v5, "wins" #Save "win" inside v5
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"

Recomendaciones:

  • Si vas a usar variables declaradas dentro de la funci贸n (declaradas v0,v1,v2...) coloca estas l铆neas entre el .local <n煤mero> y las declaraciones de las variables (const v0, 0x1)
  • Si quieres poner el c贸digo de registro en medio del c贸digo de una funci贸n:
    • Agrega 2 al n煤mero de variables declaradas: Ej: de .locals 10 a .locals 12
    • Las nuevas variables deben ser los siguientes n煤meros de las variables ya declaradas (en este ejemplo deber铆an ser v10 y v11, recuerda que comienza en v0).
    • Cambia el c贸digo de la funci贸n de registro y usa v10 y v11 en lugar de v5 y v1.

Toasting

Recuerda agregar 3 al n煤mero de .locals al principio de la funci贸n.

Este c贸digo est谩 preparado para ser insertado en el medio de una funci贸n (cambia el n煤mero de las variables seg煤n sea necesario). Tomar谩 el valor de this.o, lo transformar谩 a String y luego har谩 un toast con su valor.

bash
const/4 v10, 0x1
const/4 v11, 0x1
const/4 v12, 0x1
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v11
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v12
invoke-virtual {v12}, Landroid/widget/Toast;->show()V

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks