Задать вопрос
@IAmBogdan
Студент

Как разобрать apk приложения и затем собрать его обратно?

Хотел попробовать разобрать apk файл приложения, вырезать из его AndroidManifest все разрешения на доступ к интернету, рекламе и прочим на мой взгляд лишним сервисам и собрать обратно.

Использовал для этого apktool. Разобрал файл успешно, но затем не смог собрать, поскольку в нем очень много .xml файлов со знаками $ в названии. Похоже это считается некорректным и поэтому не собирается (в файлах .smali знаков $ не меньше, но apktool, кажется, умеет их без проблем обрабатывать, а вот .xml не умеет)

Как решить эту проблему? (надеюсь после этого новой не вылезет)
Переименовывать в ручную это невозможно. Автоматически заменить все знаки $ в названиях и самих файлах на _ - тоже глупость. Думаю есть не шуточный риск что-нибудь таким образом сломать, а мне бы хотелось универсальное решение на будущее.

Изменено:
Написал небольшой скрипт для переименования. https://github.com/1modeller1/ReplaceNames
Правда оценить работоспособность приложения после него пока не могу, поскольку вылезла целая прорва других ошибок. Как полностью разберусь - закрою вопрос.

=========================

Изменено:
В общем - разобрался. Как и подозревал сначала - проблема была вовсе не в знаках $, так что скрипт не потребовался. Инструкция следующая:

Сначала устанавливаем все нужные пакеты:

$ sudo apt install android-sdk <-- Появится файл ~/Android/Sdk/build-tools/33.0.2/aapt

В .bashrc прописываем:
export PATH=~/Android/Sdk/build-tools/33.0.2:$PATH

Проверка:
$ aapt version
Должно быть что-то вроде:
Android Asset Packaging Tool, v0.2-9420752

Устанавливаем новую версию apktool (Та, которая устанавлвиается через обычный apt, не работает)
Скачиваем с https://github.com/iBotPeaches/Apktool/releases/

=========================
Также ничего не работает без framework - папки с иконками, изображениями, цветами и т.п. Я скачал его с https://androidfilehost.com/?s=framework-res.apk&t..., хотя без VPN загрузка почему-то не пошла.
Скачанный файл по идее можно импортировать командой:
$ java -jar apktool_2.12.1.jar if framework-res.apk

Однако у меня не заработало, поэтому я распаковал framework-res.apk при помощи обычного архиватора, и теперь добавляю к концу каждой команды -p framework-res

Возможно в вашем приложении framework уже предусмотрен. Можно попробовать запустить без добавления этого аргумента или подставляя в него файлы из приложения - если вы пересобираете xapk, то это по сути zip архив с несколькими apk в нем. Один из них может оказаться фреймворком.

=========================
И теперь можем запускать:

Разбираем приложение:
$ java -jar apktool_2.12.1.jar d <INPUT.apk> -o <OUTPUT> -p framework-res


Собираем приложение:
$ java -jar apktool_2.12.1.jar b <INPUT> -o <OUTPUT.apk> -p framework-res


=========================
Перед установкой на телефон apk приложения его еще нужно не забыть подписать.
$ keytool -genkey -v -keystore mykey.keystore -alias <MY_ALIAS> -keyalg RSA -keysize 2048 -validity 10000
<-- Достаточно сделать 1 раз, но созданный файл должен лежать в той же папке, откуда вы вызываете apktool_2.12.1.jar.
$ zipalign -p -f 4 <INPUT.apk> <OUTPUT.apk> <-- начиная с android 11 чего-то требует для apk приложения и эта команда это решает
$ apksigner sign --ks mykey.keystore --ks-key-alias <MY_ALIAS> --out <OUTPUT.apk> <INPUT.apk>
<-- подписываем каждый apk файл

Смотрим, что файл успешно подписался:
$ apksigner verify -v <OUTPUT.apk>
(Может вылести куча предупреждений, но это не критично)

=========================
Для простоты сборки и разборки я вставил в .bashrc функции:
apktool () {
        if [ "$1" = "-h" ];
        then
                echo "apk <mode> <input.apk> <output.apk>"
                echo "<mode>: -d (распаковка из apk) | -b (запаковка в apk)"
                echo ""
                echo "====================================================="
                echo ""
                java -jar ~/Applications/apktool_2.12.1.jar
        else
                java -jar ~/Applications/apktool_2.12.1.jar "$1" "$2" -o "$3" -p ~/Applications/framework-res "${@:4}"
        fi
}

sign () {
        zipalign -p -f 4 "$1" "s-$1"
        apksigner sign --ks ~/mykey.keystore --ks-key-alias apkey --out "ss-$1" "s-$1" "${@:2}"
        rm "s-$1"
        mv "ss-$1" "$1"
}


=========================
P.S.
Это все работает с нормальными приложениями, а есть еще такие, которые сознательно усложняют свою пересборку. Там по видимому нужно распоковывать их как zip и потом отдельно менять те бинарники, которые нужно. Но я с этим еще не разбирался.

А, и еще - очень важно. Если приложение уже было ранее у вас установлено, то просто удалить его перед переустановкой может быть недостаточно.
Подключите телефон по adb к компьютеру
(Сначала войдите в режим разработчиков на телефоне, включите в нем отладку по USB и установку через USB)
и запустите adb install <APP.apk>. Если вылезет ошибка вроде той, что ниже - пропишите adb uninstall smellymoo.sand (Вместо smellymoo.sand подставте нужное)
adb: failed to install sandBox.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package smellymoo.sand signatures do not match newer version; ignoring!]
  • Вопрос задан
  • 911 просмотров
Подписаться 5 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Android-разработчик
    12 месяцев
    Далее
  • Яндекс Практикум
    Мидл Android‑разработчик
    5 месяцев
    Далее
  • Академия Codeby
    Курс «Анализ защищенности приложений Андроид»
    14 недель
    Далее
Пригласить эксперта
Ответы на вопрос 1
Steel_Balls
@Steel_Balls
Я в своё время пользовался старой статьёй, но она мне помогала и через пять лет.
Не знаю как сейчас. Попробуй
https://xakep.ru/2013/10/22/modify-and-packing-and...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы