Формат Portable Executable (PE) - это формат файла для исполняемых файлов , объектного кода , DLL и других файлов, используемых в 32-битных и 64-битных версиях операционных систем Windows . Формат PE - это структура данных, которая инкапсулирует информацию, необходимую загрузчику ОС Windows для управления обернутым исполняемым кодом . Сюда входят ссылки на динамические библиотеки для связывания , таблицы экспорта и импорта API , данные управления ресурсами и данные локального хранилища потоков (TLS). В операционных системах NT формат PE используется для EXE ,DLL , SYS ( драйвер устройства ), MUI и другие типы файлов. В спецификации Unified Extensible Firmware Interface (UEFI) указано, что PE является стандартным исполняемым форматом в средах EFI. [2]
Расширение имени файла | .acm , .ax , .cpl , .dll , .drv , .efi , .exe , .mui , .ocx , .scr , .sys , .tsp |
---|---|
Тип интернет-СМИ | приложение / vnd.microsoft.portable-исполняемый файл [1] |
Разработано | В настоящее время: Microsoft |
Тип формата | Двоичные , исполняемые , объектные , разделяемые библиотеки |
Расширен с | Исполняемый файл DOS MZ COFF |
В операционных системах Windows NT PE в настоящее время поддерживает архитектуры набора команд (ISA) x86-32 , x86-64 (AMD64 / Intel 64), IA-64 , ARM и ARM64 . До Windows 2000 Windows NT (и, следовательно, PE) поддерживала ISA MIPS , Alpha и PowerPC . Поскольку PE используется в Windows CE , он продолжает поддерживать несколько вариантов MIPS, ARM (включая Thumb ) и SuperH ISA. [3]
Аналогичные форматы для PE - это ELF (используется в Linux и большинстве других версий Unix ) и Mach-O (используется в macOS и iOS ).
История
Microsoft перешла на формат PE из 16-битных форматов NE с появлением операционной системы Windows NT 3.1 . Все более поздние версии Windows, включая Windows 95/98 / ME и Win32s в дополнение к Windows 3.1x, поддерживают файловую структуру. Формат сохранил ограниченную устаревшую поддержку для преодоления разрыва между системами на базе DOS и NT. Например, заголовки PE / COFF по-прежнему включают исполняемую программу DOS , которая по умолчанию является заглушкой DOS , отображающей сообщение типа «Эта программа не может быть запущена в режиме DOS» (или подобное), хотя это может быть полноценная DOS. версия программы (более поздний известный случай - установщик Windows 98 SE). [4] Это форма двоичного кода . PE также продолжает обслуживать меняющуюся платформу Windows. Некоторые расширения включают формат .NET PE (см. Ниже), 64-разрядную версию PE32 + (иногда PE +) и спецификацию для Windows CE.
Технические подробности
Макет
PE-файл состоит из ряда заголовков и разделов, которые сообщают динамическому компоновщику, как отображать файл в память. Исполняемый образ состоит из нескольких различных областей, каждая из которых требует разной защиты памяти; поэтому начало каждого раздела должно быть выровнено по границе страницы. [5] Например, обычно секция .text (которая содержит программный код) отображается как выполнение / только для чтения, а секция .data (содержащая глобальные переменные) отображается как без выполнения / чтения-записи. Однако, чтобы не тратить лишнее место, разные разделы на диске не выравниваются по страницам. Частью работы динамического компоновщика является сопоставление каждого раздела с памятью отдельно и назначение правильных разрешений для результирующих областей в соответствии с инструкциями, содержащимися в заголовках. [6]
Таблица импорта
Следует отметить, что таблица адресов импорта (IAT) используется в качестве справочной таблицы, когда приложение вызывает функцию в другом модуле. Это может быть как импорт по порядковому номеру, так и импорт по имени . Поскольку скомпилированная программа не может знать расположение в памяти библиотек, от которых она зависит, при каждом вызове API требуется косвенный переход. Когда динамический компоновщик загружает модули и объединяет их вместе, он записывает фактические адреса в слоты IAT, чтобы они указывали на ячейки памяти соответствующих библиотечных функций. Хотя это добавляет дополнительный скачок к стоимости внутримодульного вызова, что приводит к снижению производительности, это дает ключевое преимущество: количество страниц памяти, которые должны быть изменены загрузчиком при копировании при записи, минимизировано, что позволяет экономить память. и время дискового ввода-вывода. Если компилятор заранее знает, что вызов будет межмодульным (через атрибут dllimport), он может создать более оптимизированный код, который просто приведет к коду операции косвенного вызова . [6]
Переезды
Файлы PE обычно не содержат независимого от позиции кода . Вместо этого они компилируются в предпочтительный базовый адрес , и все адреса, выдаваемые компилятором / компоновщиком, фиксируются заранее. Если PE-файл не может быть загружен по его предпочтительному адресу (потому что он уже занят чем-то другим), операционная система перебазирует его. Это включает в себя пересчет каждого абсолютного адреса и изменение кода для использования новых значений. Загрузчик делает это, сравнивая предпочтительный и фактический адреса загрузки и вычисляя значение дельты . Затем он добавляется к предпочтительному адресу, чтобы получить новый адрес ячейки памяти. Базовые перемещения сохраняются в списке и при необходимости добавляются в существующую ячейку памяти. Результирующий код теперь является частным для процесса и больше не доступен для совместного использования , поэтому многие преимущества экономии памяти DLL теряются в этом сценарии. Это также значительно замедляет загрузку модуля. По этой причине по возможности следует избегать перебазирования, а библиотеки DLL, поставляемые Microsoft, имеют предварительно вычисленные базовые адреса, чтобы не перекрываться. Таким образом, в случае отсутствия перебазирования PE имеет преимущество в виде очень эффективного кода, но при наличии перебазирования использование памяти может быть дорогостоящим. Это контрастирует с ELF, который использует полностью независимый от позиции код и глобальную таблицу смещений, в которой время выполнения сокращается в пользу более низкого использования памяти.
.NET, метаданные и формат PE
В исполняемом файле .NET раздел кода PE содержит заглушку, которая вызывает запись запуска виртуальной машины CLR , _CorExeMain или _CorDllMain в mscoree.dll , как это было в исполняемых файлах Visual Basic . Затем виртуальная машина использует имеющиеся метаданные .NET, на корень которых, IMAGE_COR20_HEADER (также называемый «заголовком CLR»), указывает запись IMAGE_DIRECTORY_ENTRY_COMHEADER
[7] в каталоге данных PE-заголовка. IMAGE_COR20_HEADER сильно напоминает необязательный заголовок PE, по сути, играя свою роль для загрузчика CLR. [3]
Данные, связанные с CLR, включая саму корневую структуру, обычно содержатся в разделе общего кода, .text . Он состоит из нескольких каталогов: метаданных, встроенных ресурсов, строгих имен и нескольких каталогов для взаимодействия с собственным кодом. Каталог метаданных - это набор таблиц, в которых перечислены все отдельные сущности .NET в сборке, включая типы, методы, поля, константы, события, а также ссылки между ними и другими сборками.
Использование в других операционных системах
Формат PE также используется ReactOS , поскольку ReactOS предназначена для двоичной совместимости с Windows. Исторически он также использовался рядом других операционных систем, включая SkyOS и BeOS R3. Однако и SkyOS, и BeOS в конечном итоге перешли на ELF . [ необходима цитата ]
Поскольку платформа разработки Mono должна быть двоично-совместимой с Microsoft .NET Framework , она использует тот же формат PE, что и реализация Microsoft. То же самое и с кроссплатформенным .NET Core от Microsoft .
В Unix-подобных операционных системах x86 (-64) двоичные файлы Windows (в формате PE) могут выполняться с Wine . HX DOS Extender также использует формат PE для нативных DOS 32-разрядных двоичных файлов, а также он может, до некоторой степени, выполнять существующие двоичные файлы Windows , в DOS, таким образом , действует как эквивалент Wine для DOS.
В IA-32 и x86-64 Linux также можно запускать библиотеки DLL Windows из loadlibrary. [8]
В Mac OS X 10.5 есть возможность загружать и анализировать PE-файлы, но она не совместима с Windows на двоичном уровне. [9]
Микропрограммы UEFI и EFI используют переносимые исполняемые файлы, а также соглашение о вызовах Windows ABI x64 для приложений .
Смотрите также
- EXE
- Исполняемый и связываемый формат
- Мачо
- а. выход
- Сравнение форматов исполняемых файлов
- Исполняемое сжатие
- ar (Unix), поскольку все библиотеки COFF используют тот же формат
- Виртуализация приложений
Рекомендации
- ^ Андерссон, Хенрик (2015-04-23). "приложение / vnd.microsoft.portable-исполняемый файл" . IANA . Проверено 26 марта 2017 .
- ^ «Спецификация UEFI, версия 2.8B» (PDF) .в примечании на стр. 15 говорится, что «этот тип изображения выбран, чтобы разрешить изображениям UEFI содержать инструкции Thumb и Thumb2, при этом сами интерфейсы EFI определены как находящиеся в режиме ARM».
- ^ а б «Формат PE (Windows)» . Проверено 21 октября 2017 .
- ^ Например, компоновщик Microsoft имеет переключатель / STUB для присоединения одного
- ^ «Переносимый исполняемый файл сверху вниз» . Проверено 21 октября 2017 .
- ^ а б «Пиринг внутри PE: обзор переносимого исполняемого файла Win32» . Проверено 21 октября 2017 .
- ^ Запись была ранее использована для COM + метаданных в COM + приложений, отсюда и название
- ^ https://github.com/taviso/loadlibrary
- ^ Шартье, Дэвид (30 ноября 2007 г.). «Обнаружено: свидетельство того, что Mac OS X скоро сможет запускать приложения для Windows» . Ars Technica . Проверено 3 декабря 2007 .
... Стивен Эдвардс описывает открытие, что Leopard, по-видимому, содержит недокументированный загрузчик для Portable Executables, типа файла, используемого в 32-битных и 64-битных версиях Windows. Дальнейшие поиски показали, что собственный загрузчик Leopard пытается найти файлы DLL Windows при попытке загрузить двоичный файл Windows.
Внешние ссылки
- Формат PE (последний онлайн-документ)
- Спецификация формата переносимых исполняемых файлов и общих объектных файлов Microsoft (версия 8.1, формат OOXML )
- Спецификация формата переносимых исполняемых файлов и общих объектных файлов Microsoft (версия 6.0, формат .doc )
- Оригинальная статья о Portable Executable, написанная Мэттом Пьетреком ( MSDN Magazine, март 1994 г.)
- Часть I. Углубленный взгляд на формат переносимых исполняемых файлов Win32 , Мэтт Пьетрек ( журнал MSDN , февраль 2002 г.)
- Часть II. Углубленный взгляд на формат переносимых исполняемых файлов Win32 , Мэтт Питрек ( журнал MSDN , март 2002 г.)
- Формат файлов .NET, Даниэль Пистелли
- Блог Эро Карреры, описывающий заголовок PE и как пройти
- PE Internals предоставляет простой способ изучить Portable Executable File Format