Переносимый исполняемый файл - Portable Executable

Переносимый исполняемый файл
Расширение имени файла
.acm, .ax, .cpl, .dll, .drv, .efi, .exe, .mui, .ocx, .scr, .sys,.tsp
Тип интернет-СМИ
приложение / vnd.microsoft.portable-исполняемый
Разработан В настоящее время: Microsoft
Тип формата Двоичные , исполняемые , объектные , разделяемые библиотеки
Расширен с Исполняемый файл DOS MZ
COFF

Формат Portable Executable (PE) - это формат файла для исполняемых файлов , объектного кода , DLL и других файлов, используемых в 32-битных и 64-битных версиях операционных систем Windows . Формат PE - это структура данных, которая инкапсулирует информацию, необходимую загрузчику ОС Windows для управления обернутым исполняемым кодом . Сюда входят ссылки на динамические библиотеки для связывания , таблицы экспорта и импорта API , данные управления ресурсами и данные локального хранилища потоков (TLS). В операционных системах NT формат PE используется для файлов EXE , DLL , SYS ( драйвер устройства ), MUI и других типов файлов. В спецификации Unified Extensible Firmware Interface (UEFI) указано, что PE является стандартным исполняемым форматом в средах EFI.

В операционных системах 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.

Аналогичные форматы для 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). Это одна из форм двоичного кода . PE также продолжает обслуживать меняющуюся платформу Windows. Некоторые расширения включают формат .NET PE (см. Ниже), 64-разрядную версию PE32 + (иногда PE +) и спецификацию для Windows CE.

Технические детали

Макет

Структура переносимого исполняемого 32-битного файла

PE-файл состоит из ряда заголовков и разделов, которые сообщают динамическому компоновщику, как отображать файл в память. Исполняемый образ состоит из нескольких различных областей, каждая из которых требует разной защиты памяти; поэтому начало каждого раздела должно быть выровнено по границе страницы. Например, обычно секция .text (которая содержит программный код) отображается как выполнение / только для чтения, а секция .data (содержащая глобальные переменные) отображается как без выполнения / чтения-записи. Однако, чтобы не тратить лишнее место, разные разделы на диске не выравниваются по страницам. Частью работы динамического компоновщика является сопоставление каждого раздела с памятью индивидуально и назначение правильных разрешений для результирующих областей в соответствии с инструкциями, содержащимися в заголовках.

Таблица импорта

Следует отметить, что таблица адресов импорта (IAT) используется в качестве справочной таблицы, когда приложение вызывает функцию в другом модуле. Это может быть как импорт по порядковому номеру, так и импорт по имени . Поскольку скомпилированная программа не может знать расположение в памяти библиотек, от которых она зависит, при каждом вызове API требуется косвенный переход. Когда динамический компоновщик загружает модули и объединяет их вместе, он записывает фактические адреса в слоты IAT, чтобы они указывали на ячейки памяти соответствующих библиотечных функций. Хотя это добавляет дополнительный скачок к стоимости внутримодульного вызова, что приводит к снижению производительности, это дает ключевое преимущество: количество страниц памяти, которые должны быть изменены загрузчиком при копировании при записи, минимизировано, что позволяет экономить память. и время дискового ввода-вывода. Если компилятор заранее знает, что вызов будет межмодульным (через атрибут dllimport), он может создать более оптимизированный код, который просто приведет к коду операции косвенного вызова .

Переезды

Файлы PE обычно не содержат независимого от позиции кода . Вместо этого они компилируются в предпочтительный базовый адрес , и все адреса, выдаваемые компилятором / компоновщиком, фиксируются заранее. Если PE-файл не может быть загружен по его предпочтительному адресу (потому что он уже занят чем-то другим), операционная система перебазирует его. Это включает в себя пересчет каждого абсолютного адреса и изменение кода для использования новых значений. Загрузчик делает это, сравнивая предпочтительный и фактический адреса загрузки и вычисляя значение дельты . Затем он добавляется к предпочтительному адресу, чтобы получить новый адрес ячейки памяти. Базовые перемещения сохраняются в списке и при необходимости добавляются в существующую ячейку памяти. Результирующий код теперь является частным для процесса и больше не доступен для совместного использования , поэтому многие преимущества экономии памяти DLL теряются в этом сценарии. Это также значительно замедляет загрузку модуля. По этой причине по возможности следует избегать перебазирования, а библиотеки DLL, поставляемые Microsoft, имеют предварительно вычисленные базовые адреса, чтобы не перекрываться. Таким образом, в случае отсутствия перебазирования PE имеет преимущество в виде очень эффективного кода, но при наличии перебазирования использование памяти может быть дорогостоящим. Это контрастирует с ELF, который использует полностью независимый от позиции код и глобальную таблицу смещений, которая жертвует временем выполнения в пользу меньшего использования памяти.

.NET, метаданные и формат PE

В исполняемом файле .NET раздел кода PE содержит заглушку, которая вызывает запись запуска виртуальной машины CLR_CorExeMain или _CorDllMainin mscoree.dll, как это было в исполняемых файлах Visual Basic . Затем виртуальная машина использует имеющиеся метаданные .NET, на корень которых IMAGE_COR20_HEADER(также называемый «заголовком CLR») указывает IMAGE_DIRECTORY_ENTRY_COMHEADERзапись в каталоге данных PE-заголовка. IMAGE_COR20_HEADERсильно напоминает необязательный заголовок PE, по сути, играя свою роль для загрузчика CLR.

Данные , связанные с 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.

В Mac OS X 10.5 есть возможность загружать и анализировать PE-файлы, но она не совместима с Windows на двоичном уровне.

Микропрограммы UEFI и EFI используют переносимые исполняемые файлы, а также соглашение о вызовах Windows ABI x64 для приложений .

Смотрите также

использованная литература

внешние ссылки