LINUX.ORG.RU

Основы реверс-инжиниринга Android-приложений

 ,

Основы реверс-инжиниринга Android-приложений

5

2

Как известно, Android — это тоже Linux, основной особенностью которого является то, что он позволяет устанавливать приложения только на Java/Kotlin в формате apk, запускаемые через свою реализацию JVM — своего рода песочницу. Раз уж это Linux, то и запускать его можно через стандартные средства — LXC-контейнеры, как это делается в том же Waydroid. Главный плюс такого подхода в отличие от реального устройства — полный доступ к файловой системе, что эквивалентно рут-доступу. На реальном устройстве получить рут-права с помощью Magisk несложно, но это приводит к утрате данных вместе с ключом шифрования от sd-карты, хотя их можно и восстановить, если был бекап. Однако большей проблемой является то, что из-за этого перестают запускаться те же банковские приложения…

Установка и запуск

Установка:

# Для тех кто добавил репозитории типа arcglinuxcn и chaotic-aur
sudo pacman -S waydroid

# Можно из AUR
yay -S waydroid

Загружаем последний образ LineageOS с Google Play

sudo waydroid init -f -s GAPPS

В вики арча настройка описана сумбурно. Для waydroid не нужно устанавливать и загружать модуль binder.

Автоматический запуск контейнера, чтобы ускорить открытие приложений при старте системы:

sudo systemctl enable waydroid-container

Примеры команд:

# Останавливает текущую запущенную сессию WayDroid.
waydroid session stop

# Запускает полный графический интерфейс Android (рабочий стол).
waydroid show-full-ui

# Устанавливает APK-файл в WayDroid.
waydroid install <file>

# Запускает конкретное приложение по его пакетному имени.
waydroid launch <app>

# Удаляет приложение из WayDroid.
waydroid remove <app>

# Открывает оболочку (shell) Android внутри контейнера WayDroid с правами суперпользователя.
sudo waydroid shell

Все файлы waydroid в тч конфиги хранятся в сл каталогах:

  • /var/lib/waydroid
  • ~/.local/share/waydroid

Настройка сети и подключение к эмулятору

Заставляем работать Интернет внутри Waydroid:

# Разрешаем входящие соединения для DHCP (порт 67) и DNS (порт 53).
# DHCP нужен для получения IP-адреса Waydroid, DNS — для разрешения доменных имен.
sudo ufw allow 67
sudo ufw allow 53

# Разрешаем пересылку трафика (FORWARD) по умолчанию.
# Это критически важно, так как Waydroid работает как контейнер и его трафик должен перенаправляться через хост-систему.
sudo ufw default allow FORWARD

# Перезагружаем UFW, чтобы применить новые правила.
sudo ufw reload

Подключение через adb (пакет android-tools):

# Сначала узнаем ip контейнера
$ sudo waydroid shell ip a
...
2: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    ...
    inet 192.168.240.112/24 brd 192.168.240.255 scope global eth0
    ...

# А теперь подключимся к нему
$ adb connect 192.168.240.112:5555
connected to 192.168.240.112:5555

adb удобно использовать для установки приложений и просмотра логов.

This device isn’t Play Protect certified

Google Play из коробки отказывается работать, так как ему не нравится странная модель устройства, которую отдает эмулятор. Чтобы это исправить в официальной группе советуют выполнить команду:

sudo waydroid shell ANDROID_RUNTIME_ROOT=/apex/com.android.runtime ANDROID_DATA=/data ANDROID_TZDATA_ROOT=/apex/com.android.tzdata ANDROID_I18N_ROOT=/apex/com.android.i18n sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "select * from main where name = \"android_id\";"

И зарегистрируйте устройство, а потом перегрузите waydroid.

Проще прикинуться каким Google Pixel:

cat <<EOF | sudo tee -a /var/lib/waydroid/waydroid_base.prop
ro.product.brand=google
ro.product.device=crosshatch
ro.product.manufacturer=google
ro.product.model=Pixel 3
ro.product.name=crosshatch
ro.vendor.product.manufacturer=google
EOF

