Smali - Decompiling/[Modifying]/Compiling
Reading time: 7 minutes
tip
Lernen & ĂŒben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & ĂŒben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
UnterstĂŒtzen Sie HackTricks
- ĂberprĂŒfen Sie die AbonnementplĂ€ne!
- Treten Sie der đŹ Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter đŠ @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Manchmal ist es interessant, den Anwendungscode zu modifizieren, um auf versteckte Informationen zuzugreifen (vielleicht gut obfuskierte Passwörter oder Flags). Dann könnte es interessant sein, die apk zu dekompilieren, den Code zu Àndern und ihn neu zu kompilieren.
Opcodes reference: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
Fast Way
Mit Visual Studio Code und der APKLab Erweiterung können Sie die Anwendung automatisch dekompilieren, modifizieren, neu kompilieren, signieren und installieren, ohne einen Befehl auszufĂŒhren.
Ein weiteres Skript, das diese Aufgabe erheblich erleichtert, ist https://github.com/ax/apk.sh
Decompile the APK
Mit APKTool können Sie auf den smali code und die Ressourcen zugreifen:
apktool d APP.apk
Wenn apktool einen Fehler anzeigt, versuche die neueste Version zu installieren.
Einige interessante Dateien, die du dir ansehen solltest, sind:
- res/values/strings.xml (und alle xmls in res/values/*)
- AndroidManifest.xml
- Jede Datei mit der Erweiterung .sqlite oder .db
Wenn apktool
Probleme beim Dekodieren der Anwendung hat, schaue dir https://ibotpeaches.github.io/Apktool/documentation/#framework-files an oder versuche das Argument -r
zu verwenden (Ressourcen nicht dekodieren). Dann, wenn das Problem in einer Ressource und nicht im Quellcode lag, wirst du das Problem nicht haben (du wirst auch die Ressourcen nicht dekompilieren).
Smali-Code Àndern
Du kannst Anweisungen Ă€ndern, den Wert einiger Variablen Ă€ndern oder neue Anweisungen hinzufĂŒgen. Ich Ă€ndere den Smali-Code mit VS Code, du installierst dann die smalise Erweiterung und der Editor wird dir sagen, ob eine Anweisung falsch ist.
Einige Beispiele findest du hier:
Oder du kannst unten einige Smali-Ănderungen erklĂ€rt ansehen.
APK neu kompilieren
Nachdem du den Code geÀndert hast, kannst du den Code mit rekompilieren:
apktool b . #In the folder generated when you decompiled the application
Es wird die neue APK im dist Ordner kompilieren.
Wenn apktool einen Fehler ausgibt, versuche die neueste Version zu installieren.
Signiere die neue APK
Dann musst du einen SchlĂŒssel generieren (du wirst nach einem Passwort und einigen Informationen gefragt, die du zufĂ€llig ausfĂŒllen kannst):
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
SchlieĂlich signiere die neue APK:
jarsigner -keystore key.jks path/to/dist/* <your-alias>
Neue Anwendung optimieren
zipalign ist ein Archiv-Ausrichtungswerkzeug, das wichtige Optimierungen fĂŒr Android-Anwendungen (APK) bietet. More information here.
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
Signiere die neue APK (noch einmal?)
Wenn du bevorzugst, apksigner anstelle von jarsigner zu verwenden, solltest du die apk signieren, nachdem du die Optimierung mit zipalign angewendet hast. ABER BEACHTE, DASS DU DIE ANWENDUNG NUR EINMAL MIT jarsigner (vor zipalign) ODER MIT aspsigner (nach zipalign) SIGNIEREN MUSST.
apksigner sign --ks key.jks ./dist/mycompiled.apk
Modifying Smali
FĂŒr den folgenden Hello World Java-Code:
public static void printHelloWorld() {
System.out.println("Hello World")
}
Der Smali-Code wÀre:
.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
Das Smali-Befehlssatz ist hier verfĂŒgbar.
Leichte Ănderungen
Ăndern der Anfangswerte einer Variablen innerhalb einer Funktion
Einige Variablen werden zu Beginn der Funktion mit dem Opcode const definiert, Sie können deren Werte Àndern oder neue definieren:
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
Grundlegende Operationen
#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
GröĂere Ănderungen
Protokollierung
#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>"
Empfehlungen:
- Wenn Sie deklarierte Variablen innerhalb der Funktion verwenden möchten (deklarierte v0,v1,v2...), setzen Sie diese Zeilen zwischen die .local <number> und die Deklarationen der Variablen (const v0, 0x1)
- Wenn Sie den Logging-Code in die Mitte des Codes einer Funktion einfĂŒgen möchten:
- FĂŒgen Sie 2 zur Anzahl der deklarierten Variablen hinzu: z.B. von .locals 10 zu .locals 12
- Die neuen Variablen sollten die nÀchsten Zahlen der bereits deklarierten Variablen sein (in diesem Beispiel sollten es v10 und v11 sein, denken Sie daran, dass es bei v0 beginnt).
- Ăndern Sie den Code der Logging-Funktion und verwenden Sie v10 und v11 anstelle von v5 und v1.
Toasting
Denken Sie daran, 3 zur Anzahl der .locals zu Beginn der Funktion hinzuzufĂŒgen.
Dieser Code ist vorbereitet, um in die Mitte einer Funktion eingefĂŒgt zu werden (Ă€ndern Sie die Nummer der Variablen nach Bedarf). Er wird den Wert von this.o nehmen, ihn in String umwandeln und dann einen Toast mit seinem Wert machen.
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
Lernen & ĂŒben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & ĂŒben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
UnterstĂŒtzen Sie HackTricks
- ĂberprĂŒfen Sie die AbonnementplĂ€ne!
- Treten Sie der đŹ Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter đŠ @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.