Smali - Decompiling/[Modifying]/Compiling
Reading time: 8 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Іноді буває корисно змінити код додатку, щоб отримати приховану інформацію для себе (можливо добре обфусковані паролі або flags). Тоді може бути цікаво decompile the apk, modify the code і recompile його.
Opcodes reference: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
Швидкий спосіб
Використовуючи Visual Studio Code та розширення APKLab, ви можете автоматично decompile, modify, recompile, sign & install додаток без виконання жодної команди.
Ще один скрипт, який значно полегшує це завдання — https://github.com/ax/apk.sh
Decompile the APK
Використовуючи APKTool, ви можете отримати доступ до smali code and resources:
apktool d APP.apk
If apktool дає будь‑яку помилку, спробуйте встановити останній версії
Деякі цікаві файли, які варто переглянути,:
- res/values/strings.xml (and all xmls inside res/values/*)
- AndroidManifest.xml
- Any file with extension .sqlite or .db
Якщо apktool
має проблеми з декодуванням додатка, перегляньте https://ibotpeaches.github.io/Apktool/documentation/#framework-files або спробуйте використати аргумент -r
(Do not decode resources). Тоді, якщо проблема була в ресурсі, а не в коді, ви уникаєте цієї проблеми (також ви не декомпілюєте ресурси).
Змінити smali код
Ви можете змінювати instructions, змінювати value деяких змінних або додавати нові інструкції. Я змінюю Smali код за допомогою VS Code, потім встановіть розширення smalise, і редактор скаже вам, якщо якась instruction некоректна.
Деякі приклади можна знайти тут:
Або можна check below some Smali changes explained.
Перекомпілювати APK
Після внесення змін у код ви можете перекомпілювати код, використовуючи:
apktool b . #In the folder generated when you decompiled the application
Він скомпілює новий APK всередині папки dist.
Якщо apktool викидає помилку, спробуйте installing the latest version
Підпишіть новий APK
Потім потрібно згенерувати ключ (вам буде запропоновано ввести пароль та деяку інформацію, яку можна заповнити випадковими даними):
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
Нарешті, підпишіть новий APK:
jarsigner -keystore key.jks path/to/dist/* <your-alias>
Оптимізувати новий додаток
zipalign — це інструмент вирівнювання архівів, який забезпечує важливу оптимізацію файлів Android-додатків (APK). More information here.
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
Підпишіть новий APK (знову?)
Якщо ви вважаєте за краще використовувати apksigner замість jarsigner, ви повинні підписати apk після застосування оптимізації за допомогою zipaling. Але зауважте, що вам потрібно підписати додаток лише один раз за допомогою jarsigner (до zipalign) або за допомогою aspsigner (після zipaling).
apksigner sign --ks key.jks ./dist/mycompiled.apk
Модифікація Smali
Для наступного коду Hello World на Java:
public static void printHelloWorld() {
System.out.println("Hello World")
}
Код Smali буде:
.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 доступний here.
Незначні зміни
Змінити початкові значення змінної всередині функції
Деякі змінні визначені на початку функції за допомогою опкоду const; ви можете змінити їхні значення або додати нові:
#Number
const v9, 0xf4240
const/4 v8, 0x1
#Strings
const-string v5, "wins"
Основні операції
#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
Великі зміни
Логування
#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:
- Якщо ви збираєтесь використовувати оголошені змінні всередині функції (declared v0,v1,v2...) помістіть ці рядки між .local
і деклараціями змінних (const v0, 0x1) - Якщо ви хочете вставити код логування посеред коду функції:
- Додайте 2 до кількості оголошених змінних: Ex: from .locals 10 to .locals 12
- Нові змінні повинні бути наступними номерами після вже оголошених змінних (в цьому прикладі це повинні бути v10 та v11, remember that it starts in v0).
- Змініть код функції логування та використовуйте v10 і v11 замість v5 і v1.
Відображення Toast
Пам'ятайте додати 3 до числа .locals на початку функції.
This code is prepared to be inserted in the середину функції (змініть число змінних за потреби). It will take the значення this.o, перетворить його на String and them зробить a toast with its value.
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
Loading a Native Library at Startup (System.loadLibrary)
Іноді потрібно попередньо завантажити нативну бібліотеку, щоб вона ініціалізувалася перед іншими JNI libs (наприклад, щоб увімкнути локальну для процесу телеметрію/логування). Ви можете інжектувати виклик System.loadLibrary() у статичний ініціалізатор або на ранньому етапі Application.onCreate(). Приклад smali для статичного ініціалізатора класу (
.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
Або розмістіть ті самі дві інструкції на початку вашого Application.onCreate(), щоб гарантувати, що бібліотека завантажується якомога раніше:
.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
Примітки:
- Переконайтеся, що правильний варіант ABI бібліотеки існує в lib/
/ (наприклад, arm64-v8a/armeabi-v7a), щоб уникнути UnsatisfiedLinkError. - Завантаження дуже рано (class static initializer) гарантує, що native logger може спостерігати подальшу активність JNI.
Посилання
- SoTap: Легкий in-app JNI (.so) behavior logger – github.com/RezaArbabBot/SoTap
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.