Smali - Decompiling/[Modifying]/Compiling

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Ponekad je interesantno modifikovati kod aplikacije kako biste pristupili skrivenim informacijama (možda dobro obfuskirane lozinke ili zastavice). Zatim, može biti interesantno dekompilirati apk, modifikovati kod i ponovo ga kompilirati.

Referenca za opcode-ove: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Brzi način

Koristeći Visual Studio Code i ekstenziju APKLab, možete automatski dekompilirati, modifikovati, rekompilirati, potpisati i instalirati aplikaciju bez izvršavanja bilo koje komande.

Još jedan skript koji olakšava ovaj zadatak je https://github.com/ax/apk.sh

Dekompilacija APK-a

Korišćenjem APKTool-a možete pristupiti smali kodu i resursima:

apktool d APP.apk

Ako apktool prikaže bilo kakvu grešku, pokušajte instalirati najnoviju verziju.

Neki zanimljivi fajlovi koje biste trebali pogledati su:

  • res/values/strings.xml (i svi xml fajlovi unutar res/values/*)

  • AndroidManifest.xml

  • Svaki fajl sa ekstenzijom .sqlite ili .db

Ako apktool ima problema sa dekodiranjem aplikacije, pogledajte https://ibotpeaches.github.io/Apktool/documentation/#framework-files ili pokušajte koristiti argument -r (Ne dekodiraj resurse). Tada, ako je problem u resursu, a ne u izvornom kodu, nećete imati problem (takođe nećete dekompajlirati resurse).

Promena smali koda

Možete promeniti instrukcije, promeniti vrednost nekih promenljivih ili dodati nove instrukcije. Ja menjam Smali kod koristeći VS Code, zatim instalirate smalise ekstenziju i editor će vam reći ako je neka instrukcija neispravna. Neki primeri mogu se naći ovde:

Ili možete proveriti ispod objašnjenja nekih promena Smali koda.

Rekompajliranje APK-a

Nakon što izmenite kod, možete rekompajlirati kod koristeći:

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

Biće kompajliran novi APK unutar fascikle dist.

Ako apktool prikaže grešku, pokušajte instalirati najnoviju verziju

Potpišite novi APK

Zatim, trebate generisati ključ (biće vam zatražena lozinka i neke informacije koje možete popuniti nasumično):

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

Na kraju, potpišite novi APK:

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

Optimizujte novu aplikaciju

zipalign je alat za poravnanje arhive koji pruža važnu optimizaciju Android aplikacija (APK) datotekama. Više informacija ovde.

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

Potpišite novi APK (ponovo?)

Ako preferirate da koristite apksigner umesto jarsigner-a, trebali biste potpisati apk nakon primene optimizacije sa zipalingom. ALI OBRATITE PAŽNJU DA SAMO JEDNOM TREBA DA POTPISUJETE APLIKACIJU SA jarsigner-om (pre zipaligna) ILI SA apksigner-om (nakon zipalinga).

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

Modifikacija Smali koda

Za sledeći Hello World Java kod:

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

Smali kod bi bio:

.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

Smali instrukcioni set je dostupan ovde.

Lagane promene

Izmena početnih vrednosti promenljive unutar funkcije

Neke promenljive su definisane na početku funkcije koristeći opcode const, možete izmeniti njihove vrednosti ili definisati nove:

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

Osnovne operacije

Dodavanje instrukcija

Da biste dodali nove instrukcije u smali kod, pratite ove korake:

  1. Pronađite mesto u kodu gde želite da dodate instrukciju.

  2. Napišite smali kod za željenu instrukciju.

  3. Ubacite novu instrukciju na odgovarajuće mesto u smali kodu.

Na primer, ako želite da dodate instrukciju za ispisivanje teksta na ekranu, možete koristiti sledeći smali kod:

const-string v0, "Hello, World!"
invoke-static {v0}, Landroid/util/Log;->i(Ljava/lang/String;)I

Ovaj kod će ispisati "Hello, World!" u logu.

Izmena instrukcija

Da biste izmenili postojeću instrukciju u smali kodu, pratite ove korake:

  1. Pronađite instrukciju koju želite da izmenite.

  2. Izmenite odgovarajući deo smali koda.

  3. Sačuvajte izmene.

Na primer, ako želite da izmenite instrukciju koja proverava da li je broj veći od nule, možete koristiti sledeći smali kod:

const v0, 10
if-gt v0, v1, :greater_than_zero

Ovaj kod će proveriti da li je vrednost u registru v0 veća od nule.

Brisanje instrukcija

Da biste obrisali instrukciju iz smali koda, pratite ove korake:

  1. Pronađite instrukciju koju želite da obrišete.

  2. Uklonite odgovarajući deo smali koda.

  3. Sačuvajte izmene.

Na primer, ako želite da obrišete instrukciju koja postavlja vrednost registra na 0, možete koristiti sledeći smali kod:

const v0, 0

Ovaj kod će postaviti vrednost registra v0 na 0.

Zamena instrukcija

Da biste zamenili instrukciju u smali kodu, pratite ove korake:

  1. Pronađite instrukciju koju želite da zamenite.

  2. Napišite smali kod za željenu instrukciju.

  3. Zamenite postojeću instrukciju novom instrukcijom.

  4. Sačuvajte izmene.

Na primer, ako želite da zamenite instrukciju koja proverava da li je broj jednak nuli, možete koristiti sledeći smali kod:

const v0, 0
if-eqz v0, :equal_to_zero

Ovaj kod će proveriti da li je vrednost u registru v0 jednaka nuli.

#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

Veće promene

Pisanje logova

#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>"

Preporuke:

  • Ako ćete koristiti deklarisane promenljive unutar funkcije (deklarisane v0,v1,v2...), stavite ove linije između .local <broj> i deklaracija promenljivih (const v0, 0x1)

  • Ako želite da ubacite kod za beleženje u sredinu koda funkcije:

  • Dodajte 2 broju deklarisanih promenljivih: Na primer, od .locals 10 do .locals 12

  • Nove promenljive treba da budu sledeći brojevi već deklarisanih promenljivih (u ovom primeru bi trebalo da budu v10 i v11, zapamtite da počinje od v0).

  • Promenite kod funkcije za beleženje i koristite v10 i v11 umesto v5 i v1.

Toastovanje

Ne zaboravite da dodate 3 broju .locals na početku funkcije.

Ovaj kod je pripremljen da se ubaci u sredinu funkcije (promenite broj promenljivih po potrebi). Uzeće vrednost this.o, pretvoriti je u String i zatim napraviti toast sa njenom vrednošću.

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
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated