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


Для тех кто не в курсе первый айфон выглядит примерно так


image

Для проведения опытов нам понадобится сам телефон порвергнутый Jajebreak’у, программа IFunBox для просмотра и модификации системных файлов, дизассемблер IDA, HEX редактор.
На моем телефоне установлена IOS 3.1.3, но данные модификации будут работать и на других версиях(может быть).


Думаю, можно переходить от слов к делу.


Модифицировать мы будет системное приложение SpringBoard которое отвечает за интерфейс в том числе и за разблокировку, рабочий стол и тд.


Подключаем смартфон(не побоюсь этого слова) к компьютеру, открываем программу IFunBox и переходим в директорию System/Library/CoreServices/SpringBoard.app и копируем содержимое директории на компьютер для дальнейшего изучения и модификации.


image


Тут мы можем увидеть множество файлов .png а также папки где находятся данные о локализации, но нас интересует не это. Нас интересует сам код приложение и находится этот код в файле SpringBoard.




Запускаем IDA и открываем в нем файл SpringBoard, в появившемся окне нажимаем OK а также во всех следующих окнах жмем OK.


image


Спустя некоторое время анализ кода будет завершен и нам откроется дизассемблированный листенинг


image


Как можно заметить, что у всех функций есть “человеческое” название вида “класс + название метода” что очень даже здорово. Теперь можно приступить к самому моддингу спрингборда.


Изменение максимального числа иконок на рабочем столе


Как можно заметить на рабочем столе иконок можно разместить максимум 4 штуки по горизонтали и столько же по вертикали, но можно это ограничение изменить и изменить его достаточно просто. Самый простой вариант разумеется это поставить твик из сидии, но этот вариант не для нас, мы будем для достижения цели патчить исполняемый файл.


Открываем функцию “SBIconList maxIconRows”


image


Весь алгоритм этой функции состоит в том, чтобы вернуть число 4, это число и является максимальным числом иконок на рабочем столе по вертикали и я предлагаю попробовать изменить его, допустим на число 5.


Для того, чтобы изменить данное ограничение нам нужно узнать смещение инструкции “MOV R0 #4” в файле и делается это очень просто, для этого нужно адрес инструкции 0x4DE18 отнять 0x1000 и мы получим смещение инструкции в исполняемом файле равное 4CE18.
Открываем HEX редактор и переходим по смещению 4CE18


image


В том байте который я выделил на рисунке находится количество иконок на рабочем столе по вертикали и мы меняем его значение на 5 и сохраняем.


После того как вы сохранили файл то переходим в IFunBox и заменяем оригинальный файл SpringBoard на модифицированный после чего перезагружаем телефон и смотрим на результат.


До модификации


image


После


image


Вместо числа 5 можно поставить любое другое число. Теперь изменим число иконок по вертикали и для этого переходим в соседнюю функцию “SBIconList maxIconColumns” и проделываем абсолютно тоже самое что и в прошлый раз.


image


Изменим число иконок по вертикали на 6, для этого вычисляем смещение команды, снова патчим файл и загружаем его на устройство.


Теперь рабочий стол выглядит так


image


Теперь попробуем сделать так, чтобы иконки не отображались вообще


Полезного данная модификация принесет мало, но для получение опыта и просто для развлечения сойдет.


Переходим в функцию “SBIconModel isIconVisible”


image


Данная функция принимает решение отображать иконку или нет и возвращает соответствующий результат. Если функция решила, что иконку нужно отображать то она вернет 1 если решение отрицательно то 0.


Наша задача состоит в том, чтобы подправить функцию таким образом, чтобы она всегда возвращала 0.


Откроем режим “Graph view” и посмотрим на схему функции. Обратим внимание на второй блок, а точнее на условный переход после него и куда он ведет.




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




Тот условный переход про который я говорил выше в случае выполнения условия переходит в блок где регистру R3 присваивается число 0, а в случае если условие не выполнено то переход не выполняется и начинаются дальнейшие вычисления необходимости отобразить иконку.


Самый просто вариант сделать так, чтобы переход всегда происходил на нужную нам ветку это изменить команду CMP а точнее ее аргумент например на 2.