Доступ к файловой системе Android-контейнера

Файлы на карте памяти лежат тут:

~
❯ sudo ls -ahl ~/.local/share/waydroid/data/media/0
total 0
drwxrwx--- 1  1023  1023 186 Jul  2 17:25 .
drwxrwx--- 1  1023  1023   2 Jul  2 19:17 ..
drwx------ 1 10146 10146   0 Jul  2 17:25 Alarms
drwxrws--x 1  1023  1023  24 Jul  2 17:25 Android
drwx------ 1 10146 10146   0 Jul  2 17:25 Audiobooks
drwx------ 1 10146 10146   0 Jul  2 17:25 DCIM
drwx------ 1 10146 10146   0 Jul  2 17:25 Documents
drwx------ 1 10146 10146   0 Jul  2 17:25 Download
drwx------ 1 10146 10146  22 Jul  2 17:25 Movies
drwx------ 1 10146 10146  22 Jul  2 17:25 Music
drwx------ 1 10146 10146   0 Jul  2 17:25 Notifications
drwx------ 1 10146 10146  22 Jul  2 17:25 Pictures
drwx------ 1 10146 10146   0 Jul  2 17:25 Podcasts
drwx------ 1 10146 10146   0 Jul  2 17:25 Ringtone

Корень смонтирован в ro в /var/lib/waydroid/rootfs.

Перехват трафика

Даже школьники знают, что перехват трафика делается через подмену сертификата.

Для начала установим mitmproxy:

sudo pacman -S mitproxy

При первом запуске mitmproxy создаст ключи для корневого сертификата в каталоге ~/.mitmproxy:

mitmproxy

Теперь копируем корневой сертификат в /etc/system/cacerts внутри контейнера:

# Остановим сессию
sudo waydroid session stop

# Увеличим размер системного контейнера, чтобы можно было в него добавиь файлы
sudo truncate -s +100M /var/lib/waydroid/images/system.img
sudo e2fsck -f /var/lib/waydroid/images/system.img
sudo resize2fs /var/lib/waydroid/images/system.img

# Смонтируем образ в /mnt
sudo mount -o loop,rw /var/lib/waydroid/images/system.img /mnt

# Корневой сертификат должен иметь в качестве имени хеш от старого поля subject, который имеет суффикс `.0`.
cert_name="$(openssl x509 -inform PEM -subject_hash_old -in ~/.mitmproxy/mitmproxy-ca-cert.cer | head -1).0"

# Копируем сертификат mitmproxy.
sudo cp ~/.mitmproxy/mitmproxy-ca-cert.cer /mnt/system/etc/security/cacerts/$cert_name

# Устанавливаем права доступа.
sudo chmod 644 /mnt/system/etc/security/cacerts/$cert_name
  • На идею выше меня навел этот комментарий к gist. В арче какие-то свои настройки, потому как никакого overlayfs не работает?
  • Про сертификаты можно почитать тут.

Вышеописанным способом можно пропатчить и образ, который скачивает Android Studio… лишь бы было желание.

Вариант по-проще:

# Устанавливаем прокси
adb shell settings put global http_proxy "<host_ip>:8080"

# Сбрасываем прокси
adb shell settings delete global http_proxy
# или так
adb shell settings put global http_proxy :0

Можно создать правила iptables для перенаправления всего трафика по умолчанию (вариант лучше):

sudo iptables -t nat -A PREROUTING -i waydroid0 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i waydroid0 -p tcp --dport 443 -j REDIRECT --to-port 8080

Так же для этого варианта нужно включить ip forwarding. Это можно сделать разными способами, например:

sudo sysctl -w net.ipv4.ip_forward=1

# Делаем постоянным
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-waydroid-forwarding.conf

# Перечитываем все конфиги
sudo sysctl --system

Запустим прокси:

mitmweb

Вместо mitmproxy, у которого есть API для написания скриптов на Python, можно использовать Burp Suite для автоматического сканирования на уязвимости… Да что угодно и зачем угодно…

Внедрение кода

Для начала нам потребуется скачать приложение в виде apk. Для этого есть множество способов и специальных сервисов типа этого, не говоря о том, что у вас полный доступ к файловой системе эмулятора.

Установим apktool:

sudo pacman -S android-apktool

Декомпиляция приложения:

apktool d com.govno.app.apk /path/to/decompiled
cd /path/to/decompiled

В данном каталоге у нас будет куча файлов с расширением .smali. Я уже выше писал, что у Android своя реализация JVM под названием Dalvik. Smali — это ее байт-код, атомарные операции, выполняемые виртуальной машиной, в понятном для человека виде. Каждый smali-файл соответствует классу Java/Kotlin и легко поддается редактированию. Вы можете поиском через grep/rg/fzf найти нужные вам строки, а затем отредактировать файл.

Например есть какой-то метод, в котором есть интересующее нас значение:

.method public final b()Ljava/lang/String;
    .locals 1

    # ...
    
    # Вот тут оно присваивается в регистр 0
    move-result-object v0

    # ...
    
    # А затем возвращается
    return-object v0
.end method

Этот код можно изменить так:

.method public final b()Ljava/lang/String;
    # Для логера нужно минимум три регистра
    .locals 3

    # ...

    # В регистре 0 лежит интересующее нас значение
    move-result-object v0

    # Тут вызывается Log.d("TEST_DEBUG", "$0")
    const-string v1, "TEST_DEBUG"
    invoke-static {v0}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
    move-result-object v2
    invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    return-object v0
.end method

Перейдем в каталог с декомпилированным приложением и соберем его:

apktool b -f -o ../modified.apk
cd ..

Теперь нужно подписать приложение:

# Сгенерируем ключ для подписи
keytool -genkeypair -v \
  -keystore debug.keystore \
  -alias androiddebugkey \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -storepass android \
  -keypass android \
  -dname "CN=Android Debug, OU=Unknown, O=Android, L=Unknown, ST=Unknown, C=US"

# Нужно выровнять архив (jar)
zipalign -v 4 modified.apk aligned.apk

# А теперь все нужно подписать
apksigner sign \
  --ks debug.keystore \
  --ks-pass pass:android \
  --key-pass pass:android \
  --v1-signing-enabled true \
  --v2-signing-enabled true \
  --v3-signing-enabled true \
  --min-sdk-version 21 \
  aligned.apk

А потом нужно установить aligned.apk и запустить…

И далее через adb смотрим интересующее нас значение:

$ adb logcat -s "TEST_DEBUG"
★★★

Проверено: hobbit ()
Последнее исправление: rtxtxtrx (всего исправлений: 7)

Спасибо за статью! Может пригодится.
Но вот вопос waydroid только под вяленым работает или это просто название?

получить рут-права с помощью Magisk несложно

увы но нет, очень зависит от устройства

Kolins ★★★★★
()
Последнее исправление: Kolins (всего исправлений: 2)

...Android — это тоже Linux...

Дальше не читал.

sparkie ★★★★★
()

В вики арча настройка описана сумбурно. Для waydroid не нужно устанавливать и загружать модуль binder.

См. мой комментприй тут Наоборот сматфон на линуксе (комментарий)

Я сейчас повторно проверил ссылки: от anbox-modules зависит waydroid из другого оверлея (https://gpo.zugaina.org/Overlays/parona-overlay/app-containers/waydroid).
Но есть зависимость на конфиг ядра:

ERROR_ANDROID_BINDERFS="CONFIG_ANDROID_BINDERFS: need for creating Android-specific binder IPC channels"
ERROR_ANDROID_BINDER_IPC="CONFIG_ANDROID_BINDER_IPC: need for creating Android-specific binder IPC channels"
ERROR_MEMFD_CREATE="CONFIG_MEMFD_CREATE: it completely replaced deprecated ISHMEM drivers,
	therefore it's vital for android-specific memory management"

В принципе доп. модули ядра это не проблема.
Но мне не нравится наличие внешних по отношению к LXC-контейнеру сервисов:

Anbox Container Manager

Anbox Session Manager is basically the Anbox core. It runs LXC containerized Android OS and sits above LXC featured Linux system (userspace + kernel). It handles core Android OS functions, container-specific network connections, device handling and other system level interaction.
Anbox Session Manager

Anbox Session Manager sits between Android applications and the container manager. It handles Android application user-level connections and services and basically makes it possible to run GUI-driven Android applications on a Linux desktop.
(источник указан с моем комментарии от 26.01.25)

Как я понимаю, waydroid наследует эту же архитеутуру от Anbox.

MirandaUser2
()

он позволяет устанавливать приложения только на Java/Kotlin в формате apk

Правда что ли?????

КСЖ

James_Holden ★★★★★
()

Спасибо за статью @rtxtxtxt

  • А будет или подскажите пример с примером патчинга чего-то готового типа как в crackme?
  • А будет ли про Ghidra ?
pinachet ★★★★★
()
Ответ на: комментарий от MirandaUser2

waydroid - это просто скрипт на питоне, который запускает сторонние утилиты (кто бы мог подумать…)

он использует gbinder для работы с libgbinder…

❯ pacman -Qs binder
local/libgbinder 1.1.42-1
    GLib-style interface to binder
local/python-gbinder 1.1.2-5
    Python bindings for libgbinder

модуль ядра сейчас не нужен

rtxtxtrx ★★★
() автор топика
Ответ на: комментарий от rtxtxtrx

waydroid - это просто скрипт на питоне, который запускает сторонние утилиты (кто бы мог подумать…)

Но тогда было бы неплохо обойтись вообще без него. Если есть образ для контейнера, то зачем ещё что-то нужно для его запуска.

MirandaUser2
()
Ответ на: комментарий от rtxtxtrx

Гм, а вот это уже проблема.
Есть какие-то не сильно трудоемкие способы это обойти? (с Wayland никогда не имел дело, да и не особо хочу)

MirandaUser2
()
Ответ на: комментарий от Kolins

Декомпиляция приложения:

В данном каталоге у нас будет куча файлов с расширением .smali. … Smali — это ее байт-код, атомарные операции, выполняемые виртуальной машиной, в полнятном для человека виде.

Это не декомпиляция тогда, это дизассемблирование.

Что, неужто ведроидолюбители не осилили сваять какой-нибудь аналог hexrays или хотя бы r2dec для жабы?

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 1)

Годная статья. Без воды, доходчиво. Уважаю

MrClon ★★★★★
()
Ответ на: комментарий от rtxtxtrx

А при чём тут кряки, иногда надо региональные ограничения пропатчить. У нас тут как-бы новые регионы и некоторые нехорошие люди не дают там софту работать, да и тут в старых палки в колёса вставляют.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от rtxtxtrx

в чем проблема? и че с ним иметь? он просто работает

это не очевидно для тех, кто им никогда не пользовался и не настраивал.

Но я уже нашел в интернетах рецепты: Waydroid Installation and Usage Guide for X11

Согласно рецепту достаточно установить Weston (the required Wayland compositor).
Да и на на его веб-сайте пишут:

A Wayland compositor could be <...> a nested compositor that itself is an X11 or Wayland application (client).
MirandaUser2
()
Ответ на: комментарий от peregrine

это проблема несколько сложней даже в рамках «старых регионов». Геолокация - это не так просто, тем более что половина мракоплейсов требует ее так или иначе и никак не объясняет последствия. У меня лично геолокация везде на дне реки. Мне так спокойней…

Slackware_user ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.