← На главную

Как создать резервную копию Android-приложения

Любое приложение для Android можно скопировать себе на компьютер. Это удобно для создания резервных копий особо ценных приложений. А то вдруг разработчик по какой-то причине решит удалить свое творение из Play Store. Также это позволяет изучить внутреннее устройство закрытого приложения, или даже модифицировать его.

Поскольку на ноутбуке у меня Linux, то описанные шаги будут для этой системы. Вероятно, для Windows и MacOS шаги будут похожи. Но так ли это на самом деле, я не проверял.

Понадобятся следующие пакеты:

$ sudo apt install adb apksigner

Они тянут за собой довольно тяжелую JRE. Однако постоянно держать в системе названные пакеты не требуется. Можно установить, воспользоваться, и сразу удалить.

Утилита ADB, Android Debug Bridge, предназначена для управления Android-устройством с компьютера. Она позволяет устанавливать приложения, копировать файлы, отлаживать код и т.п. Чтобы это работало, устройство необходимо перевести в режим разработчика.

Для этого заходим в Settings → About phone. Проматываем в самый низ и 7 раз нажимаем на Build Number. Должно появиться сообщение об активации режима разработчика. Возвращаемся на предыдущий экран. Идем в System → Advanced → Developer options → Debugging. Ставим галочку напротив USB debugging.

Подключаем смартфон / планшет к компьютеру по USB. Определяем полное имя интересующего нас приложения. Для этого в консоли говорим:

$ adb shell pm list packages | grep -i superproga package:me.eax.superproga

Определяем соответствующие ему apk-файлы:

$ adb shell pm path me.eax.superproga package:/data/app/(...много букв...)/base.apk package:/data/app/(...много букв...)/split_config.arm64_v8a.apk package:/data/app/(...много букв...)/split_config.en.apk package:/data/app/(...много букв...)/split_config.ru.apk package:/data/app/(...много букв...)/split_config.xxhdpi.apk

В данном случае приложение разбито на несколько файлов. Копируем их на ноутбук:

$ adb pull /data/app/(...много букв...)/base.apk . $ adb pull /data/app/(...много букв...)/split_config.arm64_v8a.apk . $ adb pull /data/app/(...много букв...)/split_config.en.apk . $ adb pull /data/app/(...много букв...)/split_config.ru.apk . $ adb pull /data/app/(...много букв...)/split_config.xxhdpi.apk .

Удаляем приложение. Затем проверяем, что оно устанавливается из бэкапа:

$ adb install-multiple base.apk split_config.arm64_v8a.apk ⏎ split_config.en.apk split_config.ru.apk split_config.xxhdpi.apk

Для удобства склеим полученные файлы в один монолитный apk:

$ mkdir me.eax.superproga $ mv *.apk me.eax.superproga $ java -jar APKEditor.jar m -i ./me.eax.superproga -o superproga.apk

Здесь использована программа APKEditor. Помимо нее существует схожая по функционалу apktool. Однако apktool не работает со split-пакетами, а также имеет другие недостатки.

Склеенному пакету требуется новая цифровая подпись. Android не против самоподписанных сертификатов. Только при установке система предупредит, что перед вами приложение от неизвестного разработчика.

Создаем приватный ключ и самоподписанный сертификат со сроком годности 10 000 дней:

$ openssl genrsa -out eaxme_key.pem 2048 $ openssl req -new -key eaxme_key.pem -out eaxme_csr.csr $ openssl x509 -req -days 10000 -in eaxme_csr.csr -signkey eaxme_key.pem ⏎ -out eaxme_cert.x509.pem

Конвертируем ключ в формат PKCS#8, который понятен Android'у:

$ openssl pkcs8 -topk8 -outform DER -in eaxme_key.pem -inform PEM ⏎ -out eaxme_key.pk8 -nocrypt

Подписываем пакет:

$ apksigner sign --key eaxme_key.pk8 --cert eaxme_cert.x509.pem superproga.apk

Удаляем приложение на смарфтоне и говорим:

$ adb install superproga.apk

Теперь у нас есть резервная копия приложения в виде монолитного apk. Кстати, для его установки не обязательно использовать ADB. Можно перекинуть apk при помощи условного Google Drive, и просто открыть файл на Android-устройстве.

Обратите внимание, что при установке приложения из Play Store устройство получает сплиты под конкретные модель процессора, DPI и язык системы. Чтобы собрать все сплиты и получить самый переносимый apk, необходимо больше одного устройства.

А что, если приложение еще доступно в Play Store, но мы не хотим обновляться? Ведь иногда после обновления софт начинает работать хуже. Пусть такое и случается не всегда, но бывает.

Модифицируем приложение соответствующим образом. Для этого его нужно распаковать:

java -jar APKEditor.jar d -i superproga.apk -o superproga

Помимо прочего, в каталоге superproga будет создано множество файлов с расширением .smali. Это текстовые файлы с ассемблерным листингом соответствующих классов. С ними можно работать в вашем любимом текстовом редакторе и при желании вносить изменения.

Однако сейчас нас интересует superproga/AndroidManifest.xml:

<?xml version='1.0' encoding='utf-8' ?> <manifest android:versionCode="123" android:versionName="1.2.3" android:compileSdkVersion="36" android:compileSdkVersionCodename="16" package="me.eax.superproga" platformBuildVersionCode="36" (... пропущено ...)

Здесь versionName – это версия приложения, показываемая пользователю, а versionCode – внутренний номер версии для Play Store. Чтобы приложение перестало обновляться, нужно указать большое значение versionCode:

<?xml version='1.0' encoding='utf-8' ?> <manifest android:versionCode="999999" android:versionName="1.2.3-backup" android:compileSdkVersion="36" android:compileSdkVersionCodename="16" package="me.eax.superproga" platformBuildVersionCode="36" (... пропущено ...)

Запаковываем и снова подписываем:

$ mv superproga.apk /tmp $ java -jar APKEditor.jar b -i superproga -o superproga.apk $ apksigner sign --key eaxme_key.pk8 --cert eaxme_cert.x509.pem superproga.apk

Еще раз переустанавливаем. Приложение должно работать как раньше, но теперь иметь версию 1.2.3-backup. Если что-нибудь сломалось (не должно, но мало ли), то смотрим логи:

$ adb logcat *:E | grep -i me.eax.superproga

Для более глубокого изучения JVM-кода существует декомпилятор JADX, а для файлов .so – уже знакомые нам Radare2 и Cutter.

Примечательно, что на самом деле apk-файлы представляют собой zip-архивы. Однако эти архивы имют ряд особенностей. Например, файлы .so хранятся несжатыми и выровненными по размеру страницы, а AndroidManifest.xml имеет бинарный формат. Поэтому для работы с .apk следует использовать специальные утилиты.