
Инструментарий IDA для анализа кэшей ядра iOS.
Этот форк обновлён для работы с IDA 9.x / Python 3 / iOS 27.0 beta 1
ida_kernelcache — это модуль IDAPython для IDA Pro, упрощающий работу с ядерными кешами iOS. Модуль предоставляет функции для:
__PRELINK_INFO в словарь Python.__got и функций-заглушек в секциях __stubs.Основная функция обработки предназначена для запуска до любого ручного анализа или реверс-инжиниринга. При настройках по умолчанию IDA, как правило, упускает много полезной информации в ядерном кеше. Эти скрипты помогают IDA, используя известную структуру ядерного кеша для автоматического распространения полезной информации.
Помимо стандартной функциональности модуля, ida_kernelcache содержит несколько скриптов, упрощающих анализ ядерного кеша iOS. Например, с помощью скриптов можно автоматически генерировать структуры C, используемые функцией.
Многие методы, используемые в ida_kernelcache, были разработаны для memctl и заимствованы непосредственно из него.
ida_kernelcache тестировался с IDA Pro 6.95 на ядерных кешах для версий iOS 10.1.1, 11.0, 11.2, 11.3.1 и 12.0 beta. В настоящее время поддерживаются только ядерные кеши Arm64 начиная с iOS 10.
У вас уже должен быть загружен в IDA распакованный файл ядерного кеша. URL для загрузки конкретного IPSW можно найти у Apple онлайн, и существует ряд публичных инструментов (включая memctl), способных распаковать ядерный кеш.
В IDA выберите в строке меню "File" -> "Script file...", затем выберите скрипт ida_kernelcache.py
в главном каталоге. Это загрузит модуль ida_kernelcache в интерпретатор IDAPython
под именами ida_kernelcache и kc. В приглашении IDAPython введите
kc.kernelcache_process() и нажмите Enter, чтобы начать анализ ядерного кеша. Эта функция выполняет
весь основной анализ, поддерживаемый ida_kernelcache. Функция будет выполняться несколько минут, пока
IDA идентифицирует и анализирует новые функции.
ida_kernelcache будет стараться не перезаписывать пользовательские имена для адресов. Это означает, что если
ядерный кеш был проанализирован вручную до инициализации с помощью kernelcache_process,
результаты могут быть не такими полными, поскольку заданные пользователем имена могут блокировать автоматическое
распространение имён. Однако также нет гарантии, что ida_kernelcache не испортит предыдущий анализ,
поэтому если вы решите запустить kernelcache_process на уже проанализированном файле ядерного кеша,
сначала сделайте резервную копию.
ida_kernelcache предназначен для загрузки через ida_kernelcache.py; подмодули в каталоге
ida_kernelcache не предназначены для прямой загрузки. Однако ida_kernelcache предоставляет
доступ к функциональности многих из этих подмодулей. Вот что делает каждый из них:
ida_utilities:
Этот модуль оборачивает некоторые функции IDA, предоставляя более удобный API. Особенно полезны
is_mapped, read_word, read_struct, force_function и ReadWords. is_mapped проверяет,
отображён ли адрес и, опционально, содержит ли он известное значение. read_word считывает
слово переменного размера по адресу. read_struct считывает структурный тип в словарь Python
или объект доступа Python, что значительно упрощает разбор структур данных. force_function использует
несколько приёмов для преобразования адреса в начало функции в IDA. ReadWords — это
генератор для итерации по словам данных и их адресам в диапазоне.
build_struct: Этот внутренний модуль содержит утилиты для автоматического заполнения структуры IDA на основе последовательности обращений к структуре.
class_struct:
Этот модуль предоставляет функции для генерации структур IDA, представляющих таблицы виртуальных методов C++ и
классы. initialize_vtable_structs сканирует (символизированные) таблицы виртуальных методов и создаёт
структуры IDA для хранения указателей на виртуальные методы. initialize_class_structs выполняет анализ
потока данных в виртуальных методах для выявления обращений к полям каждого класса, а затем строит
структуры IDA для представления классов. Инструкции, которые, по-видимому, ссылаются на поле, также
преобразуются в ссылки на смещения в структуре. Подробнее см. docstring модуля.
classes:
Этот модуль определяет тип ClassInfo, который хранит информацию о классах C++ в ядерном кеше,
и предоставляет функцию collect_class_info для сканирования ядерного кеша на предмет классов и
заполнения глобального словаря class_info соответствием имён классов объектам ClassInfo.
Тип ClassInfo записывает имя класса, экземпляр OSMetaClass, таблицу виртуальных методов и
имя суперкласса для каждого класса C++. Кроме того, каждый объект ClassInfo хранит ссылки на
ClassInfo суперкласса и ClassInfo всех прямых подклассов, что упрощает
изучение и обход иерархии классов. collect_class_info также сохраняет набор всех таблиц
виртуальных методов в глобальном множестве vtables.
data_flow: Этот внутренний модуль содержит операции потока данных, используемые остальной частью ida_kernelcache.
kernel:
Этот модуль предоставляет глобальные переменные base и prelink_info. base — это базовый адрес
образа ядра (начало Mach-O заголовка ядра). prelink_info — это разобранный словарь
__PRELINK_INFO.
kplist:
Этот модуль предоставляет функцию kplist_parse для разбора plist-файлов в стиле ядра.
metaclass:
Этот модуль предоставляет функцию initialize_metaclass_symbols, которая добавляет символ для каждого
известного экземпляра OSMetaClass.
offset:
Этот модуль предоставляет функции initialize_data_offsets и initialize_offset_symbols. Первая
сканирует сегменты в поисках указателей, которые можно преобразовать в смещения. Вторая
символизирует смещения в секции __got каждого kext, если цель смещения имеет символ.
segment:
Этот модуль предоставляет функцию initialize_segments для переименования сегментов IDA в более
полезные. По умолчанию IDA, по-видимому, создаёт имена сегментов, комбинируя предположительный
идентификатор пакета с секцией Mach-O, описывающей область. initialize_segments извлекает
фактический идентификатор пакета из словаря __PRELINK_INFO и переименовывает каждый сегмент,
включая идентификатор пакета, сегмент Mach-O и секцию Mach-O. Это позволяет, например, различать
__TEXT.__const и __DATA_CONST.__const. Этот модуль также предоставляет функцию
kernelcache_kext (повторно экспортируемую на верхнем уровне) для определения kext, содержащего
указанный адрес (только в старом формате ядерного кеша iOS 11 с раздельными kext).
stub:
Многие kext в ядерном кеше содержат функции-заглушки в секции __stubs, которые переходят к функциям
в самом ядре. К сожалению, эти заглушки создают барьер для распространения перекрёстных ссылок
и информации о типах. Этот модуль не решает эти проблемы, но он упрощает просмотр заглушек,
автоматически переименовывая функции-заглушки так, чтобы было видно имя целевой функции.
Заглушки и их цели принудительно преобразуются в функции в IDA, что помогает привести
функции в IDA в соответствие с функциями в исходном коде.