Smali - Декомпіляція/[Модифікація]/Компіліяція

Reading time: 6 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Іноді цікаво модифікувати код програми, щоб отримати доступ до прихованої інформації (можливо, добре обфусцировані паролі або прапори). Тоді може бути цікаво декомпілювати apk, модифікувати код і знову скомпілювати його.

Справочний посібник з опкодів: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

Швидкий спосіб

Використовуючи Visual Studio Code та розширення APKLab, ви можете автоматично декомпілювати, модифікувати, скомпілювати, підписати та встановити програму без виконання будь-якої команди.

Ще один скрипт, який значно полегшує це завдання, - https://github.com/ax/apk.sh

Декомпіляція APK

Використовуючи APKTool, ви можете отримати доступ до smali коду та ресурсів:

bash
apktool d APP.apk

Якщо apktool видає будь-яку помилку, спробуйте встановити остання версія

Деякі цікаві файли, на які варто звернути увагу:

  • res/values/strings.xml (та всі xml всередині res/values/*)
  • AndroidManifest.xml
  • Будь-який файл з розширенням .sqlite або .db

Якщо apktool має проблеми з декодуванням програми, ознайомтеся з https://ibotpeaches.github.io/Apktool/documentation/#framework-files або спробуйте використати аргумент -r (Не декодувати ресурси). Тоді, якщо проблема була в ресурсі, а не в вихідному коді, ви не матимете проблеми (також не буде декомпільовано ресурси).

Зміна коду smali

Ви можете змінювати інструкції, змінювати значення деяких змінних або додавати нові інструкції. Я змінюю код Smali, використовуючи VS Code, ви потім встановлюєте розширення smalise, і редактор скаже вам, якщо будь-яка інструкція є некоректною.
Деякі приклади можна знайти тут:

Або ви можете перевірити нижче деякі пояснені зміни Smali.

Перекомпіляція APK

Після зміни коду ви можете перекомпілювати код, використовуючи:

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

Це скомпілює новий APK всередині папки dist.

Якщо apktool видає помилку, спробуйте встановити остання версія

Підпишіть новий APK

Потім вам потрібно згенерувати ключ (вас попросять ввести пароль та деяку інформацію, яку ви можете заповнити випадковим чином):

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

Нарешті, підпишіть новий APK:

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

Оптимізувати новий додаток

zipalign - це інструмент вирівнювання архівів, який забезпечує важливу оптимізацію для файлів Android додатків (APK). More information here.

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

Підпишіть новий APK (знову?)

Якщо ви надаєте перевагу використовувати apksigner замість jarsigner, вам слід підписати apk після застосування оптимізації з zipalign. АЛЕ ЗВЕРНІТЬ УВАГУ, ЩО ВИ МАЄТЕ ПІДПИСАТИ ЗАСТОСУВАННЯ ОДИН РАЗ З jarsigner (перед zipalign) АБО З aspsigner (після zipalign).

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

Зміна Smali

Для наступного коду Hello World на Java:

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

Код Smali буде:

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 доступний here.

Легкі зміни

Змінити початкові значення змінної всередині функції

Деякі змінні визначені на початку функції за допомогою опкоду const, ви можете змінити їх значення або визначити нові:

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

Основні операції

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

Більші зміни

Логування

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

Рекомендації:

  • Якщо ви збираєтеся використовувати оголошені змінні всередині функції (оголошені v0,v1,v2...) помістіть ці рядки між .local <number> та оголошеннями змінних (const v0, 0x1)
  • Якщо ви хочете вставити код логування в середині коду функції:
  • Додайте 2 до кількості оголошених змінних: Наприклад: з .locals 10 до .locals 12
  • Нові змінні повинні бути наступними номерами вже оголошених змінних (в цьому прикладі повинні бути v10 та v11, пам'ятайте, що починається з v0).
  • Змініть код функції логування і використовуйте v10 та v11 замість v5 та v1.

Toasting

Не забудьте додати 3 до кількості .locals на початку функції.

Цей код підготовлений для вставки в середину функції (змініть номер змінних за необхідності). Він візьме значення this.o, перетворить його в String і потім зробить toast з його значенням.

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

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks