Smali - Decompile Etme/[Değiştirme]/Derleme
Reading time: 8 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın:
HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Bazen uygulama kodunu, sizin için gizli bilgilere erişmek amacıyla (örneğin iyi obfuskelenmiş parolalar veya flag'ler) değiştirmek ilginç olabilir. Bu durumda apk'yı decompile etmek, kodu değiştirmek ve yeniden derlemek faydalı olabilir.
Opcodes reference: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
Hızlı Yol
Visual Studio Code ve APKLab eklentisini kullanarak, herhangi bir komut çalıştırmadan uygulamayı otomatik olarak decompile edebilir, değiştirebilir, yeniden derleyebilir, imzalayıp yükleyebilirsiniz.
Bu işi çok kolaylaştıran başka bir script ise https://github.com/ax/apk.sh
APK'yı decompile etme
APKTool kullanarak smali koduna ve kaynaklara erişebilirsiniz:
apktool d APP.apk
If apktool gives you any error, deneyin installing the latest version
Some interesting files you should look are:
- res/values/strings.xml (ve res/values/* içindeki tüm xml dosyaları)
- 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 (Kaynakları çözümleme). 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
Bazı komutları değiştirebilir, bazı değişkenlerin değerini değiştirebilir veya yeni komutlar ekleyebilirsiniz. Smali kodunu VS Code ile değiştiriyorum; ardından smalise extension'ı kurduğunuzda editör herhangi bir talimatın yanlış olup olmadığını söyleyecektir.
Some examples can be found here:
Or you can check below some Smali changes explained.
Recompile the APK
Kodu değiştirdikten sonra şu komutla kodu yeniden derleyebilirsiniz:
apktool b . #In the folder generated when you decompiled the application
Yeni APK, dist klasörünün içinde derlenecektir.
Eğer apktool bir hata verirse, en son sürümü yüklemeyi deneyin
Yeni APK'yi İmzala
Sonra, bir anahtar oluşturmanız gerekiyor (parola ve rastgele doldurabileceğiniz bazı bilgiler istenecek):
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
Son olarak, yeni APK'yı imzala:
jarsigner -keystore key.jks path/to/dist/* <your-alias>
Yeni uygulamayı optimize et
zipalign, Android uygulama (APK) dosyalarına önemli optimizasyon sağlayan bir arşiv hizalama aracıdır. Daha fazla bilgi burada.
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
Yeni APK'yı imzala (tekrar mi?)
Eğer jarsigner yerine apksigner kullanmayı tercih ediyorsanız, zipaling ile yapılan optimizasyonu uyguladıktan sonra APK'yı imzalamalısınız. ANCAK UNUTMAYIN Kİ UYGULAMAYI SADECE BİR KEZ İMZALAMANIZ YETERLİDİR jarsigner ile (zipalign'dan önce) veya aspsigner ile (zipaling'den sonra).
apksigner sign --ks key.jks ./dist/mycompiled.apk
Smali'yi Değiştirme
Aşağıdaki Hello World Java kodu için:
public static void printHelloWorld() {
System.out.println("Hello World")
}
Smali kodu şöyle olacaktır:
.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
The Smali instruction set şu adreste mevcuttur here.
Hafif Değişiklikler
Bir fonksiyon içindeki bir değişkenin başlangıç değerlerini değiştirin
Bazı değişkenler fonksiyonun başında opcode const kullanılarak tanımlanır; değerlerini değiştirebilir veya yeni değişkenler tanımlayabilirsiniz:
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
Temel İşlemler
#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
Daha Büyük Değişiklikler
Günlükleme
#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:
- Eğer fonksiyon içinde bildirilen değişkenleri kullanacaksanız (bildirilen v0,v1,v2...) bu satırları .local
ile değişkenlerin bildirimleri (const v0, 0x1) arasına koyun. - Eğer logging kodunu bir fonksiyonun gövdesinin ortasına koymak istiyorsanız:
- Bildirilen değişken sayısına 2 ekleyin: Örn: .locals 10 to .locals 12
- Yeni değişkenler, zaten bildirilen değişkenlerin sonraki numaraları olmalıdır (bu örnekte v10 ve v11 olmalıdır, bunun v0'dan başladığını unutmayın).
- Logging fonksiyonunun kodunu değiştirin ve v10 ve v11 kullanın, v5 ve v1 yerine.
Toast gösterimi
Fonksiyonun başında .locals sayısına 3 eklemeyi unutmayın.
Bu kod, bir fonksiyonun ortasına yerleştirilecek şekilde hazırlanmıştır (gerektiğinde değişken sayısını değiştirin). Bu kod this.o değerini alacak, onu String'e dönüştürecek ve ardından değeriyle bir toast gösterecektir.
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
Başlangıçta Yerel Bir Kütüphaneyi Yükleme (System.loadLibrary)
Bazen, diğer JNI kütüphanelerinden önce başlatılması için bir yerel kütüphaneyi önceden yüklemeniz gerekir (ör. process-local telemetri/kayıt etkinleştirmek için). System.loadLibrary() çağrısını bir static initializer içinde veya Application.onCreate() içinde erken bir aşamada enjekte edebilirsiniz. Statik sınıf başlatıcısı (
.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
Alternatif olarak, kütüphanenin mümkün olduğunca erken yüklenmesini sağlamak için aynı iki talimatı Application.onCreate()'in başına yerleştirin:
.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
Notlar:
- Kütüphanenin doğru ABI varyantının lib/
/ altında (örn. arm64-v8a/armeabi-v7a) bulunduğundan emin olun; UnsatisfiedLinkError hatasını önlemek için. - Çok erken yükleme (class static initializer), native logger'ın sonraki JNI aktivitelerini gözlemleyebilmesini garanti eder.
Referanslar
- SoTap: Hafif uygulama içi JNI (.so) davranış günlükleyicisi – github.com/RezaArbabBot/SoTap
tip
AWS Hacking'i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın:
HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
HackTricks