Corvus DDoSKrom

Smali - Descompilar/[Modificar]/Compilar

28 November 2024
pentest mobile
android
Última actualización:20 December 2024
4 Minutos
769 Words

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 ofuscadas). Entonces, podría ser interesante descompilar el apk, modificar el código y recompilarlo.

Opcodes reference: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Fast Way Usando Visual Studio Code y la extensión APKLab, puedes descompilar 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

Decompile the APK Usando APKTool puedes acceder al código smali y recursos:

Terminal window
1
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í:

Ejemplos de cambios Smali

Google CTF 2018 - Shall We Play a Game?

O puedes revisar a continuación algunos cambios Smali explicados.

Recompilar el APK Después de modificar el código, puedes recompilar el código usando:

Terminal window
1
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

Firmar el nuevo APK Luego, necesitas generar una clave (se te pedirá una contraseña y algo de información que puedes llenar aleatoriamente):

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

Finalmente, firma el nuevo APK:

Terminal window
1
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). Más información aquí.

Terminal window
1
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
2
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 apksigner (después de zipalign).

Terminal window
1
apksigner sign --ks key.jks ./dist/mycompiled.apk

Modificando Smali Para el siguiente código Java Hello World:

Terminal window
1
public static void printHelloWorld() {
2
System.out.println("Hello World")
3
}

El código Smali sería:

Terminal window
1
.method public static printHelloWorld()V
2
.registers 2
3
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
4
const-string v1, "Hello World"
5
invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
6
return-void
7
.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:

Terminal window
1
#Number
2
const v9, 0xf4240
3
const/4 v8, 0x1
4
#Strings
5
const-string v5, "wins"

Operaciones Básicas

Terminal window
1
#Math
2
add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0
3
mul-int v0,v2,0x2 #v2*0x2 and save in v0
4
5
#Move the value of one object into another
6
move v1,v2
7
8
#Condtions
9
if-ge #Greater or equals
10
if-le #Less or equals
11
if-eq #Equals
12
13
#Get/Save attributes of an object
14
iget v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save this.o inside v0
15
iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside this.o
5 collapsed lines
16
17
#goto
18
:goto_6 #Declare this where you want to start a loop
19
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
20
goto :goto_6 #Always go to: :goto_6

Cambios Más Grandes Registro

Terminal window
1
#Log win: <number>
2
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
3
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String
4
move-result-object v1 #Move to v1
5
const-string v5, "wins" #Save "win" inside v5
6
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.

Terminal window
1
const/4 v10, 0x1
2
const/4 v11, 0x1
3
const/4 v12, 0x1
4
iget v10, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I
5
invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
6
move-result-object v11
7
invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
8
move-result-object v12
9
invoke-virtual {v12}, Landroid/widget/Toast;->show()V
Article title:Smali - Descompilar/[Modificar]/Compilar
Article author:Rafael Morinigo
Fecha de publicación:28 November 2024