Сегодня в выпуске: реверс‑инжиниринг Flutter-приложения, подборка полезных функций‑расширений на Kotlin, две статьи об ошибках использования корутин и Flow в Kotlin, заметка об автоматически устаревающих комментариях, а также подборка из одиннадцати must have библиотек и десяток новых библиотек.
Reverse Engineering a Flutter app by recompiling Flutter Engine — статья о реверс‑инжиниринге приложений, написанных с использованием фреймворка Flutter.
Flutter — это кросс‑платформенный инструмент, предназначенный для создания быстрых приложений на языке Dart с использованием реактивного UI-фреймворка. Написанные с помощью Flutter приложения могут работать на Android, iOS, десктопе и вебе. При этом интерфейс будет полностью идентичен на всех платформах.
Главная особенность, отличающая Flutter от фреймворка, предоставляемого Android, в том, что код всего приложения, вместо набора из байт‑кода и ресурсов, компилируется в единую нативную библиотеку, разобраться в структуре которой достаточно сложно. К тому же формат данных в этой библиотеке постоянно меняется, что еще сильнее запутывает реверсера.
Библиотека, содержащая код приложения, называется libapp.so
. Причем это не просто код и данные приложения, а так называемый snapshot, представляющий собой снимок состояния виртуальной машины Dart перед передачей управления на точку входа приложения (функция main), плюс скомпилированный с помощью AOT-компилятора код всех классов приложения.
Разбирать код библиотеки libapp.so
классическим способом (запускаем IDA Pro и начинаем исследовать) бесполезно. Да, это нативный код, но формат самого файла в корне отличается от обычных библиотек.
Один из методов анализа состоит в том, чтобы пропарсить заголовок снапшота, найти в нем ссылки на все объекты типа Code (они как раз и хранят нативный код методов), а затем дизассемблировать находящиеся по этим адресам инструкции. В этом поможет инструмент Doldrums. Он выведет на экран все имеющиеся в коде классы и укажет, по каким адресам располагается код методов.
Проблема этого подхода в том, что формат снапшота меняется от версии к версии. Тот же Doldrums отлично работает для приложений, собранных с помощью Flutter 2.5, но не работает для более поздних версий.
Универсальный подход к анализу заключается в том, чтобы модифицировать сам фреймворк Flutter, располагающийся в библиотеке libflutter.so
рядом с libapp.so
. Для этого необходимо взять исходники фреймворка той же версии, добавить в них код для печати всех нужных нам данных (имена классов, методов и адреса их кода), а затем собрать его и заменить им оригинальный фреймворк в пакете приложения.
В частности, можно внести исправления в метод Deserializer::ReadProgramSnapshot(ObjectStore* object_store)
в файле runtime/vm/clustered_snapshot.cc
, чтобы заставить его распечатать таблицу классов. Также можно изменить метод void ClassTable::Print()
в файле runtime/vm/class_table.cc
для печати более подробной информации.
В статье приведено еще несколько деталей, как это сделать правильно, но нет готовых файлов. Так что в данный момент реверс‑инжиниринг Flutter-приложений — дело неблагодарное и достаточно сложное. До появления полноценных инструментов еще год‑другой.
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
-35%
1 год9300 рублей 6040 р. |
1 месяц870 р. |
Я уже участник «Xakep.ru»
Читайте также
Последние новости