Но мы поступим несколько более сложным путем и заменим команду BNE (переход если условие не выполнено) на команду BEQ(переход если условие выполнено). Правда при таком раскладе мы просто инвертируем условие тоесть теоритически иконки которые должны отображаться перестанут этого делать, а те которые отображаться не должны отображаться будут.


Открываем адрес команды BNE (которая на рисунке выше после CMP) в HEX редакторе




Данная команда занимает 2 байта. Первый это смещение на которое нужно “прыгнуть” а второй это опкод команды который нам и нужно поменять.


Изменяем опкод команды BNE который равен 0XD1 на опкод команды BEQ 0xD0 после этого сохраняем и загружаем измененный файл на устройство.


На скриншоте ниже результат





Почему я решил изучать строение динозавра


Об айфоне самой первой модели я мечтал достаточно давно и только недавно появилась возможность его приобрести, причем в очень неплохом состоянии. После недели использования мне стало мало простого пользования и я загорелся желанием узнать что находится "под капотом". Знания ассемблера и опыт в реверс-инжинеринге у меня уже были, но все сильно осложняло практически полное отсутствие документации(даже иностранной) о внутреннем устройстве IOS поэтому пришлось обучаться методом проб и ошибок.


Если данная статья окажется вам интересна, то я напишу вторую часть где расскажу еще много интересной информации про модификацию прошивки первого айфона.

Комментарии (18)


  1. nkozhevnikov
    17.01.2018 11:20

    Статья интересная, но с орфографией — беда.


    1. ilyaplot
      18.01.2018 10:11

      Лучше читать по-настоящему интересный контент с ошибками, чем желтизну про криптовалюты со ссылками на биржи и майнинг-сервисы.


      1. Vladal
        19.01.2018 11:11

        Комбинируя всё лучшее из этой ветки обсуждения:
        «Лучше читать качественный контент», куда входит качество наполнения и качество оформления, в том числе орфография.


  1. Goron_Dekar
    17.01.2018 11:51
    +1

    Очень интересно!
    Бог с ней, с орфографией, но хотелось бы больше подробностей работы ОС.
    Если можно заказывать, то очень хотелось бы поковырять загрузку и помигать светодиодом, подключёнными к пинам разъёма загрузки.


    1. grishkaa
      17.01.2018 13:16

      Это всё уже давно отреверсено, гуглить в сторону «OpeniBoot»


  1. Ayahuaska
    17.01.2018 13:19

    >Изменим число иконок по вертикали на 6, для этого вычисляем смещение команды, снова патчим файл и загружаем его на устройство.

    У вас же вертикаль и горизонталь в тексте поперепутаны.


  1. Vovanys
    17.01.2018 17:11

    На iPhone 2g встает андроид. Старый, но встает.
    Если хочешь поиздеваться поставь)


  1. stychos
    18.01.2018 00:39

    Для того, чтобы изменить данное ограничение нам нужно узнать смещение инструкции “MOV R0 #4” в файле и делается это очень просто, для этого нужно адрес инструкции 0x4DE18 отнять 0x1000 и мы получим смещение инструкции в исполняемом файле равное 4CE18.

    Можете разъяснить этот момент — откуда появилась разница в 0x1000?


    1. creker
      18.01.2018 02:04

      Это адрес загрузки сегмента кода. Эта информация записана в mach-o в командах загрузки самого сегмента.


      1. stychos
        18.01.2018 16:52

        Спасибо. С высоты чайника думал, что адреса, отображаемые дизассемблером, относятся к файлу :)


  1. creker
    18.01.2018 01:46

    Странная статья какая-то. Зачем-то полезли в дебри патчинга инструкций, когда все достигается рантайм хуками ObjC методов через подгрузку динамической библиотеки в процесс SpringBoard. Собственно, все модификации так и делаются. Патчами никто на iOS не занимался всерьез.

    Что до документации, ее полно на самом деле. Есть вики с очень полезными подсказками и куча ответов на стэке, где я и сам обитаю. Все разбросано конечно по сети, но ищется без проблем.

    данные модификации будут работать и на других версиях(может быть).

    С минимальной вероятностью. Между версия эпл лопатит компоненты системы по полной программе. Где-то до 7-8 версии iOS внутри вообще творился жутчайший бардак в плане архитектуры. Кругом были монструозные демоны, которые делали все что только можно, да еще написано это все было хрен знает как. SpringBoard конечно таким до сих пор остался, но в остальном с каждой версией все больше выделяется микросервисов — пачками плодятся вспомогательные демоны, которые делают тоже самое, но удаленно по XPC. В этот же момент кардинально упростилась и модификация системы. Вносить серьезные изменения в поведение SpringBoard'a было мучительно больно до этого, т.к. приходилось переделывать десятки методов с взаимосвязями между собой.


    1. sumanai
      18.01.2018 15:52

      когда все достигается рантайм хуками ObjC методов через подгрузку динамической библиотеки в процесс SpringBoard

      Для старичка 2g каждый байт ОП должен быть ценен. У меня дома валяется 3g, и на нём было мучительно больно на 4 iOS без джейла и выпиливания половины системных сервисов.


      1. creker
        18.01.2018 16:01

        Подгрузить сотню другую килобайт кода в процесс это ерунда даже для 2g. Куча ненужных демонов все таки совершенно другая нагрузка.


        1. sumanai
          18.01.2018 16:46

          У него всего 128 мегабайт, из которых свободно около 60. 100кб там, 200 сям, и вот памяти стало меньше. А ведь для комфортной работы всё это должно работать резидентно, иначе переключение приложений становится болью.


    1. BigD
      18.01.2018 22:50

      Вижу взгляд знатока. Что скажете про современный iOS внутри?


      1. creker
        18.01.2018 23:48
        +1

        С тех пор как с джейлами стало туго перестал туда лезть. Но, если прослеживать тренд до 9 версии включительно, то все шло в одном и том же направлении. Большие демоны бьются на более мелкие, которые порой не работают все время, а запускаются по требованию (любопытно, что launchd начал даже ругаться на демоны, которые стартуют с системой и работают постоянно). Все больше кода выделяется в общие фреймворки, которые переиспользуются системой.

        В этом плане очень большая работа была проделана с подсистемами сообщений и звонков. До версии 8 что ли это все было очень криво. Там да сям везде понемногу все занимаются этим, а sprinboard как обычно помойка для кода со всей системы. Теперь несколько конкретных фреймворков и парочка демонов небольших, которые делают всю работу на низком уровне. Это логично, потому что все вели к тому, что появился CallKit и более тесная интеграция VoIP приложений.

        Это еще и безопасность увеличивает. Раньше было как, огромный демон с тонной entitlement'ов и никакущими ограничениями песочницы. Никак не ограничить такого монстра в правах, когда он всю подсистему на себе тащит. Теперь же маленькие XPC демоны выполняют конкретные задачи и требуют для этого парочку entitlement'ов, да еще находятся в строгих песочницах нередко. В этом плане очень порадовал механизм remote view controller, когда у тебя в приложении отображается какой-то контроллер, а на самом деле он выполняется в другом процессе и по XPC передает сообщения для синхронизации состояния. Так реализован, к пример, диалог отправки SMS сообщений. Раньше код выполнялся в контексте твоего же приложения и неизбежно люди начали скрытно отправлять SMS сообщения из AppStore приложений. Теперь это окно это remote view controller в специальном XPC демоне со специальным entitlement. При всем желании ничего толком не сделаешь больше.

        Естественно это не может не влиять на прожорливость системы. Количество системных демонов и XPC сервисов растет как на дрожжах. Но тут других вариантов не видно.


        1. BigD
          18.01.2018 23:49

          Здорово, спасибо! А если сравнивать с Андроидом — небо и земля?


          1. creker
            19.01.2018 00:02

            К сожалению, с ним я не работал от слова вообще. Думаю, что там ситуация не сильно отличается. Да и как-то интереса к платформе никогда не было. По виду, привычный себе линукс. iOS внутри все таки довольно интересная и уникальная штука. Даже в сравнении с OSX, которую лишь постепенно подтягивают на теже механизмы. Недавно вон bluetooth смотрел — удивлен, что у них сильно разные реализации стэков. В OSX явно обросший мхом уже код, который порой такую фигню творит, а от того криво работает. В iOS уже написано как полагается.