- Регистрация
- 23 Янв 2019
- Сообщения
- 1,351
- Баллы
- 0
- Общие продажи
- 0$
- Общие покупки
- 0$
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сегодня мы разберем несколько приложений, чтобы потренироваться в реверс-инжиниринге и узнать о подлинных возможностях твоего смартфона. Какое приложение мы будем препарировать?
Я выбрал для своих целей VK Admin — программу для управления сообществами «ВКонтакте» со смартфона. В нем не предусмотрена темная тема, поэтому мы с тобой попробуем эту тему добавить.
Собираем и разбираем
Сначала извлечем все ресурсы приложения, используя утилиту apktool — она распаковывает и запаковывает файлы пакетов APK, которые хранятся в сжатом, бинарном виде, и дизассемблирует программный код, заключенный в них.Чтобы получить установочный пакет, можно воспользоваться Android Debugging Bridge — системой для отладки программ на устройстве. В *nix-подобных системах ADB ставится стандартно, с помощью пакетного менеджера, а в Windows — идет в составе Android Studio или Android SDK Platform Tools.В первую очередь установим приложение из Google Play Store на смартфон, подключим его к компьютеру с помощью USB, затем воспользуемся ADB для переноса пакета приложения на компьютер и извлечем его содержимое.
Для создания подписи в первый раз нужно воспользоваться утилитой keytool (входит в ):
Меняем цветовые схемы
Цвета в приложении можно настроить несколькими способами:
colors.xml
Цветовая палитра приложения содержится в файле com.vk.admin/res/values/colors.xml. Структура файла выглядит так:
Каждый цвет, который в дальнейшем используется в статичных экранах приложения, записан здесь. Наша задача — изменить цвета, самый простой способ это сделать — инвертировать. Для записи цвета в формате hex можно отнять из 255 каждый компонент: R, Gи B, то есть 255 - R, 255 - G, 255 - B. Параметры @android:color/white и @android:color/black можно изменить вручную.
styles.xml
В файле com.vk.admin/res/values/styles.xml заданы цвета, но только некоторые. Этот файл используется самими разработчиками, когда они хотят сделать несколько цветовых схем приложения. Если же этих схем нет, работать приходится нам с тобой.
Некоторые цвета текста и фона заданы именно здесь, поэтому их нужно изменить аналогично с colors.xml.
Layout
В папке com.vk.admin/res/ находятся описания экранов приложения.
Но закончить мы пока не можем — есть некоторые экраны, цвет фона и текста которых задан не в файлах .xml, а прямо в исполняемом коде приложения. Туда нам и дорога.
Smali
Внутри приложений на Android используется собственный формат файлов — .dex, или , и собственная виртуальная машина, чтобы эти файлы исполнять, — .
Как и с любым компилируемым языком, для .dex есть байт-код — smali — человекочитаемый и понятный с первого взгляда.
Машина Dalvik, в отличие от , — регистровая, а не стековая. Регистры не имеют типов и могут хранить всё: числа, строки, экземпляры классов. При этом язык smali строго типизирован.
Вот небольшая последовательность инструкций, чтобы вывести содержимое регистра v0 в лог.
Интуитивно понятный интерфейс Jadx
Использовать Jadx просто — нужно лишь выбрать файл и открыть его, код будет автоматически декомпилирован и показан.
setBackgroundColor
Для некоторых экранов приложения используется параметр setBackgroundColor(I)V, который устанавливает цвет фона. Часто это не статичные экраны, а динамические: с поддержкой скролла, различные списки и карточки.
invoke-virtual {v1, v0}, Landroid/webkit/WebView;->setBackgroundColor(I)V
Эта строка занимается изменением. Чтобы изменить цвет, нужно его записать в регистр, а затем передать в функцию вместо настоящего.
const v12, -0x1000000
#### Эквивалент 0xFF000000 — черного
invoke-virtual {v1, v12}, Landroid/webkit/WebView;->setBackgroundColor(I)V
Теперь пройдись по всем файлам и замени цвет.
Бывают случаи на порядок проще.
const v2, -0x1
#### Здесь -0x1 == 0xFFFFFFFF — белый цвет
invoke-virtual {v1, v2}, Landroid/support/v7/widget/CardView;->setBackgroundColor(I)V
Нужно просто изменить -0x1 на -0x1000000, и приложение погрузится во тьму.
Стоит быть внимательным и пытаться разобраться в коде: иногда оптимизатор кода будет перемещать инструкции const вверх, и ты можешь их не заметить.
setTextColor
Иногда текст, который меняется в ходе работы с приложением, может менять свой цвет. За это отвечает параметр setTextColor(I)V, второй аргумент которого можно подменить на нужный, в нашем случае — белый.
#### Меняем цвет
const p1, -0x1
#### на белый
invoke-virtual {v0, p1}, Landroid/widget/TextView;->setTextColor(I)V
На этом борьбу со светлым фоном и ярким экраном можно закончить. Большинство элементов экрана поменяли свой цвет на противоположный. Так ты можешь изменить любое приложение, особенно если ты любишь потыкать в телефон поздно ночью.
Результат изменений
Меняем функциональность приложения
Чтобы ощутить всю мощь smali, давай попробуем изменить какую-то часть приложения. Например, обойдем проверку на внутренние покупки.
Возьмем другое приложение — . Оно показывает положение МКС над Землей. В нем можно купить расширения: показ комет, планет, Луны, телескопа «Хаббл».
При копировании приложения на компьютер может возникнуть проблема: в составе приложения не один и не два, а целых три файла apk!
$ adb shell pm path com.runar.issdetector
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/base.apk
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/split_config.en.apk
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/split_config.xxhdpi.apk
Копируем все. При переустановке приложения файлы split_config.en.apk и split_config.xxhdpi.apk потеряются, а без них приложение будет вылетать. Поэтому их нужно будет переподписать: зайти в них как в архивы ZIP, удалить папку META_INF и прогнать через стандартную процедуру утилиты jarsigner. Основной же файл мы будем препарировать с помощью apktool.
Покупками в приложении занимается интерфейс IInAppBillingService. Для него прописана обертка com.runar.issdetector.util: IabHelper, IabResult, Purchase, Security, Inventory.
В этом приложении можно не идти напролом, обманывая сервис покупок. Проще заставить приложение думать, что все уже куплено. В этом нам поможет Inventory.smali.
В особо сложных случаях такой трюк провернуть не удается, и тогда приходится подменять данные, заставляя сервис ложно сообщать о совершенных покупках. Подробнее об этом можно почитать в материале компании Securing Apps ().
Открыв файл, ты увидишь поле mPurchaseMap, которое содержит в себе все покупки: номер товара, сопоставленный с покупкой, которую совершил пользователь.
.field mPurchaseMap:Ljava/util/Map;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/Map<",
"Ljava/lang/String;",
"Lcom/runar/issdetector/util/Purchase;",
">;"
}
.end annotation
.end field
Далее в коде мы видим строку hasPurchase(String sku) -> boolean, которая проверяет, совершал ли пользователь покупку. Для этого делается проверка на существование ключа sku в mPurchaseMap.
.method public hasPurchase(Ljava/lang/StringZ
.locals 1
.line 45
iget-object v0, p0, Lcom/runar/issdetector/util/Inventory;->mPurchaseMap:Ljava/util/Map;
invoke-interface {v0, p1}, Ljava/util/Map;->containsKey(Ljava/lang/ObjectZ
move-result p1
return p1
.end method
А что будет, если в любом случае отдавать true?
.method public hasPurchase(Ljava/lang/StringZ
.locals 1
const p1, 0x1
return p1
.end method
Собираем приложение и устанавливаем его.
$ adb install-multiplie com.runar.issdetector.apk split_config.xxhdpi.apk split_config.en.apk
Success
Результат изменения кода
С этого можно начать свой путь в реверс-инжиниринг. Я рассказал тебе основы, с которых начинал сам. Небольшие изменения могут улучшить твою жизнь — надеюсь, я смог тебе это показать.
Я выбрал для своих целей VK Admin — программу для управления сообществами «ВКонтакте» со смартфона. В нем не предусмотрена темная тема, поэтому мы с тобой попробуем эту тему добавить.
Собираем и разбираем
Сначала извлечем все ресурсы приложения, используя утилиту apktool — она распаковывает и запаковывает файлы пакетов APK, которые хранятся в сжатом, бинарном виде, и дизассемблирует программный код, заключенный в них.Чтобы получить установочный пакет, можно воспользоваться Android Debugging Bridge — системой для отладки программ на устройстве. В *nix-подобных системах ADB ставится стандартно, с помощью пакетного менеджера, а в Windows — идет в составе Android Studio или Android SDK Platform Tools.В первую очередь установим приложение из Google Play Store на смартфон, подключим его к компьютеру с помощью USB, затем воспользуемся ADB для переноса пакета приложения на компьютер и извлечем его содержимое.
Для создания подписи в первый раз нужно воспользоваться утилитой keytool (входит в ):
Меняем цветовые схемы
Цвета в приложении можно настроить несколькими способами:
- использовать встроенные цвета, к примеру @android:color/white;
- создать палитру собственных цветов в файле colors.xml, которые затем используются в виде @color/text_primary;
- задать цвет шестнадцатеричным кодом, главное — не забывай, что цвета в приложении записаны в формате #AARRGGBB — прозрачность на первом месте;
- воспользоваться параметрами setTextColor,setBackgroundColor внутри кода Java или Kotlin.
colors.xml
Цветовая палитра приложения содержится в файле com.vk.admin/res/values/colors.xml. Структура файла выглядит так:
Каждый цвет, который в дальнейшем используется в статичных экранах приложения, записан здесь. Наша задача — изменить цвета, самый простой способ это сделать — инвертировать. Для записи цвета в формате hex можно отнять из 255 каждый компонент: R, Gи B, то есть 255 - R, 255 - G, 255 - B. Параметры @android:color/white и @android:color/black можно изменить вручную.
styles.xml
В файле com.vk.admin/res/values/styles.xml заданы цвета, но только некоторые. Этот файл используется самими разработчиками, когда они хотят сделать несколько цветовых схем приложения. Если же этих схем нет, работать приходится нам с тобой.
Некоторые цвета текста и фона заданы именно здесь, поэтому их нужно изменить аналогично с colors.xml.
Layout
В папке com.vk.admin/res/ находятся описания экранов приложения.
- com.vk.admin/res/layout/ — универсальное хранилище экранов для всех смартфонов. Если нет каких-то специальных указаний, то будут использованы эти ресурсы;
- com.vk.admin/res/layout-v``XX (где XX — версия SDK смартфона, зависит от версии Android на устройстве) используются для работы с самыми передовыми элементами UI;
- остальные com.vk.admin/res/layout-... задают специфичные экраны приложения для ориентации устройства, разрешения и так далее.
Но закончить мы пока не можем — есть некоторые экраны, цвет фона и текста которых задан не в файлах .xml, а прямо в исполняемом коде приложения. Туда нам и дорога.
Smali
Внутри приложений на Android используется собственный формат файлов — .dex, или , и собственная виртуальная машина, чтобы эти файлы исполнять, — .
Как и с любым компилируемым языком, для .dex есть байт-код — smali — человекочитаемый и понятный с первого взгляда.
Машина Dalvik, в отличие от , — регистровая, а не стековая. Регистры не имеют типов и могут хранить всё: числа, строки, экземпляры классов. При этом язык smali строго типизирован.
Вот небольшая последовательность инструкций, чтобы вывести содержимое регистра v0 в лог.
- const-string v1, "MyTag" — записать в регистр v1 строку "MyTag".
- invoke-static {v0}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; — вызвать функцию String.valueOf(v0). Здесь static означает, что функция встроена в виртуальную машину; {v0} — список аргументов; L показывает, что сразу за ним идет название объекта, класса и так далее; java, lang, String; — тип строки; I — тип числа, Integer; а все вместе (->valueOf(I)Ljava/lang/String говорит нам о том, что вызывается функция valueOf от одного аргумента и возвращает она строку.
- move-result-object v2 — записать результат предыдущей операции в v2.
- invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/StringI — залогировать содержимое v2 под тегом из v1.
Интуитивно понятный интерфейс Jadx
Использовать Jadx просто — нужно лишь выбрать файл и открыть его, код будет автоматически декомпилирован и показан.
setBackgroundColor
Для некоторых экранов приложения используется параметр setBackgroundColor(I)V, который устанавливает цвет фона. Часто это не статичные экраны, а динамические: с поддержкой скролла, различные списки и карточки.
invoke-virtual {v1, v0}, Landroid/webkit/WebView;->setBackgroundColor(I)V
Эта строка занимается изменением. Чтобы изменить цвет, нужно его записать в регистр, а затем передать в функцию вместо настоящего.
const v12, -0x1000000
#### Эквивалент 0xFF000000 — черного
invoke-virtual {v1, v12}, Landroid/webkit/WebView;->setBackgroundColor(I)V
Теперь пройдись по всем файлам и замени цвет.
Бывают случаи на порядок проще.
const v2, -0x1
#### Здесь -0x1 == 0xFFFFFFFF — белый цвет
invoke-virtual {v1, v2}, Landroid/support/v7/widget/CardView;->setBackgroundColor(I)V
Нужно просто изменить -0x1 на -0x1000000, и приложение погрузится во тьму.
Стоит быть внимательным и пытаться разобраться в коде: иногда оптимизатор кода будет перемещать инструкции const вверх, и ты можешь их не заметить.
setTextColor
Иногда текст, который меняется в ходе работы с приложением, может менять свой цвет. За это отвечает параметр setTextColor(I)V, второй аргумент которого можно подменить на нужный, в нашем случае — белый.
#### Меняем цвет
const p1, -0x1
#### на белый
invoke-virtual {v0, p1}, Landroid/widget/TextView;->setTextColor(I)V
На этом борьбу со светлым фоном и ярким экраном можно закончить. Большинство элементов экрана поменяли свой цвет на противоположный. Так ты можешь изменить любое приложение, особенно если ты любишь потыкать в телефон поздно ночью.
Результат изменений
Меняем функциональность приложения
Чтобы ощутить всю мощь smali, давай попробуем изменить какую-то часть приложения. Например, обойдем проверку на внутренние покупки.
Возьмем другое приложение — . Оно показывает положение МКС над Землей. В нем можно купить расширения: показ комет, планет, Луны, телескопа «Хаббл».
При копировании приложения на компьютер может возникнуть проблема: в составе приложения не один и не два, а целых три файла apk!
$ adb shell pm path com.runar.issdetector
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/base.apk
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/split_config.en.apk
package:/data/app/com.runar.issdetector-dtgy8_hlf1y-cekrg1_W-A==/split_config.xxhdpi.apk
Копируем все. При переустановке приложения файлы split_config.en.apk и split_config.xxhdpi.apk потеряются, а без них приложение будет вылетать. Поэтому их нужно будет переподписать: зайти в них как в архивы ZIP, удалить папку META_INF и прогнать через стандартную процедуру утилиты jarsigner. Основной же файл мы будем препарировать с помощью apktool.
Покупками в приложении занимается интерфейс IInAppBillingService. Для него прописана обертка com.runar.issdetector.util: IabHelper, IabResult, Purchase, Security, Inventory.
В этом приложении можно не идти напролом, обманывая сервис покупок. Проще заставить приложение думать, что все уже куплено. В этом нам поможет Inventory.smali.
В особо сложных случаях такой трюк провернуть не удается, и тогда приходится подменять данные, заставляя сервис ложно сообщать о совершенных покупках. Подробнее об этом можно почитать в материале компании Securing Apps ().
Открыв файл, ты увидишь поле mPurchaseMap, которое содержит в себе все покупки: номер товара, сопоставленный с покупкой, которую совершил пользователь.
.field mPurchaseMap:Ljava/util/Map;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/Map<",
"Ljava/lang/String;",
"Lcom/runar/issdetector/util/Purchase;",
">;"
}
.end annotation
.end field
Далее в коде мы видим строку hasPurchase(String sku) -> boolean, которая проверяет, совершал ли пользователь покупку. Для этого делается проверка на существование ключа sku в mPurchaseMap.
.method public hasPurchase(Ljava/lang/StringZ
.locals 1
.line 45
iget-object v0, p0, Lcom/runar/issdetector/util/Inventory;->mPurchaseMap:Ljava/util/Map;
invoke-interface {v0, p1}, Ljava/util/Map;->containsKey(Ljava/lang/ObjectZ
move-result p1
return p1
.end method
А что будет, если в любом случае отдавать true?
.method public hasPurchase(Ljava/lang/StringZ
.locals 1
const p1, 0x1
return p1
.end method
Собираем приложение и устанавливаем его.
$ adb install-multiplie com.runar.issdetector.apk split_config.xxhdpi.apk split_config.en.apk
Success
Результат изменения кода
С этого можно начать свой путь в реверс-инжиниринг. Я рассказал тебе основы, с которых начинал сам. Небольшие изменения могут улучшить твою жизнь — надеюсь, я смог тебе это показать.