iOS - добавить "объекты" в существующее приложение (джейлбрейк)

Как добавить "объекты" в существующее приложение?

Например, настройка EasyRefresh для Chrome, включает новую кнопку в приложении iOS Chrome, как и многие другие настройки.

Как я могу добавить простой UIButton к, например, приложению Twitter?

Есть ли какие-нибудь проекты GitHub, которые могут помочь мне понять, как это делается?


образ

Источник изображения: ModMyI


Благодарю.

2 ответа

Решение

Уловка вовлекает некоторый (очень простой) реверс-инжиниринг и состоит из нескольких шагов; Я постараюсь объяснить их как можно более четко.

Шаг ноль: если приложение загружено из AppStore, оно зашифровано. Вы должны расшифровать его, используя один из скриптов / приложений, обычно используемых для взлома приложений; один сценарий командной строки - poedCrack.sh (Google, вы быстро найдете его на одном из сайтов для вставки), одно приложение с графическим интерфейсом -Crakculous (оно доступно в Cydia). Обратите внимание, что один из них необходим для простого (автоматического) дешифрования - метод ручного дешифрования слишком сложен, чтобы вставить ответ Stackru, поэтому я предлагаю эти инструменты.) Однако я ни в коем случае не поощряю вам взломать приложения! (В основном, я прошу вас не использовать эти инструменты для их первоначальной цели:) Если вы хотите взглянуть на процесс ручного дешифрования, отправляйтесь сюда.

Шаг первый: вам нужно сделать какие классы приложение использует / создает. Для этого вам понадобится утилита class-dump или class-dump-z. Это приложение командной строки обращает двоичный исполняемый файл приложения и генерирует объявления интерфейса для всех классов Objective C, которые приложение использует и имеет внутри. Вы можете найти class-dump-z, более продвинутый и предпочтительный вариант здесь.

Шаг второй: после того, как у вас есть объявления классов, вам нужно будет угадать, какой класс делает что и когда (да, немного сбивает с толку). Например, в одном из файлов, сгенерированных из вышеуказанного приложения, Google Chrome, с помощью class-dump-z, вы можете найти что-то похожее:

@interface ChromeUrlToolbar: UIToolbar {
    UISearchBar *urlBar;
}

- (id)initWithFrame:(CGRect)frame;
- (void)loadURL:(NSURL *)url;

@end

Ну, это звучит хорошо, не так ли? Вы можете видеть, что его реализация имеет метод initWithFrame: (как и все подклассы UIView) - почему бы не попробовать изменить его?

Шаг третий: для этой модификации вам понадобится MobileSubstrate. MobileSubstrate - это библиотека для разработчиков, созданная Saurik, создателем Cydia, для упрощения внедрения кода в приложения. Вы можете найти некоторые действительно хорошие учебники в Интернете, включая этот. Итак, у вас есть класс, и вы хотите его "зацепить" - поэтому вы пишете такой код:

static IMP __original_init; // A

id __modified_init(id __self, SEL __cmd, CGRect frame) // B
{
    __self = __original_init(__self, __cmd, frame); // C

    // D
    UIButton *newButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [newButton setTitle:@"Chrome Pwned"];
    newButton.frame = CGRectMake(0, 0, 100, 40);
    [__self addSubview:newButton];

    return __self;
}

// E
__attribute__((constructor))
void init()
{
    Class clazz = objc_getClass("ChromeUrlToolbar"); // F
    MSHookMessageEx(clazz, @selector(initWithFrame:), __modified_init, &__original_init); // G
}

Пояснение: давайте начнем с конца. init функция (E) объявлена __attribute__((constructor)), Это означает, что он автоматически вызывается, когда библиотека, которую мы создадим из этого кода, будет загружена в Chrome. Это именно то, что мы хотим, потому что мы хотим изменить поведение нашего приложения до его запуска.

На линии отмечены // F, мы захватили сам объект класса, который мы хотим изменить. Objective-C - высокодинамичный язык; это означает, что мы можем получать и изменять информацию о классах и объектах во время выполнения. На линии отмечены // GМы используем самую важную функцию MobileSubstrate API: MSHookMessageEx. Чтобы понять, как он работает (а точнее, что он делает), вы должны знать следующее: Objective-C сам по себе реализован как простая библиотека C - сам язык, находящийся под капотом, является просто простым C. Таким образом, каждое сообщение отправляется в Obejctive. -C на самом деле вызов функции C. Эти функции C имеют два специальных аргумента: self а также cmd - первый - указатель на объект, о котором идет обмен сообщениями, второй - селектор (специальный, уникальный указатель на имя отправляемого сообщения). Итак, что делает MSHookMessageEx, так это то, что он принимает класс и селектор, находит реализацию соответствующей им функции и обменивается этой функцией с функцией, предоставленной в ее третьем аргументе (__modified_init в этом случае). Чтобы не потерять данные, он также возвращает функцию в своем 4-м параметре (здесь это __original_init).

Итак, теперь инициализация панели инструментов Chrome URL перенаправлена ​​в нашу функцию, что делать дальше? Ну, ничего особенного: сначала мы просто вызываем исходную функцию инициализации (обратите внимание на первые два специальных аргумента, __self и __cmd!), Которая создает панель инструментов, как обычно (эта строка кода обозначается как // C). Затем мы делаем фактическое изменение: в разделе // D, мы создаем UIButton, устанавливаем его заголовок и место и добавляем в качестве подпредставления на нашу только что созданную панель инструментов. Затем, зная, что это функция инициализации, мы возвращаем исходный экземпляр вместе с введенным в него кодом нашей кнопки.

Ну, это в основном то, что вам нужно знать об этом; Если вам интересны более глубокие подробности о том, как работает Objective-C и как вы можете создавать крутые настройки iOS, я предлагаю вам прочитать официальную документацию Apple по этой теме, и вы можете просмотреть некоторые из моих настроек Cydia с открытым исходным кодом. также.

Я надеюсь, что это поможет вам!

Это необходимо для того, чтобы понять, как работает среда выполнения Objective C. Особенно система обмена сообщениями (т. Е. Вызов метода). В частности, методы для вызова определяются во время выполнения, по сравнению с другими языками, где это происходит во время компиляции. Это учитывает глобальное изменение определенных методов, иначе метод swizzling.

Используя библиотеку Mobile Substrate, вам будет разрешено заменить любую реализацию метода своей собственной и даже вызвать исходную реализацию. Для этого вам, конечно, нужно знать имя метода и аргумент, который он принимает, а также класс, к которому он принадлежит.

Так, например, чтобы изменить SpringBoard, вы должны знать, какой класс в нем содержится и какой метод. Вам придется использовать class-dump или же class-dump-z утилита, которая делает это для вас (class-dump-z более свежая и более используемая для iOS, class-dump является более универсальным и совместимым со старыми двоичными файлами, а также с 64-разрядной версией).

Таким образом, чтобы сбросить класс SpringBoard, вам нужно войти в Terminal.app

class-dump -H /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard -o ~/Desktop/SpringBoard

Для класса dump-z -p опция сгенерирует @property вместо геттеров / сеттеров, что более понятно, так что вы, вероятно, наберете

class-dump-z -p -H /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard -o ~/Desktop/SpringBoard

Эта строка создаст папку на вашем рабочем столе со всеми определениями классов SpringBoard. Конечно, вам может потребоваться изменить путь к тому, который подходит для вашей системы (о том, что для последних версий XCode папка разработчика находится в XCode, поэтому вам нужно что-то вроде

/Applications/Xcode/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/CoreServices/SpringBoard.app/SpringBoard

Вы также можете найти в Интернете людей, которые сделали это для вас для большинства существующих фреймворков, это очень удобно, если вы убедитесь, что они в правильной версии для вашей системы.

Теперь для приложений AppStore вам сначала нужно будет расшифровать их, поскольку они защищены. Вам, вероятно, нужно будет найти их имена и ссылки, так как это, вероятно, против ToS of Stack Overflow, хотя и с использованием gdb может достичь этой цели.

Чтобы облегчить работу, были созданы некоторые инструменты, такие как Logos (вам, вероятно, также понадобится увидеть Theos), которые уменьшают необходимый шаблонный код. Существует также (довольно старый) шаблон xcode и учебник для mobilesubstrate, который предоставляет хорошую помощь.

Логос позволяет легко подключить метод method из класса classname:

%hook classname //declares the class from your application you're going to override

-(void)method {

    dosomethingnew(); //put all your new code for the method here
    return %orig;     //this calls the original definition of the method
}
%end //end hooking classname

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

Последнее: список популярных твиков с открытым исходным кодом (по возможности ссылки на GitHub):

Некоторые маленькие хитрости

Наконец, взгляните на WeekTweak, они выпускают твик с открытым исходным кодом каждую неделю, чтобы вы могли узнать, посмотрев на чужой источник, чтобы попробовать и сделать что-то свое. И #theos chan на IRC (irc.saurik.com) также предоставит помощь, если вы попросите об этом.

Другие вопросы по тегам