Разработка
Реверс-инжиниринг iOS-приложения
Этот эксперимент продемонстрировал, как реверс-инжиниринг и внедрение кода могут быть использованы для изменения поведения приложения.
Около месяца назад я познакомился с увлекательным миром реверс-инжиниринга, и это было похоже на открытие сундука с сокровищами! Я и представить себе не мог, что, начав с чего-то столь простого, как приложение на джейлбрейкнутом устройстве, можно открыть совершенно новое поле для творчества и экспериментов.
Я решил использовать свой старый iPhone 6 по назначению и с головой окунулся в это приключение. Моим первым проектом было простое приложение с UITextField и UIButton, в котором пользователь угадывает код. Если он угадал правильно, то появляется всплывающее окно об успехе; если нет, то появляется всплывающее окно о повторной попытке. Это была базовая настройка, но она идеально подходила для моего исследования.
Мне не терпелось узнать, как много я смогу сделать реверс-инжинирингом с этим простым приложением. В итоге я изменил логику работы пинов и заменил обычные сообщения на игривое всплывающее окно «Hello World». Было удивительно видеть, как даже небольшое изменение может оказать такое влияние!
Шаг 1: Сделайте джейлбрейк iOS-устройства и установите SSH, SFTP
Итак, первым делом сделайте джейлбрейк вашего iPhone. Я не буду вдаваться в тонкости того, как это сделать, — есть масса руководств и видео. Для своего приключения я использовал iPhone с iOS 12 и джейлбрейком unc0ver. После этого откройте Cydia и найдите openssh для установки.
Шаг 2: Загрузите приложение и распакуйте его
Теперь, когда ваш телефон настроен, пришло время установить на него ваше приложение. Используйте SFTP, чтобы перенести файл приложения в каталог /Applications вашего iPhone. Этот файл имеет формат .ipa — считайте, что это шикарный подарок в запакованном виде. Распакуйте его прямо на телефоне. Для примера вы можете скачать исходный код и скомпилировать ipa.
Шаг 3: Подключите приложение с помощью Cycript
Настало время для грандиозного финала: подключите ваше приложение к Cycript. Войдите в устройство по SSH и убедитесь, что ваше приложение AnalysisDemoApp находится на переднем плане (не дремлет в фоновом режиме). С помощью команды UIApp найдите главного героя приложения, он же rootViewController.
Спойлер: имя звезды — ViewController.
Шаг 4: Подготовьте инструменты отладки — Debugserver и LLDB
Теперь пришло время подключить наших верных помощников в отладке: debugserver и LLDB. Во-первых, вам нужно установить debugserver через SSH или Cydia. Считайте это настройкой вашего набора инструментов для отладки. После этого вы будете использовать LLDB для удаленного подключения к процессу вашего приложения. Это похоже на небольшую виртуальную проверку вашего приложения на расстоянии.
Подключившись, выполните команды типа [[UIWindow keyWindow] recursiveDescription]
, чтобы заглянуть во внутреннее устройство приложения. Эта команда покажет вам иерархию элементов, и если вы заметите исходный UIView, то, скорее всего, это замаскированный UIViewController. Используя Cycript, мы можем подтвердить, что этот UIViewController действительно называется «ViewController». Запустив команду nextResponder
, мы получим адрес VC, который будет 0x100d08590. Это как найти секретное местоположение комнаты управления!
Я выполнил еще одну команду, po [0x100d08590 _methodDescription]
, которая перечислила все методы по заданному адресу. Чтобы навести порядок, я экспортировал этот список в текстовый файл, дав команду session save output
. Просматривая вывод, я заметил метод с именем `buttonTapped` — он выглядел как метод, связанный с действием кнопки.
При изучении приложения с Hopper выяснилось, что при вызове `buttonTapped` процедура выполняет некоторую простую логику, а затем показывает всплывающее окно.
Мы планируем создать фреймворк и использовать обход метода (method swizzling) для модификации метода `buttonTapped`. Это позволит нам внедрить собственный код и заменить оригинальную функциональность. В данном примере новое поведение будет заключаться в появлении веселого сообщения «Hello World».
Вот окончательный результат. Скомпилировав фреймворк и выполнив переключение метода `buttonTapped`, я успешно интегрировал модифицированный фреймворк в существующий IPA с помощью Sideloadly.
В результате приложение теперь отображает всплывающее окно «Hello World» вместо своей первоначальной функциональности. Этот эксперимент продемонстрировал, как реверс-инжиниринг и внедрение кода могут быть использованы для изменения поведения приложения. Он стал наглядным примером возможностей модификации приложений на iOS-устройствах.