Мачо
![]() | Эта статья включает список общих ссылок , но в ней отсутствуют достаточные соответствующие встроенные цитаты . ( февраль 2021 г. ) |
![]() | |
Расширение имени файла | никто, .o , .dylib , .bundle |
---|---|
Единый идентификатор типа (UTI) | com.apple.mach-o-binary |
Разработано | Университет Карнеги-Меллона , Apple Inc. |
Тип формата | Двоичные файлы , исполняемые файлы , объекты , общие библиотеки , дамп ядра |
Контейнер для | ARM , SPARC , PA-RISC , PowerPC и x86 , дампы образов памяти Исполняемый код |
Mach-O , сокращение от Mach формата объектного файла , представляет собой формат файла для исполняемых файлов , объектного кода , общих библиотек , динамически загружаемого кода и дампов ядра . Он был разработан для замены формата a.out .
Mach-O используется некоторыми системами, основанными на ядре Mach . NeXTSTEP , macOS и iOS — примеры систем, использующих этот формат для собственных исполняемых файлов, библиотек и объектного кода.
Макет файла Mach-O [ править ]
Каждый файл Mach-O состоит из одного заголовка Mach-O, за которым следует серия команд загрузки, за которыми следуют один или несколько сегментов, каждый из которых содержит от 0 до 255 разделов. REL Mach-O использует формат перемещения для обработки ссылок на символы. При поиске символов Mach-O использует двухуровневое пространство имен , которое кодирует каждый символ в пару «имя объекта/символа», которая затем линейно ищется сначала по объекту, а затем по имени символа. [1]
Базовая структура — список «команд загрузки» переменной длины, которые ссылаются на страницы данных в другом месте файла. [2] — также использовался в формате исполняемого файла для Accent . [ нужна ссылка ] Формат файла Accent, в свою очередь, был основан на идее Spice Lisp . [ нужна ссылка ]
Все многобайтовые значения во всех структурах данных записываются в порядке байтов хоста, для которого был создан код. [3]
Заголовок Mach-O [ править ]
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | Магическое число |
4 | 4 | Тип процессора |
8 | 4 | Подтип ЦП |
12 | 4 | Тип файла |
16 | 4 | Количество команд загрузки |
20 | 4 | Размер команд загрузки |
24 | 4 | Флаги |
28 | 4 | Зарезервировано (только 64-разрядная версия) |
Магическое число для 32-битного кода: 0xfeedface
в то время как магическое число для 64-битных архитектур равно 0xfeedfacf
.
Зарезервированное значение присутствует только в 64-битных файлах Mach-O. Он зарезервирован для будущего использования или расширения 64-битного заголовка.
Тип ЦП указывает архитектуру набора команд для кода. Если файл предназначен для 64-битной версии архитектуры набора команд, значение типа ЦП имеет значение 0x01000000
бит установлен.
Значения типа ЦП следующие: [5]
Ценить | Тип процессора |
---|---|
0x00000001 | ВАКС |
0x00000002 | шумка |
0x00000004 | НС32032 |
0x00000005 | НС32332 |
0x00000006 | MC680x0 |
0x00000007 | х86 |
0x00000008 | МИПС |
0x00000009 | НС32352 |
0x0000000A | MC98000 |
0x0000000B | HP-PA |
0x0000000C | РУКА |
0x0000000D | MC88000 |
0x0000000E | СПАРК |
0x0000000F | i860 (обратный порядок байтов) |
0x00000010 | i860 (с прямым порядком байтов) |
0x00000011 | РС/6000 |
0x00000012 | PowerPC |
Каждый тип ЦП имеет набор значений подтипа ЦП, указывающий конкретную модель того типа ЦП, для которого предназначен код. Более новые модели типа ЦП могут поддерживать инструкции или другие функции, не поддерживаемые более старыми моделями ЦП, поэтому код, скомпилированный или написанный для более новой модели, может содержать инструкции, которые являются недопустимыми инструкциями для более старой модели, что приводит к перехвату этого кода или иному не работает корректно при запуске на более старой модели. Код, предназначенный для более старой модели, будет без проблем работать на более новых моделях.
Если тип ЦП — ARM, то подтипы следующие: [5]
Ценить | Версия процессора |
---|---|
0x00000000 | Все процессоры ARM. |
0x00000001 | Оптимизирован для ARM-A500 ARCH или новее. |
0x00000002 | Оптимизирован для ARM-A500 или новее. |
0x00000003 | Оптимизирован для ARM-A440 или новее. |
0x00000004 | Оптимизирован для ARM-M4 или новее. |
0x00000005 | Оптимизирован для ARM-V4T или новее. |
0x00000006 | Оптимизирован для ARM-V6 или новее. |
0x00000007 | Оптимизирован для ARM-V5TEJ или новее. |
0x00000008 | Оптимизирован для ARM-XSCALE или новее. |
0x00000009 | Оптимизирован для ARM-V7 или новее. |
0x0000000A | Оптимизирован для ARM-V7F (Cortex A9) или новее. |
0x0000000B | Оптимизирован для ARM-V7S (Swift) или новее. |
0x0000000C | Оптимизирован для ARM-V7K (Kirkwood40) или новее. |
0x0000000D | Оптимизирован для ARM-V8 или новее. |
0x0000000E | Оптимизирован для ARM-V6M или новее. |
0x0000000F | Оптимизирован для ARM-V7M или новее. |
0x00000010 | Оптимизирован для ARM-V7EM или новее. |
Если тип ЦП — x86, то подтипы следующие: [5]
Ценить | Версия процессора |
---|---|
0x00000003 | Все процессоры x86. |
0x00000004 | Оптимизирован для 486 или новее. |
0x00000084 | Оптимизирован для 486SX или новее. |
0x00000056 | Оптимизирован для Pentium M5 или новее. |
0x00000067 | Оптимизирован для Celeron или новее. |
0x00000077 | Оптимизирован для Celeron Mobile. |
0x00000008 | Оптимизирован для Pentium 3 или новее. |
0x00000018 | Оптимизирован для Pentium 3-M или новее. |
0x00000028 | Оптимизирован для Pentium 3-XEON или новее. |
0x0000000A | Оптимизирован для Pentium-4 или новее. |
0x0000000B | Оптимизирован для Itanium или новее. |
0x0000001B | Оптимизирован для Itanium-2 или новее. |
0x0000000C | Оптимизирован для XEON или новее. |
0x0000001C | Оптимизирован для XEON-MP или новее. |
После значения подтипа следует значение типа файла.
Ценить | Описание |
---|---|
0x00000001 | Перемещаемый объектный файл. |
0x00000002 | Требуемый подкачиваемый исполняемый файл. |
0x00000003 | Исправлен файл общей библиотеки виртуальной машины. |
0x00000004 | Основной файл. |
0x00000005 | Предзагруженный исполняемый файл. |
0x00000006 | Динамически связанный файл общей библиотеки. |
0x00000007 | Редактор динамических ссылок. |
0x00000008 | Динамически связанный файл пакета. |
0x00000009 | Заглушка общей библиотеки только для статического связывания, без содержимого раздела. |
0x0000000A | Сопутствующий файл, содержащий только разделы отладки. |
0x0000000B | x86_64 кексты. |
0x0000000C | файл, состоящий из других Mach-O, который будет запускаться в одном пользовательском пространстве, используя один связанный файл. |
После значения типа файла указывается количество команд загрузки и общее количество байтов команд загрузки. После заголовка Mach-O следует 32-битный флаг со следующими возможными настройками.
Флаг в левой смене | Флаг в двоичном формате | Описание |
---|---|---|
1<<0 | 0000_0000_0000_0000_0000_0000_0000_0001 | Объектный файл не имеет неопределенных ссылок. |
1<<1 | 0000_0000_0000_0000_0000_0000_0000_0010 | Объектный файл представляет собой результат инкрементальной связи с базовым файлом и не может быть повторно отредактирован по ссылке. |
1<<2 | 0000_0000_0000_0000_0000_0000_0000_0100 | Объектный файл является входным для динамического компоновщика, и его нельзя снова редактировать статически. |
1<<3 | 0000_0000_0000_0000_0000_0000_0000_1000 | Неопределенные ссылки объектного файла связываются динамическим компоновщиком при загрузке. |
1<<4 | 0000_0000_0000_0000_0000_0000_0001_0000 | К файлу предварительно привязаны динамические неопределенные ссылки. |
1<<5 | 0000_0000_0000_0000_0000_0000_0010_0000 | В файле разделены сегменты только для чтения и для чтения и записи. |
1<<6 | 0000_0000_0000_0000_0000_0000_0100_0000 | Процедура инициализации разделяемой библиотеки должна выполняться лениво, перехватывая ошибки памяти в ее записываемых сегментах (устарело). |
1<<7 | 0000_0000_0000_0000_0000_0000_1000_0000 | В образе используются двухуровневые привязки пространства имен. |
1<<8 | 0000_0000_0000_0000_0000_0001_0000_0000 | Исполняемый файл заставляет все изображения использовать привязки плоского пространства имен. |
1<<9 | 0000_0000_0000_0000_0000_0010_0000_0000 | Этот зонтик гарантирует отсутствие множественных определений символов в своих фрагментах, поэтому всегда можно использовать двухуровневые подсказки пространства имен. |
1<<10 | 0000_0000_0000_0000_0000_0100_0000_0000 | Не заставляйте dyld уведомлять агент предварительной привязки об этом исполняемом файле. |
1<<11 | 0000_0000_0000_0000_0000_1000_0000_0000 | Бинарный файл не является предварительно привязанным, но его предварительную привязку можно переделать. используется только тогда, когда MH_PREBOUND не установлен. |
1<<12 | 0000_0000_0000_0000_0001_0000_0000_0000 | Указывает, что этот двоичный файл привязывается ко всем двухуровневым модулям пространства имен зависимых библиотек. |
1<<13 | 0000_0000_0000_0000_0010_0000_0000_0000 | Безопасное разделение разделов на подразделы с помощью символов для удаления мертвого кода. |
1<<14 | 0000_0000_0000_0000_0100_0000_0000_0000 | Бинарный файл был канонизирован с помощью операции отмены предварительной привязки. |
1<<15 | 0000_0000_0000_0000_1000_0000_0000_0000 | Окончательное связанное изображение содержит внешние слабые символы. |
1<<16 | 0000_0000_0000_0001_0000_0000_0000_0000 | В окончательном связанном изображении используются слабые символы. |
1<<17 | 0000_0000_0000_0010_0000_0000_0000_0000 | Когда этот бит установлен, всем стекам в задаче будут предоставлены привилегии выполнения стека. |
1<<18 | 0000_0000_0000_0100_0000_0000_0000_0000 | Когда этот бит установлен, двоичный файл объявляет, что его можно безопасно использовать в процессах с нулевым uid. |
1<<19 | 0000_0000_0000_1000_0000_0000_0000_0000 | Когда этот бит установлен, двоичный файл объявляет, что его можно безопасно использовать в процессах, когда UGID имеет значение true. |
1<<20 | 0000_0000_0001_0000_0000_0000_0000_0000 | Когда этот бит установлен в dylib, статическому компоновщику не нужно проверять зависимые dylib, чтобы увидеть, были ли они реэкспортированы. |
1<<21 | 0000_0000_0010_0000_0000_0000_0000_0000 | Когда этот бит установлен, ОС будет загружать основной исполняемый файл по случайному адресу. |
1<<22 | 0000_0000_0100_0000_0000_0000_0000_0000 | Только для использования в dylibs. При связывании с dylib, у которого установлен этот бит, статический компоновщик не будет автоматически создавать команду загрузки в dylib, если из dylib не ссылаются никакие символы. |
1<<23 | 0000_0000_1000_0000_0000_0000_0000_0000 | Содержит раздел типа S_THREAD_LOCAL_VARIABLES. |
1<<24 | 0000_0001_0000_0000_0000_0000_0000_0000 | Когда этот бит установлен, ОС будет запускать основной исполняемый файл с кучей неисполняемых файлов даже на платформах (например, i386), которые этого не требуют. |
1<<25 | 0000_0010_0000_0000_0000_0000_0000_0000 | Код был связан для использования в приложении. |
1<<26 | 0000_0100_0000_0000_0000_0000_0000_0000 | Внешние символы, перечисленные в таблице символов nlist, не включают все символы, перечисленные в информации dyld. |
1<<27 | 0000_1000_0000_0000_0000_0000_0000_0000 | Разрешите команды загрузки LC_MIN_VERSION_MACOS и LC_BUILD_VERSION на платформах macOS, macCatalyst, iOSSimulator, tvOSSimulator и watchOSSimulator. |
1<<31 | 1000_0000_0000_0000_0000_0000_0000_0000 | Только для использования в dylibs. Когда этот бит установлен, dylib является частью общего кэша dyld, а не находится в файловой системе. |
---- | 0xxx_0000_0000_0000_0000_0000_0000_0000 | Цифры, отмеченные знаком «x», не используются и зарезервированы для использования в будущем. |
Во флагах можно установить несколько двоичных цифр, равных единице, чтобы идентифицировать любую информацию или настройки, применимые к двоичному коду.
Теперь команды загрузки считываются по мере достижения конца заголовка Mach-O.
Бинарные файлы с несколькими архитектурами [ править ]
Несколько файлов Mach-O можно объединить в двоичный файл с несколькими архитектурами . Это позволяет одному двоичному файлу содержать код для поддержки нескольких архитектур набора команд, например, для разных поколений и типов устройств Apple, включая разные архитектуры процессоров. [6] например ARM64 и x86-64 . [7]
Все поля в универсальном заголовке имеют обратный порядок байтов. [3]
Универсальный заголовок имеет следующий вид: [8]
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | Магическое число |
4 | 4 | Количество двоичных файлов |
Магическое число в двоичном файле с несколькими архитектурами: 0xcafebabe
в порядке байтов с обратным порядком байтов, поэтому первые 4 байта заголовка всегда будут 0xca 0xfe 0xba 0xbe
, в таком порядке.
Количество двоичных файлов — это количество записей, следующих за заголовком.
За заголовком следует последовательность записей в следующей форме: [9]
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | Тип процессора |
4 | 4 | Подтип ЦП |
8 | 4 | Смещение файла |
12 | 4 | Размер |
16 | 4 | Выравнивание секции (степень 2) |
За последовательностью записей следует последовательность изображений Mach-O. Каждая запись относится к изображению Mach-O.
Тип и подтип ЦП для записи должны совпадать с типом и подтипом ЦП для образа Mach-O, к которому относится запись.
Смещение и размер файла — это смещение в файле начала изображения Mach-O и размер изображения Mach-O, к которому относится запись.
Выравнивание раздела представляет собой логарифм по основанию 2 выравнивания байтов в файле, необходимом для изображения Mach-O, к которому относится запись; например, значение 14 означает, что изображение должно быть выровнено по координате 2. 14 -байтовая граница, т.е. граница в 16384 байта. Это требуется для инструментов, которые изменяют двоичный файл мультиархитектуры, чтобы они могли правильно выровнять изображение.
Загрузить команды [ править ]
Команды загрузки считываются сразу после заголовка Mach-O.
Заголовок Mach-O сообщает нам, сколько команд загрузки существует после заголовка Mach-O, а также размер в байтах до места, где заканчиваются команды загрузки. Размер команд загрузки используется в качестве проверки избыточности.
Когда последняя команда загрузки прочитана и количество байтов для команд загрузки не совпадает или если мы выходим за пределы количества байтов для команд загрузки до достижения последней команды загрузки, файл может быть поврежден.
Каждая команда загрузки представляет собой последовательность записей в следующем виде: [10]
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | Тип команды |
4 | 4 | Размер команды |
Тип команды загрузки определяет параметры команды загрузки. Если команда загрузки начинается с 0x80000000
установлен бит, что означает, что команда загрузки необходима для загрузки или запуска двоичного файла. Это позволяет более старым загрузчикам Mach-O пропускать непонятные загрузчику команды, которые не являются обязательными для загрузки приложения.
Команда загрузки сегмента [ править ]
Двоичные файлы Mach-O, использующие тип команды загрузки 0x00000001
используйте 32-битную версию команды загрузки сегмента, [11] пока 0x00000019
используется для указания 64-битной версии команды загрузки сегмента., [12]
Команда загрузки сегмента зависит от того, является ли заголовок Mach-O 32-битным или 64-битным. Это связано с тем, что 64-битная архитектура процессора использует 64-битные адреса, а 32-битная архитектура использует 32-битные адреса.
Все адреса виртуальной оперативной памяти добавляются к базовому адресу, чтобы обеспечить разнесение приложений. Каждый раздел в команде загрузки сегмента имеет смещение списка перемещения, которое определяет смещения в разделе, которые необходимо настроить на основе базового адреса приложения. Перемещения не нужны, если приложение может быть размещено в определенных местах адреса ОЗУ, например, с нулевым базовым адресом.
Смещение (32-битное) | Байты (32-битные) | Смещение (64-битное) | Байты (64-бит) | Описание |
---|---|---|---|---|
0 | 4 | 0 | 4 | 0x00000001 (Тип команды 32-битный)
|
4 | 4 | 4 | 4 | Размер команды |
8 | 16 | 8 | 16 | Название сегмента |
24 | 4 | 24 | 8 | Адрес |
28 | 4 | 32 | 8 | Размер адреса |
32 | 4 | 40 | 8 | Смещение файла |
36 | 4 | 48 | 8 | Размер (в байтах от смещения файла) |
40 | 4 | 56 | 4 | Максимальная защита виртуальной памяти |
44 | 4 | 60 | 4 | Начальная защита виртуальной памяти |
48 | 4 | 64 | 4 | Количество секций |
52 | 4 | 68 | 4 | Флаг32 |
Имя сегмента не может превышать 16 текстовых символов в байтах. Неиспользуемые символы 0x00
по стоимости.
Команда сегмента содержит адрес для записи раздела в виртуальном адресном пространстве, а также базовый адрес приложения. Количество байтов для записи по адресу (размер адреса).
После того, как информация об адресе представляет собой смещение файла, данные сегмента располагаются в двоичном формате Mach-O, а количество байтов, которые необходимо прочитать из файла.
Когда размер адреса превышает количество байтов, которые нужно прочитать из файла, остальные байты в пространстве ОЗУ устанавливаются 0x00
.
Существует сегмент под названием __PAGEZERO, который имеет нулевое смещение и нулевой размер в файле. Он имеет определенный адрес и размер ОЗУ. Поскольку он считывает нулевые байты из файла, он заполняет нулями адрес того места, где двоичный файл будет помещен в ОЗУ. Этот сегмент необходим для того, чтобы избавить раздел от любых данных из предыдущего приложения.
Когда сегмент изначально помещается в виртуальное адресное пространство, ему предоставляются права доступа к ЦП, указанные в исходном значении защиты виртуальной памяти. Разрешения на область виртуального адресного пространства могут быть изменены кодом приложения или библиотеки с помощью вызовов таких процедур, как mprotect()
; максимальная защита виртуальной памяти ограничивает разрешения, которые могут быть предоставлены для доступа к сегменту.
Бит разрешения в двоичном формате | Описание |
---|---|
00000000000000000000000000000001 | Этот раздел позволяет ЦП читать данные из этого раздела (настройка «Чтение»). |
00000000000000000000000000000010 | Этот раздел позволяет ЦП записывать данные в этот раздел (настройка записи). |
00000000000000000000000000000100 | Этот раздел позволяет ЦП выполнять код в этом разделе (настройка «Выполнить»). |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx000 | Цифры, отмеченные знаком «x», не используются и зарезервированы для использования в будущем. |
Затем после настроек защиты адреса ЦП указывается количество разделов, находящихся внутри этого сегмента, которые читаются после установки флага сегментов.
Настройки флага сегмента следующие:
Флаг32 в двоичном формате | Описание |
---|---|
00000000000000000000000000000001 | Содержимое файла для этого сегмента предназначено для верхней части пространства виртуальной машины, нижняя часть заполнена нулями (для стеков в основных файлах). |
00000000000000000000000000000010 | Этот сегмент представляет собой виртуальную машину, выделенную фиксированной библиотекой виртуальных машин для проверки перекрытия в редакторе ссылок. |
00000000000000000000000000000100 | В этом сегменте нет ничего перенесенного в него и ничего перенесенного в него, то есть его можно смело заменить без перемещения. |
00000000000000000000000000001000 | Этот сегмент защищен. Если сегмент начинается со смещения файла 0, первая страница сегмента не защищена. Все остальные страницы сегмента защищены. |
00000000000000000000000000010000 | Этот сегмент становится доступным только для чтения после того, как при необходимости применяются перемещения. |
xxxxxxxxxxxxxxxxxxxxxxxxxxx00000 | Цифры, отмеченные знаком «x», не используются и зарезервированы для использования в будущем. |
Количество разделов в сегменте представляет собой набор записей, которые читаются следующим образом:
Смещение (32-битное) | Байты (32-битные) | Смещение (64-битное) | Байты (64-бит) | Описание |
---|---|---|---|---|
0 | 16 | 0 | 16 | Название раздела |
16 | 16 | 16 | 16 | Название сегмента |
32 | 4 | 32 | 8 | Адрес раздела |
36 | 4 | 40 | 8 | Размер секции |
40 | 4 | 48 | 4 | Смещение файла сечения |
44 | 4 | 52 | 4 | Выравнивание |
48 | 4 | 56 | 4 | Смещение файла релокации |
52 | 4 | 60 | 4 | Количество переездов |
56 | 4 | 64 | 4 | Флаг/Тип |
60 | 4 | 68 | 4 | Зарезервировано1 |
64 | 4 | 72 | 4 | Зарезервировано2 |
Н/Д | Н/Д | 76 | 4 | Зарезервировано3 (только 64-разрядная версия) |
Имя сегмента раздела должно совпадать с именем команды загрузки сегментов. Записи разделов относятся к данным в сегменте. В каждом разделе находятся записи перемещения для корректировки адресов в разделе, если базовый адрес приложения добавляется к чему-либо, кроме нуля.
Размер раздела применяется как к размеру раздела по его адресу, так и к размеру файла по его смещению.
Значение раздела Флаг/Тип читается следующим образом:
Флаг в двоичном формате | Описание |
---|---|
10000000000000000000000000000000xxxxxxxx | Раздел содержит только настоящие машинные инструкции. |
01000000000000000000000000000000xxxxxxxx | Раздел содержит объединенные символы, которых не должно быть в оглавлении ranlib. |
00100000000000000000000000000000xxxxxxxx | Хорошо, чтобы удалить статические символы в этом разделе из файлов с флагом MH_DYLDLINK. |
00010000000000000000000000000000xxxxxxxx | Никакого мертвого стриптиза |
00001000000000000000000000000000xxxxxxxx | Блоки являются активными, если они ссылаются на активные блоки. |
00000100000000000000000000000000xxxxxxxx | Используется с заглушками кода i386, написанными dyld. |
00000010000000000000000000000000xxxxxxxx | Раздел отладки |
00000000000000000000010000000000xxxxxxxx | Раздел содержит некоторые машинные инструкции. |
00000000000000000000001000000000xxxxxxxx | В разделе есть записи о внешнем перемещении |
00000000000000000000000100000000xxxxxxxx | В разделе есть записи о локальном перемещении |
Любая из настроек, применимых к разделу, имеет двоичный набор цифр. Последние восемь двоичных цифр — это значение типа раздела.
Флаг в двоичном формате | Описание |
---|---|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000110 | Раздел только с неленивыми указателями на символы |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000111 | Раздел только с ленивыми указателями на символы |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001000 | Раздел только с заглушками символов |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001100 | Раздел с нулевым заполнением по требованию (размер которого может превышать 4 гигабайта) |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00010000 | Раздел только с ленивыми символьными указателями на ленивые загруженные библиотеки. |
Загрузчик Mach-O записывает разделы указателей символов и разделы-заглушки символов. Они последовательно используются таблицей косвенных символов для загрузки вызовов методов.
Размер каждой заглушки символа хранится в значении Reserved2. Каждый указатель представляет собой 32-битные адреса в 32-битном Mach-O и 64-битные адреса в 64-битном Mach-O. Достигнув конца раздела, мы переходим к следующему разделу, читая таблицу косвенных символов.
Номер сегмента и номера разделов [ править ]
Сегменты и разделы расположены по номеру сегмента и номеру раздела в сжатых и несжатых разделах информации редактирования ссылок.
Значение сегмента 3 будет означать смещение данных команды загрузки четвертого сегмента в файле Mach-O, начиная с нуля вверх (0,1,2,3 = 4-й сегмент).
Разделы также нумеруются от разделов 1 и выше. Нулевое значение раздела используется в таблице символов для символов, которые не определены ни в одном разделе (неопределено). Например, метод или данные, которые существуют в другом разделе таблицы символов двоичных файлов.
Сегмент, имеющий 7 разделов, будет означать, что последний раздел имеет номер 8. Тогда, если следующая команда загрузки сегмента имеет 3 раздела, они будут помечены как разделы 9, 10 и 11. Номер раздела 10 будет означать второй сегмент, раздел 2.
Мы не сможем правильно прочитать таблицу символов и информацию о связях, если не сохраним порядок чтения разделов и их положение смещения адреса/файла.
Вы можете легко использовать смещение файла без использования адресов и перемещений ОЗУ для создания программы чтения символов, чтения разделов редактирования ссылок и даже сопоставления вызовов методов или разработки дизассемблера.
Если вы создаете загрузчик Mach-O, вам нужно выгрузить разделы по определенным адресам ОЗУ плюс базовый адрес, чтобы приложения были разнесены друг от друга, чтобы они не записывали друг друга.
Имена сегментов и разделов можно переименовать во что угодно, и при этом не возникнет проблем с поиском соответствующих разделов по номеру раздела или номеру сегмента, если вы не измените порядок, в котором идут команды сегмента.
Ссылка на библиотеки [ править ]
Библиотеки ссылок такие же, как и любые другие двоичные файлы Mach-O, за исключением того, что в них нет команды, определяющей основную точку входа, с которой начинается программа.
Существует три команды загрузки для загрузки файла связанной библиотеки.
Тип команды загрузки 0x0000000C
относятся к полному пути к динамически подключаемой общей библиотеке.
Тип команды загрузки 0x0000000D
предназначены для динамически связанных общих расположений из текущего пути приложения.
Тип команды загрузки 0x00000018
предназначен для динамически подключаемой общей библиотеки, которая может отсутствовать. Имена символов существуют в других библиотеках ссылок и используются, если библиотека отсутствует, что означает, что все символы импортированы слабо.
Команда компоновки библиотеки читается следующим образом:
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x0000000C (Тип команды)
|
4 | 4 | Размер команды |
8 | 4 | Смещение строки (всегда смещение 24) |
12 | 4 | Штамп даты и времени |
16 | 4 | Текущая версия |
20 | 4 | Совместимая версия |
24 | Размер команды - 24 | Строка пути к файлу |
Имя пути к файлу начинается со смещения строки, которое всегда равно 24. Число байтов на текстовый символ равно оставшимся байтам в размере команды. Конец пути к файлу библиотеки обозначается символом, который 0x00
. Остальные 0x00
значения используются в качестве дополнения, если таковые имеются.
Порядковые номера библиотеки ссылок [ править ]
Библиотека расположена по порядковому номеру в сжатом и несжатом разделах информации о редактировании ссылок.
Библиотеки ссылок нумеруются от порядкового номера 1 и выше. Нулевой порядковый номер используется в таблице символов, чтобы указать, что символ не существует в качестве внешнего символа в другом двоичном файле Mach-O.
Информация о редактировании ссылки не вызовет проблем с поиском соответствующей библиотеки для чтения по порядковому номеру, если вы не измените порядок, в котором идут команды библиотеки ссылок.
Команда связывания библиотеки 0x00000018
следует избегать из соображений производительности, так как в случае отсутствия библиотеки поиск необходимо выполнять по всем загруженным библиотекам ссылок.
__LINKEDIT Таблица символов [ изменить ]
Файлы приложений Mach-O и библиотеки ссылок имеют команду таблицы символов.
Команда читается следующим образом:
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x00000002 (Тип команды) |
4 | 4 | Размер команды (всегда 24) |
8 | 4 | Символы (смещение файла относительно заголовка Mach-O) |
12 | 4 | Количество символов |
16 | 4 | Таблица строк (смещение файла относительно заголовка Mach-O) |
20 | 4 | Размер таблицы строк |
Смещение файла символов — это смещение относительно начала заголовка Mach-O до места, где в файле начинаются записи символов. Количество записей символов отмечает конец таблицы символов.
Символ имеет смещение имени, которое никогда не должно превышать размер таблицы строк. Каждое смещение имени символа добавляется к смещению файла таблицы строк, которое, в свою очередь, относится к началу заголовка Mach-O. Имя каждого символа заканчивается 0x00
значение байта.
Адрес символа использует 32-битный адрес для 32-битных файлов Mach-O и 64-битный адрес для 64-битных файлов Mach-O.
Каждая запись символа читается следующим образом:
Смещение (32-битное) | Байты (32-битные) | Смещение (64-битное) | Байты (64-бит) | Описание |
---|---|---|---|---|
0 | 4 | 0 | 4 | Смещение имени |
4 | 1 | 4 | 1 | Тип символа |
5 | 1 | 5 | 1 | Номер секции от 0 до 255 |
6 | 2 | 6 | 2 | Информация о данных (порядковый номер библиотеки) |
8 | 4 | 8 | 8 | Адрес символа |
Смещение имени символа добавляется к смещению таблицы строк. Последний байт текстового символа читается как 0x00
.
Значение типа символа имеет несколько настраиваемых разделов в двоичном формате. Тип символа читается следующим образом:
Двоичные цифры | Описание |
---|---|
???xxxxx | Локальные символы отладки |
xxxx???x | Тип адреса символа |
xxx?xxx? | Флаги настройки видимости символов |
Цифры, отмеченные ?
используются по назначению; цифры отмечены x
используются для других целей.
Три первые двоичные цифры представляют собой символы, которые соответствуют именам функций относительно инструкций скомпилированного машинного кода и номерам строк по расположению адреса. Эта информация позволяет нам генерировать номера строк в месте сбоя вашего кода. Локальные символы отладки полезны только при разработке приложения, но не нужны для его запуска.
Бинарное значение | Описание |
---|---|
xxxx000x | Символ не определен |
xxxx001x | Символ абсолютный |
xxxx101x | Символ косвенный |
xxxx110x | Предварительная привязка символа не определена |
xxxx111x | Символ, определенный в номере раздела |
Следующие настройки флага:
Бинарное значение | Описание |
---|---|
xxx1xxx0 | Частный символ |
xxx0xxx1 | Внешний символ |
Внешние символы — это символы, которые имеют определенный адрес в библиотеке ссылок и могут быть скопированы в неопределенный символ в приложении Mach-O. Местоположение адреса добавляется к базовому адресу библиотеки ссылок.
Частный символ пропускается, даже если он соответствует имени неопределенного символа. Частному и внешнему символу можно назначить неопределенный символ, только если он находится в одном файле.
После типа символа указывается номер раздела, в котором находится символ. Номер раздела представляет собой байтовое значение (от 0 до 255). Вы можете добавить больше разделов, чем 255, используя команды загрузки сегментов, но тогда номера разделов выходят за пределы диапазона значений байтов, используемого в записях символов.
Нулевой номер раздела означает, что символ отсутствует ни в одном разделе приложения, адрес символа равен нулю и ему присвоено значение «Неопределено». Соответствующее имя внешнего символа необходимо найти в библиотеке ссылок, имеющей адрес символа.
Поле информации о данных содержит порядковый номер связанной библиотеки, в которой можно найти внешний символ с соответствующим именем символа. Поле информационных битов данных выглядит следующим образом:
Двоичные цифры | Описание |
---|---|
????????xxxxxxxx | Порядковый номер библиотеки от 0 до 255 |
xxxxxxxx????xxxx | Параметры флага динамического загрузчика |
xxxxxxxxxxxx???? | Вариант типа адреса |
Порядковый номер библиотеки устанавливается равным нулю, если символ является внешним или существует в текущем файле. Только неопределенные символы используют раздел информации о данных для указания порядкового номера библиотеки и параметров компоновщика.
Параметры флага динамического загрузчика следующие:
Двоичные цифры | Описание |
---|---|
xxxxxxxx0001xxxx | Должен быть установлен для любого определенного символа, на который ссылается динамический загрузчик. |
xxxxxxxx0010xxxx | Используется динамическим компоновщиком во время выполнения. |
xxxxxxxx0100xxxx | Если динамический компоновщик не может найти определение для этого символа, он устанавливает адрес этого символа равным 0. |
xxxxxxxx1000xxxx | Если статический или динамический компоновщик находит другое определение для этого символа, это определение игнорируется. |
Можно установить любую из 4 применимых опций.
Значения опции типа адреса следующие:
Двоичные цифры | Описание |
---|---|
xxxxxxxxxxxx0000 | Вызов метода неленивого загруженного указателя |
xxxxxxxxxxxx0001 | Вызов метода указателя с отложенной загрузкой |
xxxxxxxxxxxx0010 | Вызов метода, определенный в этой библиотеке/программе |
xxxxxxxxxxxx0011 | Вызов частного метода, определенный в этой библиотеке/программе |
xxxxxxxxxxxx0100 | Вызов метода частного неленивого загруженного указателя |
xxxxxxxxxxxx0101 | Вызов метода частного ленивого загруженного указателя |
По значению можно задать только одно значение типа адреса. Указатель — это значение, которое считывается машинным кодом программы для вызова метода из другого двоичного файла. Частный означает, что другие программы не предназначены для чтения или вызова функций/методов, кроме самого двоичного файла. Ленивый означает, что указатель находится на dyld_stub_binder, который ищет символ, затем вызывает метод, а затем заменяет местоположение dyld_stub_binder местоположением символа. Любые дальнейшие вызовы, выполняемые из машинного кода в двоичном виде, теперь будут определять адрес символа и не будут вызывать dyld_stub_binder.
Организация таблицы символов [ править ]
Все записи таблицы символов хранятся в порядке их типа. Первыми считываются символы локальной отладки, если таковые имеются, затем частные символы, затем внешние символы и, наконец, неопределенные символы, которые ссылаются на другую таблицу двоичных символов, содержащую адрес внешнего символа в другом двоичном файле Mach-O.
Команда загрузки информации таблицы символов 0x0000000B
всегда существует, если в двоичном файле Mach-O есть раздел таблицы символов. Команда сообщает компоновщику, сколько существует локальных символов, сколько частных, сколько внешних и сколько неопределенных. Он также определяет номер символа, с которого они начинаются. Информация таблицы символов используется динамическим компоновщиком перед чтением записей символов, поскольку она сообщает динамическому компоновщику, с чего начать чтение символов для загрузки неопределенных символов и с чего начать чтение для поиска совпадающих внешних символов без необходимости читать весь символ. записи.
Порядок расположения символов в разделе символов никогда не должен меняться, поскольку каждый символ нумеруется с нуля. Команда информации о таблице символов использует номера символов для загрузки неопределенных символов в разделы-заглушки и указатели. Изменение порядка приведет к вызову неправильного метода во время выполнения машинного кода.
__LINKEDIT Информация о таблице символов [ редактировать ]
Команда информации о таблице символов используется динамическим компоновщиком, чтобы узнать, где читать записи таблицы символов под командой таблицы символов. 0x00000002
, для быстрого поиска неопределенных символов и внешних символов во время связывания.
Команда читается следующим образом:
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x0000000B (Тип команды) |
4 | 4 | Размер команды (всегда 80) |
8 | 4 | Индекс локального символа |
12 | 4 | Количество местных символов |
16 | 4 | Индекс внешних символов |
20 | 4 | Количество внешних символов |
24 | 4 | Индекс неопределенных символов |
28 | 4 | Количество неопределенных символов |
32 | 4 | Смещение таблицы содержимого |
36 | 4 | Количество записей таблицы содержимого |
40 | 4 | Смещение таблицы модуля |
44 | 4 | Количество записей в таблице модулей |
48 | 4 | Смещение к таблице ссылочных символов |
52 | 4 | Количество записей в таблице ссылочных символов |
56 | 4 | Косвенное смещение таблицы символов |
60 | 4 | Записи таблицы косвенных символов |
64 | 4 | Смещение внешнего перемещения |
68 | 4 | Количество записей о внешнем перемещении |
72 | 4 | Смещение местного переезда |
76 | 4 | Количество записей о локальном перемещении |
Индекс символа умножается на 12 для 32-битного Mach-O или на 16 для 64-битного Mach-O плюс смещение записей таблицы символов, чтобы найти смещение для чтения записей символов по индексу номера символа.
Индекс локального символа равен нулю, поскольку он находится в начале записей символов. Локальные символы используются для отладочной информации.
Количество локальных символов — это количество их, существующих после индекса символа.
Те же два свойства повторяются для внешних символов и неопределенных символов для быстрого чтения записей таблицы символов.
Существует небольшой разрыв в индексе/размере между локальными и внешними символами, если есть частные символы.
Любые нулевые смещения файлов не используются.
Косвенная таблица [ править ]
Загрузчик Mach-O записывает разделы указателя символа и разделы-заглушки символа во время команд загрузки сегмента. Они последовательно используются таблицей косвенных символов для загрузки вызовов методов. Достигнув конца раздела, мы переходим к следующему.
Смещение таблицы косвенных символов относится к набору 32-битных (4-байтовых) значений, которые используются в качестве индекса номера символа.
Порядок нумерации индексов символов — это порядок, в котором мы записываем каждый адрес символа один за другим в разделах указателя и заглушки.
Раздел заглушки символа содержит инструкции машинного кода с инструкциями JUMP по косвенному адресу символа для вызова метода/функции из другого двоичного файла Mach-O. Размер каждой инструкции JUMP зависит от типа процессора и хранится в значении зарезервировано2 в разделе 32/64 команды загрузки сегмента.
Разделы указателей представляют собой 32-битные (4-байтовые) значения адреса для 32-битных двоичных файлов Mach-O и 64-битные (8-байтовые) значения адреса для 64-битных двоичных файлов Mach-O. Указатели считываются машинным кодом, и считанное значение используется в качестве места для вызова метода/функции, а не содержит инструкций машинного кода.
Индексный номер символа 0x40000000
набор битов — это абсолютные методы, означающие, что указатель указывает на точный адрес метода.
Индексный номер символа 0x80000000
набор битов — это локальные методы, что означает, что сам указатель находится на методе и что имя метода отсутствует (локальный метод).
Если вы разрабатываете дизассемблер, вы можете легко сопоставить только имя символа с адресом смещения каждой заглушки и указателя, чтобы показать происходящий вызов метода или функции, не ища местоположение неопределенного адреса символа в других файлах Mach-O.
__LINKEDIT Сжатая таблица [ изменить ]
Если существует команда редактирования таблицы сжатых ссылок, то неопределенные/внешние символы в таблице символов больше не нужны. Таблица косвенных символов и расположение заглушек и разделов указателей больше не требуются.
Таблица косвенных символов по-прежнему существует в случае создания обратно совместимых файлов Mach-O, которые загружаются в более новых и старых версиях ОС.
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x00000022 (Тип команды) |
4 | 4 | Размер команды (всегда 48 байт) |
8 | 4 | Перебазировать смещение файла |
12 | 4 | Размер перебазирования |
16 | 4 | Смещение файла привязки |
20 | 4 | Размер привязки |
24 | 4 | Слабое смещение файла привязки |
28 | 4 | Слабый размер привязки |
32 | 4 | Смещение файла ленивой привязки |
36 | 4 | Размер ленивой привязки |
40 | 4 | Смещение файла экспорта |
44 | 4 | Размер экспорта |
Любые смещения файлов, равные нулю, являются неиспользуемыми разделами.
Обязательная информация [ править ]
Разделы связывания, слабого связывания и отложенного связывания считываются с использованием одного и того же формата кода операции.
Первоначально таблица символов определяла тип адреса в поле информации о данных в таблице символов как ленивый, слабый или неленивый.
Слабая привязка означает, что если заданная библиотека для поиска по порядковому номеру библиотеки, а заданное имя символа не существует, но существует в другом ранее загруженном файле Mach-O, то местоположение символа используется из другого файла Mach-O.
Ленивый означает, что адрес, записанный в dyld_stub_binder, ищет символ, затем вызывает метод, а затем заменяет местоположение dyld_stub_binder местоположением символа. Любые дальнейшие вызовы, выполняемые из машинного кода в двоичном виде, теперь будут определять адрес символа и не будут вызывать dyld_stub_binder.
Обычный старый раздел связывания не выполняет каких-либо причудливых трюков с загрузкой или адресацией. Символ должен существовать в заданном порядковом номере библиотеки.
Значение байта, которое 0x1X
задает порядковый номер библиотеки ссылок. Шестнадцатеричная цифра X представляет собой порядковый номер библиотеки от 0 до 15.
Значение байта, которое 0x20
к 0x2F
устанавливает порядковый номер библиотеки ссылок на значение, которое читается после кода операции.
Последовательность байтов 0x20 0x84 0x01
установите порядковый номер 132.
Числовое значение после кода операции кодируется как число LEB128 . Последние 7 двоичных цифр складываются вместе, образуя большее число, если последняя двоичная цифра равна единице. Это позволяет нам кодировать числовые значения переменной длины.
Значение байта, которое 0x4X
задает имя символа. Шестнадцатеричная цифра, отмеченная X, устанавливает настройку флага.
Установка флага 8 означает, что метод слабо импортирован. Установка флага 1 означает, что метод не является слабым импортированным.
Последовательность байтов 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00
задает имя символа Пример. Последний байт текстового символа 0x00
. Он также слабо импортируется, то есть его можно заменить, если найден другой экспортируемый символ с тем же именем.
Значение байта 0x7X
устанавливает текущее местоположение. Шестнадцатеричная цифра, отмеченная X, представляет собой выбранный сегмент от 0 до 15. После кода операции добавляется смещение в виде числа LEB128 к смещению сегмента.
Последовательность байтов 0x72 0x8C 0x01
устанавливает местоположение в адрес команды загрузки третьего сегмента и добавляет к адресу 140.
Код операции 0x90
к 0x9F
привязывает текущее местоположение набора к имени набора символов и порядковому номеру библиотеки. Увеличивает текущее заданное местоположение на 4 байта для 32-битного двоичного файла Mach-O или увеличивает заданный адрес на 8 для 64-битного двоичного файла Mach-O.
Последовательность байтов 0x11 0x72 0x8C 0x01 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00 0x90 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x32 0x00 0x90
Устанавливает порядковый номер библиотеки ссылок 1. Устанавливает местоположение для сегмента номер 2 и добавляет 140 к текущему местоположению. Ищет символ с именем Пример в порядковом номере выбранной библиотеки. Код операции 0x90
записывает адрес символа и увеличивает текущий установленный адрес. Код операции после этого устанавливает следующее имя символа для поиска символа с именем Пример2. Код операции 0x90
записывает адрес символа и увеличивает текущий установленный адрес.
Новый формат удаляет повторяющиеся поля в таблице символов и делает таблицу косвенных символов устаревшей.
Основная точка входа приложения [ править ]
Команда загрузки, начинающаяся с типа 0x00000028
используется для указания адреса, с которого начинается приложение.
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x00000028 (Тип команды) |
4 | 4 | Размер команды (всегда 24 байта) |
8 | 8 | Местоположение адреса |
16 | 8 | Размер памяти стека |
Если для запуска сегменты/разделы программы не нужно перемещать, то основной точкой входа является точный адрес местоположения. Это происходит только в том случае, если адреса сегментов приложения добавляются к базовому адресу приложения, равному нулю, и разделы не требуют никаких перемещений.
Основной точкой входа в загрузчик Mach-O является базовый адрес программы плюс местоположение адреса. Это адрес, по которому ЦП должен начать выполнение инструкций машинного кода.
Это заменило старую команду загрузки 0x00000005
которое варьировалось в зависимости от типа ЦП, поскольку в нем сохранялось состояние, в котором должны находиться все регистры перед запуском программы.
Номер UUID приложения [ изменить ]
Команда загрузки, начинающаяся с типа 0x0000001B
используется для указания универсального уникального идентификатора (UUID) приложения.
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x0000001B (Тип команды) |
4 | 4 | Размер команды (всегда 24 байта) |
8 | 16 | 128-битный UUID |
UUID содержит 128-битный уникальный случайный идентификатор. [ нужна ссылка ] номер при компиляции приложения, который можно использовать для идентификации файла приложения в Интернете или в магазинах приложений.
Минимальная версия ОС [ править ]
Команда загрузки, начинающаяся с типа 0x00000032
используется для указания минимальной информации о версии ОС.
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | 0x00000032 (Тип команды) |
4 | 4 | Размер команды |
8 | 4 | Тип платформы |
12 | 4 | Минимальная версия ОС |
16 | 4 | Версия SDK |
20 | 4 | Количество используемых инструментов |
Тип платформы, на которой предназначен двоичный файл, следующий:
Ценить | Платформа |
---|---|
0x00000001 | macOS |
0x00000002 | iOS |
0x00000003 | ТВОС |
0x00000004 | WatchOS |
0x00000005 | мостОС |
0x00000006 | Mac Катализатор |
0x00000007 | iOS-симулятор |
0x00000008 | симулятор tvOS |
0x00000009 | симулятор watchOS |
0x0000000A | DriverKit |
0x0000000B | видениеOS |
0x0000000C | Симулятор VisionOS |
Значение 32-битной версии считывается как 16-битное значение и два 8-битных значения. Значение 32-битной версии 0x000D0200
ломается как 0x000D
значение которого равно 13, то следующие 8 бит равны 0x02
значение которого равно 2, то последние 8 бит равны 0x00
значение которого равно нулю, что дает номер версии 13.2.0v. Значение версии SDK читается таким же образом.
Набор инструментов для создания бинарника представляет собой набор записей, которые читаются следующим образом:
Компенсировать | Байты | Описание |
---|---|---|
0 | 4 | Тип инструмента |
4 | 4 | Тип одежды |
Значения типа инструмента следующие:
Ценить | Тип используемого инструмента |
---|---|
0x00000001 | КЛАНГ |
0x00000002 | БЫСТРЫЙ |
0x00000003 | ЛД |
Номер версии читается так же, как версия ОС и версия SDK.
С появлением платформы Mac OS X 10.6 файл Mach-O претерпел значительные изменения, в результате чего двоичные файлы, скомпилированные на компьютере под управлением версии 10.6 или более поздней версии, становятся (по умолчанию) исполняемыми только на компьютерах под управлением Mac OS X 10.6 или более поздней версии. Разница связана с командами загрузки, которые динамический компоновщик в предыдущих версиях Mac OS X не понимает. Еще одним существенным изменением формата Mach-O является изменение функционирования таблиц редактирования ссылок (находится в разделе __LINKEDIT). В версии 10.6 эти новые таблицы редактирования ссылок сжимаются путем удаления неиспользуемых и ненужных битов информации, однако Mac OS X 10.5 и более ранние версии не могут читать этот новый формат таблицы редактирования ссылок. Чтобы создать обратно совместимые исполняемые файлы, можно использовать флаг компоновщика «-mmacosx-version-min=".
Другие реализации [ править ]
Приложение Mach-O можно запускать в различных операционных системах или ОС, если существует двоичный образ Mach-O, соответствующий типу ядра вашего компьютера. Большинство настольных компьютеров являются x86, а это означает, что Mach-O с двоичным файлом x86 будет работать без проблем, если вы загрузите разделы в память. Если Mach-O предназначен для iPhone с ядром ARM, то для его запуска вам понадобится ПК с ядром ARM (не обязательно Apple Silicon ARM); в противном случае вам придется изменить инструкции в кодировке ARM на эквивалентные инструкции в кодировке x86. Проблема загрузки и непосредственного выполнения Mach-O заключается в неопределенных символах, которые вызывают функции/методы из других двоичных файлов Mach-O, которые не существуют в другой операционной системе. Некоторые символы могут вызывать другие эквивалентные функции в разных операционных системах или даже вызывать функции адаптера, чтобы вызовы других двоичных функций вели себя как эквиваленты macOS. Файлы Mach-O, хранящиеся на устройстве, могут различаться в зависимости от iPhone (iOS), macOS, watchOS и tvOS. Вызывают различия в вызовах функций из неопределенных символов.
В некоторые версии NetBSD была добавлена поддержка Mach-O как часть реализации двоичной совместимости, что позволило выполнять некоторые двоичные файлы Mac OS 10.3. [13] [14]
Для Linux загрузчик Mach-O написал Шиничиро Хамадзи. [15] который может загружать 10,6 двоичных файлов. более обширное решение, основанное на этом загрузчике, Проект Darling Project, направлен на создание полноценной среды, позволяющей запускать приложения macOS в Linux.
Для языка программирования Ruby руби-мачо [16] Библиотека предоставляет реализацию двоичного анализатора и редактора Mach-O.
См. также [ править ]
- Жирный двоичный файл
- Универсальный двоичный файл
- Динамический компоновщик
- Переход Mac на процессоры Intel
- Переход Mac на Apple Silicon
- Xcode
- ЭЛЬФ
- Сравнение форматов исполняемых файлов
Ссылки [ править ]
- ^ «Справочник по формату файлов OS X ABI Mach-O» . Apple Inc., 4 февраля 2009 г. Архивировано из оригинала 4 сентября 2014 г.
- ^ Авадис Теванян-младший; Ричард Ф. Рашид; Майкл В. Янг; Дэвид Б. Голуб; Мэри Р. Томпсон; Уильям Болоски; Ричард Санзи (июнь 1987 г.). «Интерфейс Unix для общей памяти и файлов, отображенных в памяти под Mach» . Материалы летней конференции USENIX . Финикс, Аризона, США: Ассоциация USENIX}. стр. 53–67.
- ^ Jump up to: Перейти обратно: а б «Типы данных» . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ loader.h на GitHub
- ^ Jump up to: Перейти обратно: а б с Machine.h на GitHub
- ^ «Универсальные двоичные файлы и 32-битные/64-битные двоичные файлы PowerPC» . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ «Создание универсального двоичного файла macOS» . Разработчик Apple .
- ^ "фат_заголовок" . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ "fat_arch" . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ «Загрузка структур данных команды» . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ "команда_сегмента" . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ "segment_command_64" . Справочник по форматам файлов OS X ABI Mach-O . Apple Inc. , 4 февраля 2009 г. [2003 г.]. Архивировано из оригинала 4 сентября 2014 года.
- ^ Эммануэль Дрейфус (20 июня 2006 г.). «Двоичная совместимость Маха и Дарвина [ sic ] для NetBSD/powerpc и NetBSD/i386» . Проверено 18 октября 2013 г.
- ^ Эммануэль Дрейфус (сентябрь 2004 г.), Бинарная совместимость Mac OS X в NetBSD: проблемы и реализация (PDF)
- ^ Шиничиро Хамадзи, загрузчик Mach-O для Linux — я написал...
- ^ Уильям Вудрафф (15 ноября 2021 г.). Библиотека на чистом Ruby для анализа файлов Mach-O.
Библиография [ править ]
- Левин, Джонатан (25 сентября 2019 г.). * Внутреннее устройство ОС, Том 1: Пользовательский режим (изд. v1.3.3.7). Норт-Касл, Нью-Йорк: Technologieks. ISBN 978-0-9910555-6-2 .
- Сингх, Амит (19 июня 2006 г.). Внутреннее устройство Mac OS X: системный подход . Аддисон-Уэсли Профессионал. ISBN 978-0-13-270226-3 .
Внешние ссылки [ править ]
- Справочник по форматам файлов OS X ABI Mach-O (Apple Inc.)
- Darwin и macOS по форматам файлов Руководство –
- Объектные файлы Mach (документация NEXTSTEP)
- Справочник по динамической библиотеке Mach-O
- Трюки с связыванием и загрузкой Mach-O
- MachOView
- JDasm (кросс-платформенный дизассемблер для macOS, iOS, Windows PE, ELF и инструмент анализа форматов файлов)