Пишемо повноцінний твік для iOS за допомогою iOSOpenDev

Доброго часу доби!

Сьогодні я хотів би торкнутися теми розробки jailbreak-програм під iOS. У російськомовному інтернеті досить проблематично знайти щось зрозуміле новачкам, тому я спробую виправити це непорозуміння і пояснити як вирішуються деякі моменти.

Установка, настроювання середовища та пристрої, написання твіка з нуля — саме це чекає на вас під катом. Якщо вам цікаво, як поміняти частину iOS під себе — ласкаво просимо.

Почнемо!
Що нам потрібно?
  • Комп'ютер під управлінням Mac OS X з утилітами git, dpkg;
  • Xcode з встановленими Command Line tools (я використовую 5.1.1, однак, підходить 4.0+);
  • Theos;
  • Пакет iOSOpenDev;
  • іУстройство з 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 <IP пристрої>

Двічі вводимо пароль пристрою, і, якщо запросить — придумуємо пароль для кейчейна.
Більше того, потрібно завантажити пачку хеадеров і покласти в /opt/iOSOpenDev/include.

Тут складніше з IOSurfaceAPI.h, так як він не є вільно поширюваним кодом. Але якщо ви не зможете його добути з системи (на Mac OS X 10.10 я його не знайшов), то заберіть «заглушку» з папки _fallback, для нашого аналізу буде достатньо і її.

На цьому установку можна вважати завершеною.

Пишемо основу
Вся розробка буде проходити в Xcodе, хоча з деякими обмеженнями.

Створюємо новий проект і зустрічаємо новий пункт «iOSOpenDev».



Нам потрібно Logos Tweak:



Заповнюємо інформацію про проект. Include Simple PreferenceLoader додасть в проект простий блок налаштувань в Settings.app. Але про нього пізніше.

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



Після цього заходимо в наш .xm файл, зносимо директиву #error і натискаємо на збірку. Перша збірка буде невдалою, а друга повинна бути успішною, це нормально. Ще в xm файлі немає підсвічування синтаксису, але це вирішується закриттям і відкриттям Xcode після першої збірки.

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

Перші кроки
Сьогодні ми будемо міняти сумну напис «Розблокувати» екрану блокування на свій текст.

По-перше, було б добре роздобути хеадери бінарника «піддослідного». З SpringBoard все набагато простіше — народ готовий викладати хеадери спрингбоарда для кожної версії iOS. Але якщо ви хочете зробити їх самі, то утиліта class-dump-z вам у цьому допоможе.

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

Є два способи швидко знайти те, що нам потрібно. Перший — використовувати cycript і подивившись на ієрархію об'єктів знайти те, що потрібно. Другий — шукати пошуком по вмісту хеадеров. В даному випадку я вирішив пошукати за запитом «unlockText» і знайшов у класі SBLockScreenView такий от метод:

- (id)_defaultSlideToUnlockText;

Припустимо, що це те, що нам треба. Напишемо перший начерк:

#import <UIKit/UIKit.h>

%hook SBLockScreenView

- (id)_defaultSlideToUnlockText
{
return @"Привіт, Хабр!";
}

%end


Для компіляції з установкою на девайс виберіть Build for profiling:



І, о, диво! На подив все запрацювало з першого разу:



Наша основна мета — змусити змінюватися текст, тому створимо конструктор (%ctor) і будемо завантажувати настройки.

#import <UIKit/UIKit.h>

#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 і одну кнопку.



Ще можна підредагувати полі «label», щоб не світити цим «Bundle».

У кнопки є Action «respring:», тому опишемо метод респринга в 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-твіков для новачків.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.