Страницы

Поиск по вопросам

четверг, 4 октября 2018 г.

Непонятный smali

Я начинающий декомпилятор андроид приложений. Появилась нужда кое-что поменять в алгоритмах работы официального приложения ВКонтакте: чтобы перед входом выполнялось сохранение введенного логина и пароля в локальную базу данных, а также замена EditText на AutoCompleteTextView, для автозаполнения данных. Дело в том, что страничек у меня несколько и не очень-то удобно каждый раз вводить разные данные для входа. Затем, чтобы данные не сохранялись по умолчанию, нужно будет добавить CheckBox "сохранить пароль". В результате это будет очень удобно, а главное - отличное начало в практике декомпиляции и модификации. У меня есть ноутбук на Windows и рутованный android с деодексированной прошивкой. Скачал apktool и ввожу команду
apktool d apks\vk.apk
Где vk.apk - нетронутый APK, в папке apks. После завершения процесса я получаю папку vk с декомпилированным содержимым. С радостью и азартом открываю ее, ищу файлы .class - их нет. Зато есть некая папка с файлами .smali. Погуглив, понимаю что до чистого java кода добраться сложно и даже, если все получится, то высока вероятность получить ошибку при обратной компиляции. Поэтому, я отказался от dex2jar и решил учить smali следующим образом:
1) В студии делаю простенькие приложения с наипростейшим java кодом активности
2) Декомпилирую его
3) Сравниваю java код со smali
Так и учусь потихоньку. Единственное, что мне непонятно, это move-object и всякие другие коды этого типа, а также эти v1, v2, v3, v4, v5 и т.д. Особого внимания им не предал, поэтому решил просто, для начала создать класс враппер для работы с базой данных на java, декомпилировать его в smali и просто скопировать его в smali/com/vkontakte/android поменяв ссылки типа Lcom... на свои. Компилирую обратно:
apktool b vk -o vk-mod.apk
Где vk - папка для компиляции, vk-mod.apk - новый apk. Переношу на телефон, подписываю Zip Signer-ом, удаляю старую версию, устанавливаются мод, запускаю, вхожу в аккаунт. Так как я не добавил никакого кода для добавления записей в БД (метод insert), то база данных должна быть, но просто пустая. Запускаю Root Explorer, перехожу в /data/data/com.vkontakte.andtoid/databases и моей save.bd нету. Вообще. Проверяю, а вдруг база данных создаётся после вставки первой записи? Нет, она создаётся сразу при первом запуске, проверяю код smali, все верно, в чем проблема-то? Ладно, думаю дальше - может я не туда кинул smali? Нет, все верно. Подумал, наверно сделаю всё-таки вставку данных при нажатии на кнопку. В smali я полный ноль, поэтому пришлось немного подумать, чтобы найти куда рыть:
1) Ищу xml с этими двумя EditText-ами и кнопкой входа - auth.xml
2) Записываю имя xml и id полей логина и пароля, а также кнопки
3) Ищу идентификаторы в 16-ричном формате в R$id.smali и R$layout.smali
4) Делаю поиск с помощью Total Commander по всей папке smali, задав в ключевых словах сначала идентификатор xml, затем id тех самых view-элементов.
5) Смотрю на код AuthActivity.smali и туплю
Вроде, бы знакомые методы - getText(), toString(), find iewById(), затем передаются в лямбду логин и пароль, запускается ProgressDialog. Понимаю, что мне нужно "перехватить" логин и пароль при нажатии на кнопку сразу, до кода отправки их в процесс самого входа. Опять туплю. v16, p34 и всякие invoke-direct мозолят глаза, написал на java код для getWritableDatabase, ContentValues, методы put и конечный insert. Тестирую - работает. Декомпилирую его, узнаю как это будет в smali и вставляю в AuthActivity, примерно на место. Не знаю никакого нормального менеджера для редактирования, поиска и ковыряния в smali, поэтому все выполняю в блокноте, прошу не критиковать, я не знаю как это можно делать по-другому. В итоге, на этапе компиляции classes.dex вылазиют ошибки :( Сдался... Но ненадолго: на 4pda нашёл отличную тему, называется Инструкции по редактированию системных ресурсов, где профессионалы выкладывают инструкции типа "добавление кнопки сделать скриншот в шторке". Сравнивая коды, я начал получать хоть какие-то основы в smali кодинге, но вот никак и не пойму ничего. Народ, прошу вас, объясните мне конкретно максимально все базовые понятия о smali, так как в интернете я нашёл только информацию на английском, трудно и непонятно. И ещё - есть ли среда для редактирования smali, чтобы не ломать мозг в блокноте, без подсветки синтаксиса и всяких предупреждений об ошибках? И последнее - я правильно делаю все с R.smali, поиском идентификаторов? Оцените мой алгоритм, и помогите освоить smali. Очень надо. В будущем может создам сайт, группу в социальных сетях или даже приложение. Жду вразумительных ответов :)


Ответ

Smali схож с Java-байт-кодом, его знание может помочь. Но, так как в процессорах ARM-архитектуры много регистров, Google решили сэкономить и заменить долгие прогулки в память (в стек, как в JVM) на быстрые походы в регистры. Поэтому основное отличие байт-кода Dalvik от байт-кода JVM — ориентированность на регистры.
Например, System.out.println("Hello") в JVM-байт-коде выглядит приблизительно так:
getstatic System.out // PrintWriter на стеке ldc "Hello" // PrintWriter, "Hello" — два объекта на стеке invokevirtual PrintWriter.println(String):void // оба объекта забираются со стека // на PrintWriter выполняется виртуальный метод с параметром "Hello"
В Dalvik-байт-коде:
sget-object v0, System.out // PrintWriter в нулевом регистре const-string v1, "Hello" // "Hello" в первом регистре invoke-virtual PrintWriter.println(String):void, v0, v1 // вызвать виртуальный метод println на объекте v0 с параметром v1
Собственно, move-object перекладывает объект из регистра в регистр, а все эти v0, v1 и так далее — и есть регистры (value registers).
Кроме них есть ещё parameter registers — p0, p1 и т. д.. В этих регистрах оказываются значения, переданные в метод как параметры. Если метод не статический, то в p0 будет находиться this
invoke-direct напоминает invokespecial в JVM — он вызывает не виртуальный не статический метод. Примером могут служить финальные (и/или приватные) instance-методы.
Кроме того, в smali (в отличие от .class) нет пула констант, они задаются прямо в коде (см. fill-array-data-payload, const-string). Это связано с тем, что на все классы, находящиеся в одном dex, есть только один общий пул констант — это уменьшает объём по сравнению с .class и экономит время, потраченное на интернирование строк при загрузке классов.
Официальная документация с кратким, но понятным описанием опкодов: https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html
Практический пример взлома приложения: https://habrahabr.ru/post/141522/
Плагин к IDEA / Android Studio для smali: https://github.com/JesusFreke/smali/wiki/smalidea
P. S. в таких низкоуровневых вещах очень помогает знание того, как работает каждая малейшая деталь кода. Такое понимание характерно для опытного программиста. И к таким вещам можно вернуться через некоторый промежуток времени, посмотреть свежим взглядом и понять больше, чем раньше.
P. P. S. Непосредственно на тему ВКонтакте. Есть пара мыслей, готов поделиться в личку, если оставишь свои контакты (электропочту, например).

Комментариев нет:

Отправить комментарий