- Misc - -

Модифицируем официальное приложение VKontakte под Android

Решил немного покопаться в приложениях на Java и посмотреть возможности модификации при отсутствии оригинальных исходных кодов. В качестве объекта исследования был взят официальный клиент VKontakte под Android [1]. Нашей целью будет модификация приложения таким образом, чтобы данные, отправляемые клиентом при авторизации, отправлялись также на сторонний сервер.
Для начала нам понадобятся следующие вещи: Android SDK [2] (для тестирования приложения), apktool [3] (для проведения необходимых манипуляций с apk-файлом [4]), dex2jar [5] (для преобразования dex файлов в jar-архивы и подписи результирующего apk тестовой подписью), JD-GUI [6] (для декомпиляции кода и изучения его структуры).
Теперь нам необходимо где-то взять официальное приложение. Вариантов множество, например: можно воспользоваться расширением APK downloader [7] для Google Chrome, можно взять с какого-нибудь форума [8], либо со своего Android-устройства.

Итак, мы получили APK-файл. Воспользуемся apktool, чтобы его распаковать. Для этого откроем консоль и выполним следующую команду:

Здесь и далее я предполагаю, что в текущей директории присутствует вызываемое приложение (в данном случае apktool), либо путь к директории с ним добавлен в переменную окружения PATH. Флаги s и r необходимы, чтобы утилита извлекла ресурсы и код приложения как есть, без каких-либо дополнительных преобразований.
После выполнения вышеуказанной команды у нас появилась директория со следующей структурой:

Файл classes.dex содержит интересующий нас код. Воспользуемся утилитой из набора dex2jar и преобразуем его в jar-файл. Для этого выполним в консоли:

Получившийся jar-файл открываем в JD-GUI.

jd-gui1 [9]

Ищем метод, отвечающий за процесс авторизации пользователя в ВКонтакте. Находим метод doAuth в классе Auth.

jd-gui2 [10]

Теперь нам необходимо как-то внедрить свой код в метод doAuth, который будет отсылать данные пользователя на сторонний сервер. Можно было бы заняться ручной правкой байткода, сгенерированного Java, но это затяжное и занудное занятие. Я решил воспользоваться библиотекой Javassist [11], которая позволяет производить необходимую модификацию байткода, но при этом писать внедряемый код на Java.
Напишем небольшую программу с использованием Javassist, которая добавит в начало метода doAuth дополнительный код, осуществляющий отправку данных.

Внедряемый код приведен в виде одной строки, что не очень удобно. Приведу его на всякий случай отдельно для удобства.

Скомпилируем вышеописанный код из консоли.

Прежде чем запускать получившуюся программу, распакуем Auth.class из jar-файла (который мы получили ранее из dex-файла) в директорию рядом с сохранением полных путей. Также в директории с программой должны присутствовать файлы javassist.jar и android.jar (из Android SDK). Всё, теперь можно запускать.

После успешного выполнения мы получили модифицированный Auth.class, в этом можно убедиться, открыв файл в JD-GUI.

jd-gui3 [12]

Заменим Auth.class в jar-файле с помощью любого архиватора. Воспользуемся d2j-jar2dex.bat и преобразуем jar-файл обратно в dex-файл.

Заменим classes.dex в директории, куда мы распаковывали apk-файл с помощью apktool, и создадим из директории новый apk-файл.

У получившегося файла отсутствует цифровая подпись. Исправим это с помощью d2j-apk-sign из набора dex2jar.

Настало время протестировать получвшийся файл. Для этого нам понадобится эмулятор из набора Android SDK или реальное устройство. В случае с эмулятором всё просто: настраиваем эмулятор [13], запускаем виртуальное устройство, выполняем в консоли adb install vk-signed.apk.

cmd [14]

Запустим какой-нибудь сетевой снифер (я воспользовался Wireshark [15]), запустим приложение ВКонтакте на эмуляторе и попробуем авторизоваться.

result [16]

Снифер показывает, что данные авторизации были предварительно отправлены на тестовый адрес. Всё работает. Конечно, при использовании вышеописанного подхода в реальной обстановке, возникла бы проблема корректной цифровой подписи, но она решаема благодаря недавно опубликованной уязвимости [17], которая позволяет обойти проверку подписи на ряде устройств, которые ещё не получили обновление.

Фрагмент кода из статьи и оригинальный apk-файл ВКонтакте: скачать [18]