Smali - Decompiling/[Modifying]/Compiling
Reading time: 8 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Às vezes é interessante modificar o código do aplicativo para acessar informações ocultas para você (talvez senhas bem ofuscadas ou flags). Então, pode ser interessante decompilar o apk, modificar o código e recompilá-lo.
Referência de opcodes: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
Maneira rápida
Usando Visual Studio Code e a extensão APKLab, você pode decompilar automaticamente, modificar, recompilar, assinar e instalar o aplicativo sem executar nenhum comando.
Outro script que facilita muito essa tarefa é https://github.com/ax/apk.sh
Decompilar o APK
Usando o APKTool você pode acessar o smali code and resources:
apktool d APP.apk
If apktool gives you any error, try installing the latest version
Some interesting files you should look are:
- res/values/strings.xml (and all xmls inside res/values/*)
- AndroidManifest.xml
- Any file with extension .sqlite or .db
If apktool
has problems decoding the application take a look to https://ibotpeaches.github.io/Apktool/documentation/#framework-files or try using the argument -r
(Do not decode resources). Then, if the problem was in a resource and not in the source code, you won't have the problem (you won't also decompile the resources).
Change smali code
You can change instructions, change the value of some variables or add new instructions. I change the Smali code using VS Code, you then install the smalise extension and the editor will tell you if any instruction is incorrect.
Some examples can be found here:
Or you can check below some Smali changes explained.
Recompile the APK
After modifying the code you can recompile the code using:
apktool b . #In the folder generated when you decompiled the application
Isso irá compilar o novo APK dentro da pasta dist.
Se o apktool lançar um erro, tente installing the latest version
Assinar o novo APK
Então, você precisa gerar uma chave (você será solicitado a fornecer uma senha e algumas informações que pode preencher aleatoriamente):
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
Finalmente, assine o novo APK:
jarsigner -keystore key.jks path/to/dist/* <your-alias>
Otimizar nova aplicação
zipalign é uma ferramenta de alinhamento de arquivos que fornece otimizações importantes para Android application (APK) files. Mais informações aqui.
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
Assine o novo APK (de novo?)
Se você prefere usar apksigner em vez de jarsigner, você deve assinar o apk depois de aplicar a otimização com zipaling. MAS NOTE QUE VOCÊ SÓ PRECISA ASSINAR A APLICAÇÃO UMA VEZ COM jarsigner (antes do zipalign) OU COM aspsigner (depois do zipaling).
apksigner sign --ks key.jks ./dist/mycompiled.apk
Modificando Smali
Para o seguinte código Java Hello World:
public static void printHelloWorld() {
System.out.println("Hello World")
}
O Smali code seria:
.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
O conjunto de instruções Smali está disponível here.
Alterações leves
Modificar os valores iniciais de uma variável dentro de uma função
Algumas variáveis são definidas no início da função usando o opcode const, você pode modificar seus valores, ou pode definir novas:
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
Operações básicas
#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
Alterações maiores
Registro
#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>"
Recommendations:
- Se você for usar variáveis declaradas dentro da função (declaradas v0,v1,v2...) coloque essas linhas entre .local
e as declarações das variáveis (const v0, 0x1) - Se você quiser inserir o código de logging no meio do código de uma função:
- Adicione 2 ao número de variáveis declaradas: Ex: de .locals 10 para .locals 12
- As novas variáveis devem ser os números seguintes das já declaradas (neste exemplo devem ser v10 e v11, lembre-se que começa em v0).
- Altere o código da função de logging e use v10 e v11 em vez de v5 e v1.
Exibindo Toast
Lembre-se de adicionar 3 ao número de .locals no início da função.
Este código está preparado para ser inserido no meio de uma função (altere o número das variáveis conforme necessário). Ele pegará o valor de this.o, transformará em String e então fará um toast com seu valor.
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
Carregar uma Biblioteca Nativa na Inicialização (System.loadLibrary)
Às vezes você precisa pré-carregar uma biblioteca nativa para que ela seja inicializada antes de outras libs JNI (por exemplo, para habilitar telemetry/logging local do processo). Você pode injetar uma chamada para System.loadLibrary() em um inicializador estático ou no início de Application.onCreate(). Exemplo smali para um inicializador de classe estático (
.class public Lcom/example/App;
.super Landroid/app/Application;
.method static constructor <clinit>()V
.registers 1
const-string v0, "sotap" # library name without lib...so prefix
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
return-void
.end method
Como alternativa, coloque as mesmas duas instruções no início do seu Application.onCreate() para garantir que a biblioteca seja carregada o mais cedo possível:
.method public onCreate()V
.locals 1
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
invoke-super {p0}, Landroid/app/Application;->onCreate()V
return-void
.end method
Notas:
- Certifique-se de que a variante ABI correta da biblioteca exista em lib/
/ (por exemplo, arm64-v8a/armeabi-v7a) para evitar UnsatisfiedLinkError. - O carregamento muito cedo (class static initializer) garante que o logger nativo possa observar a atividade JNI subsequente.
Referências
- SoTap: Logger leve in-app de comportamento JNI (.so) – github.com/RezaArbabBot/SoTap
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.