[Из песочницы] Пишем полноценный твик для iOS с помощью iOSOpenDev

Доброго времени суток! Сегодня я хотел бы вновь затронуть тему разработки jailbreak-программ под iOS. В русскоязычном интернете довольно проблематично найти что-то понятное новичкам, поэтому я попытаюсь исправить это недоразумение и объяснить как решаются некоторые моменты.

Установка ПО, настройка среды и устройства, написание твика с нуля — именно это ждёт вас под катом. Если вам интересно, как поменять часть iOS под себя — добро пожаловать.

Что нам потребуется? Компьютер под управлением Mac OS X с утилитами git, dpkg; Xcode с установленными Command Line tools (я использую 5.1.1, однако, подходит 4.0+); Theos; Пакет iOSOpenDev; iУстройство с jailbreak’ом и установленным OpenSSH. Подготовка Первым шагом будет установка Xcode. Его вы можете скачать с Mac AppStore, а так же с страницы загрузок на сайте Apple. Подробно на этом останавливаться не буду.Следом нужно поставить theos. Нам говорят, что его можно запихать на любую платформу, и он будет работать, но сегодня мы не изобретаем велосипед делаем всё на родной для iOS SDK системе.

Скачиваем theos в папку /opt/theos. Можно ставить в любую папку, но на свой страх и риск:

export THEOS=/opt/theos git clone git://github.com/DHowett/theos.git $THEOS На этом настройка c theos можно закончить.Скачиваем iOSOpenDev и запускаем инсталлер. Он сделает всё за вас.В случае возникновения неизвестной ошибки скорее всего приложение называется не «Xcode.app» или вы его не запускали вовсе.

Халява закончилась. Время настройки переменных.Открываем ~/.bash_profile и редактируем следующие строчки:

export iOSOpenDevDevice=айпи.адрес.вашего.устройства Теперь iOSOpenDev будет знать IP вашего устройства, осталось только разрешить подключаться по SSH без запроса пароля и скачать всю необходимую базу библиотек: iod-setup base iosod sshkey -h Дважды вводим пароль устройства, и, если запросит — придумываем пароль для кейчейна.Более того, нужно скачать пачку хеадеров и положить в /opt/iOSOpenDev/include.Тут сложнее всего с IOSurfaceAPI.h, так как он не является свободно распространяемым кодом. Но если вы не сможете его добыть из системы (на Mac OS X 10.10 я его не нашел), то заберите «заглушку» из папки _fallback, для нашего разбора будет достаточно и её.

На этом установку можно считать завершенной.

Пишем основу Вся разработка будет проходить в Xcodе, хотя с некоторыми ограничениями.Создаём новый проект и встречаем новый пункт «iOSOpenDev».

f654f554df2e40ddbecb4a186b36a9fa.png

Нам требуется Logos Tweak:

229a4407d27d4910ab831ad2898884ad.png

Заполняем информацию о проекте. Include Simple PreferenceLoader добавит в проект простой блок настроек в Settings.app. Но о нём позже.

Теперь мы должны сделать то, что Xcode сам не делает — добавить в список для линковшика UIKit.framework и libsubstrate.dylib (последняя лежит в /opt/iOSOpenDev/lib/).

95ec4189977045f7bb7ef31904196e95.png

После этого заходим в наш .xm файл, сносим директиву #error и нажимаем на сборку. Первая сборка будет неудачной, а вторая должна быть успешной, это нормально. Еще в xm файле нет подсветки синтаксиса, но это решается закрытием и открытием Xcode после первой сборки.

Расставим все точки над «i»: .xm файл отвечает за код твика, а .mm файл является «промежуточным», он автоматически генерируется logos-препроцессором и потом компилируется.

Первые шаги Сегодня мы будем менять унылую надпись «Разблокируйте» экрана блокировки на свой текст.Во-первых, было бы хорошо раздобыть хеадеры бинарника «подопытного». Со SpringBoard все гораздо проще — народ готов выкладывать хеадеры спрингбоарда для каждой версии iOS. Но если вы хотите сделать их сами, то утилита class-dump-z вам в этом поможет.

Я пишу для iPad 4 на iOS 8.1, поэтому и хеадеры смотрим соответсвующие.

Есть два способа быстро найти то, что нам требуется. Первый — использовать cycript и посмотрев на иерархию объектов найти то, что нужно. Второй — искать поиском по содержимому хеадеров. В данном случае я решил поискать по запросу «unlockText» и нашел в классе SBLockScreenView такой вот метод:

 — (id)_defaultSlideToUnlockText; Предположим, что это то, что нам надо. Напишем первый набросок: #import

%hook SBLockScreenView

— (id)_defaultSlideToUnlockText { return @«Привет, Хабр!»; }

%end Для компиляции с установкой на девайс выберите Build for profiling:

3fe2cb09c912460fb3bcd3f656214ce2.png

И, о, чудо! На удивление всё заработало с первого раза:

3f7d1f849e89412fa0a6990984b6bfaf.jpg

Наша основная цель — заставить меняться текст, поэтому создадим конструктор (%ctor) и будем подгружать настройки.

#import

#define SETTINGS_FILE @»/var/mobile/Library/Preferences/ru.firemoon777.LockLabel8Bundle.plist»

NSDictionary *settings;

%hook SBLockScreenView

— (id)_defaultSlideToUnlockText { return [settings objectForKey:@«Text»]; }

%end

static void loadSettings () { settings = [[NSDictionary alloc] initWithContentsOfFile: SETTINGS_FILE]; }

%ctor { loadSettings (); } Создаём панель настроек Создадим новую цель: File — New — Target — iOS Open Dev — PreferenceBundle; Назовём её LockLabel8Bundle.Есть большой плюс проекта с «сложными» PreferenceBundle’ом — в настройках можно сделать весь графический интерфейс для приложения и не заморачиваться с запуском от рута и подписями. Но есть и минус — панель в настройках и сам твик собираются в отдельных пакетах, поэтому для релиза придётся их ещё и объединить.Можете попробовать собрать шаблон и полюбоваться на множество возможных встроенных PSSpecifier’ов.

Возможно, оно не скопилится сразу как надо. Значит, вы пропустили скачивание хеадров, про которые я говорил в начале статьи.

Из всех я оставлю только первую и последнюю группу, TextView и одну кнопку.

d09306f8948845c182c4dab1af8b6e4e.png

Еще можно подредактировать поле «label», чтобы не светить этим «Bundle».

У кнопки есть Action «respring:», поэтому опишем метод респрингa в LockLabel8BundleController:

 — (void)respring:(PSSpecifier*)specifier { system («killall SpringBoard»); } С разработкой внутри настроек всё гораздо проще: здесь действуют те же законы, что и в обычных приложениях.Исходный код доступен на гитхабе.

Поддержка нескольких версий iOS? Когда твик становится из простого наброска масштабным проектом, возникает вопрос, а как организовать поддержку нескольких версий iOS так, чтобы не загружалось ничего лишнего? Тут на помощь приходят группы. %group iOS6 // Методы для iOS6 %end

%group iOS78 // Методы для iOS7+ %end

%ctor { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) { init (iOS78); } else { init (iOS6); } }

iOSOpenDev всего лишь плагин для Xcode, но, на мой взгляд, он гораздо проще и удобнее, чем «голый» theos. На Mac OS X он заметно облегчает разработку iOS-твиков для новичков.

© Habrahabr.ru