# Smali - Decompile/\[Modifying]/Compile {{#include ../../banners/hacktricks-training.md}} Bazen, gizli bilgilere erişmek için uygulama kodunu değiştirmek ilginç olabilir (belki iyi obfuscate edilmiş şifreler veya bayraklar). Bu durumda, apk'yı decompile etmek, kodu değiştirmek ve yeniden compile etmek ilginç olabilir. **Opcode referansı:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html) ## Hızlı Yol **Visual Studio Code** ve [APKLab](https://github.com/APKLab/APKLab) uzantısını kullanarak, herhangi bir komut çalıştırmadan uygulamayı **otomatik olarak decompile**, değiştirebilir, **recompile**, imzalayabilir ve kurabilirsiniz. Bu görevi oldukça kolaylaştıran başka bir **script** [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh) ## APK'yı Decompile Et APKTool kullanarak **smali koduna ve kaynaklarına** erişebilirsiniz: ```bash apktool d APP.apk ``` Eğer **apktool** herhangi bir hata verirse, [**en son sürümü**](https://ibotpeaches.github.io/Apktool/install/) yüklemeyi deneyin. **Bakmanız gereken bazı ilginç dosyalar**: - _res/values/strings.xml_ (ve res/values/* içindeki tüm xml'ler) - _AndroidManifest.xml_ - _.sqlite_ veya _.db_ uzantısına sahip herhangi bir dosya Eğer `apktool` uygulamayı **çözümlerken sorun yaşıyorsa**, [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) adresine bakın veya **`-r`** (Kaynakları çözümleme) argümanını kullanmayı deneyin. O zaman, sorun bir kaynakta değil de kaynak kodunda ise, bu sorunu yaşamayacaksınız (kaynakları da decompile etmeyeceksiniz). ## Smali kodunu değiştir **Talimatları** **değiştirebilir**, bazı değişkenlerin **değerlerini** değiştirebilir veya **yeni talimatlar** ekleyebilirsiniz. Smali kodunu [**VS Code**](https://code.visualstudio.com) kullanarak değiştiriyorum, ardından **smalise uzantısını** yükleyin ve editör size herhangi bir **talimatın yanlış olup olmadığını** söyleyecektir.\ Bazı **örnekler** burada bulunabilir: - [Smali değişiklik örnekleri](smali-changes.md) - [Google CTF 2018 - Oyun Oynayalım mı?](google-ctf-2018-shall-we-play-a-game.md) Ya da [**aşağıda bazı Smali değişikliklerinin açıklandığını kontrol edebilirsiniz**](smali-changes.md#modifying-smali). ## APK'yı yeniden derle Kodu değiştirdikten sonra kodu **yeniden derleyebilirsiniz**: ```bash apktool b . #In the folder generated when you decompiled the application ``` Yeni APK'yı _**dist**_ klasörünün **içinde** **derleyecektir**. Eğer **apktool** bir **hata** verirse, [**en son sürümü**](https://ibotpeaches.github.io/Apktool/install/) yüklemeyi deneyin. ### **Yeni APK'yı İmzala** Sonra, bir **anahtar** **oluşturmanız** gerekiyor (bir şifre ve rastgele doldurabileceğiniz bazı bilgiler istenecektir): ```bash keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias ``` Sonunda, yeni APK'yı **imzala**: ```bash jarsigner -keystore key.jks path/to/dist/* ``` ### Yeni uygulamayı optimize et **zipalign**, Android uygulama (APK) dosyalarına önemli optimizasyonlar sağlayan bir arşiv hizalama aracıdır. [More information here](https://developer.android.com/studio/command-line/zipalign). ```bash zipalign [-f] [-v] infile.apk outfile.apk zipalign -v 4 infile.apk ``` ### **Yeni APK'yı imzalayın (yine mi?)** Eğer **apksigner** kullanmayı **tercih ediyorsanız** [**apksigner**](https://developer.android.com/studio/command-line/) yerine jarsigner, **apk'yı imzalamalısınız** zipalign ile **optimizasyonu uyguladıktan sonra**. ANCAK DİKKAT EDİN, Sadece **UYGULAMAYI BİR KEZ İMZALAMALISINIZ** jarsigner ile (zipalign'dan önce) veya aspsigner ile (zipalign'dan sonra). ```bash apksigner sign --ks key.jks ./dist/mycompiled.apk ``` ## Smali'yi Değiştirme Aşağıdaki Hello World Java kodu için: ```java public static void printHelloWorld() { System.out.println("Hello World") } ``` Smali kodu şöyle olacaktır: ```java .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 talimat seti [burada](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions) mevcuttur. ### Hafif Değişiklikler ### Bir fonksiyon içindeki bir değişkenin başlangıç değerlerini değiştirin Bazı değişkenler, _const_ opcode'u kullanılarak fonksiyonun başında tanımlanır, değerlerini değiştirebilir veya yenilerini tanımlayabilirsiniz: ```bash #Number const v9, 0xf4240 const/4 v8, 0x1 #Strings const-string v5, "wins" ``` ### Temel İşlemler ```bash #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 ```bash #Log win: 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: " ``` Öneriler: - Eğer fonksiyon içinde tanımlı değişkenleri kullanacaksanız (tanımlı v0,v1,v2...) bu satırları _.local \_ ile değişkenlerin tanımları (_const v0, 0x1_) arasında koyun. - Eğer bir fonksiyonun kodunun ortasına logging kodunu eklemek istiyorsanız: - Tanımlı değişkenlerin sayısına 2 ekleyin: Örnek: _.locals 10_'dan _.locals 12_'ye. - Yeni değişkenler, zaten tanımlı değişkenlerin sonraki numaraları olmalıdır (bu örnekte _v10_ ve _v11_ olmalıdır, v0'dan başladığını unutmayın). - Logging fonksiyonunun kodunu değiştirin ve _v5_ ve _v1_ yerine _v10_ ve _v11_ kullanın. ### Toasting Fonksiyonun başında _.locals_ sayısına 3 eklemeyi unutmayın. Bu kod, **bir fonksiyonun ortasına** eklenmek üzere hazırlanmıştır (**değişkenlerin** **sayısını** gerektiği gibi **değiştirin**). **this.o**'nun **değerini** alacak, **String**'e **dönüştürecek** ve ardından **değerini** kullanarak bir **toast** yapacaktır. ```bash 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 ``` {{#include ../../banners/hacktricks-training.md}}