Portable Executable - (PE, вимовляється як [потебл екзекьютебл] - переносимий виконуваний) - формат виконуваних файлів, об'єктного коду та динамічних бібліотек, використовуваний в 32 - і 64-бітових версіях операційної системи Microsoft Windows. Формат PE являє собою структуру даних, що містить всю інформацію, необхідну PE завантажувачу для проеціювання файлу в пам'ять. Виконуваний код включає в себе посилання для зв'язування динамічно завантажуваних бібліотек, таблиці експорту та імпорту API функцій, дані для управління ресурсами і дані локальної пам'яті потоку (TLS). В операційних системах сімейства Windows NT формат PE використовується для EXE, DLL, SYS (драйверів пристроїв), та інших типів виконуваних файлів.

PE являє собою модифіковану версію COFF формату файлу для Unix. PE / COFF - альтернативний термін при розробці Windows.

На операційних системах сімейства Windows NT формат PE зараз підтримує наступні архітектури наборів команд : IA-32, IA-64, і x86-64 (AMD64/Intel64). До Windows 2000 Windows NT (таким чином, і PE) підтримував MIPS, Alpha, і PowerPC. Оскільки PE використовується на Windows CE, він продовжує підтримувати декілька різновидів MIPS, ARM (включаючи Thumb), і SuperH.

Основні "конкуренти" PE - ELF (використовуваний в Linux і більшості інших версій Unix) і Mach-O (використовуваний в Mac OS X).


1. Коротка історія

З появою операційної системи Windows NT 3.1 Microsoft перейшла на формат PE. Все більш пізні версії Windows, включаючи Windows 95/98/ME, підтримують цей формат. Формат зберіг обмежену підтримку існуючого ( MZ) для подолання розриву між системами, заснованими на DOS, і системами NT. Наприклад, заголовки PE / COFF все ще включають виконувану програму MS-DOS, яка за замовчуванням є заглушкою, яка виводить на екран просте повідомлення "This program cannot be run in DOS mode" - "Ця програма не може бути виконана в режимі DOS" (або подібне). PE продовжує служити змінюється платформі Windows. Деякі розширення включають формат PE.NET (див. нижче), 64-розрядну версію під назвою PE32 + (іноді PE +), і специфікацію для Windows CE.


2. Технічні деталі

2.1. Розташування

Файл PE складається з декількох заголовків і секцій, які вказують динамічному компонувальнику, як відображати файл у пам'ять. Виконуваний образ складається з декількох різних областей (секцій), кожна з яких вимагає різних прав доступу до пам'яті; таким чином, початок кожної секції має бути вирівняні по межі сторінки. Наприклад, зазвичай секція. Text, яка містить код програми, відображена як співається / доступна тільки для читання, і секція. Data, містить глобальні змінні, відображена як неісполняемимі / доступна для читання і запису. Однак, щоб не витрачати даремно простір на жорсткому диску, різні секції на ньому на межу сторінки не вирівняні. Частина роботи динамічного компонувальника полягає в тому, щоб відобразити кожну секцію в пам'ять окремо і привласнити коректні права доступу получившимся областям згідно із вказівками, що містяться в заголовках.


2.2. Таблиця імпорту

Одна з відомих секцій - таблиця адрес імпорту (IAT - Import Address Table), яка використовується в якості таблиці пошуку, коли додаток викликає функцію з іншого модуля. Це може бути зроблено і в формі імпорту за порядковим номером функції (ordinal), і імпорту по її імені. Оскільки скомпілювати програму невідомо розташування бібліотек, від яких вона залежить, то потрібно проводити непрямий перехід всякий раз, коли відбувається виклик API функції. Коли динамічний компонувальник завантажує модулі і об'єднує їх, він записує дійсні адреси в область IAT так, щоб вони вказали на комірки пам'яті відповідних бібліотечних функцій. Хоча це додає додатковий перехід всередині модуля, що приводить до втрати продуктивності, це надає ключова перевага: кількість сторінок пам'яті, які повинні бути скопійовані завантажувачем при записі, мінімізовано, що призводить до економії пам'яті і дискового часу введення-виведення. Якщо компілятору буде відомо заздалегідь, що виклик буде міжмодульних (через атрибут dllimport), то він зможе зробити більше оптимізований код, який просто призводить до коду операції непрямого виклику.


2.3. Переміщення

Файли PE не містять позиційно-незалежного коду. Замість цього вони скомпільовані для кращого базової адреси, і всі адреси, що генеруються компілятором / компоновщиком, заздалегідь фіксовані. Якщо PE файл не може бути завантажений за своїм кращого адресою (тому що він вже зайнятий чимось ще), операційна система буде перебазувати його. Це включає в себе перевичісленіе кожного абсолютного адреси і зміна коду для того, щоб використовувати нові значення. Завантажувач робить це, порівнюючи переважний і фактична адреси завантаження, і обчислюючи значення різниці. Тоді для отримання нової адреси комірки пам'яті ця різниця складається з переважним адресою. Базові адреси переміщень зберігаються в списку і при необхідності додаються до існуючої комірці пам'яті. Отриманий код є тепер окремим по відношенню до процесу і не є більше поділюваним, так що при такому способі втрачаються багато з переваг економії пам'яті динамічно завантажуваних бібліотек. Такий спосіб також значно уповільнює завантаження модуля. З цієї причини слід уникати перебазування скрізь, де це можливо; наприклад, бібліотеки, що поставляються Microsoft, мають попередньо обчислені неперекривающіеся базові адреси. У випадку відсутності необхідності перебазування PE файли мають перевагу дуже ефективного коду, але при наявності перебазування витрати в використання пам'яті можуть бути значними. Це відрізняє формат PE від ELF, який використовує повністю позиційно-незалежний код і глобальну таблицю зміщень, яка жертвує часом виконання на користь витрачання пам'яті.


3. . NET, метадані, і PE формат

Платформа. NET корпорації Microsoft розширила формат PE за допомогою функцій, які підтримують загальномовного середовища виконання (Common Language Runtime - CLR). Серед доповнень - заголовок CLR і секція даних CLR. Після завантаження двійкового файлу завантажувач ОС приводить до виконання CLR через посилання в таблиці імпорту PE / COFF. Потім CLR завантажує заголовок CLR і секції даних.

Секція даних CLR містить два важливих сегменти: сегмент метаданих і сегмент коду проміжного мови (IL):

  • Метадані містять інформацію, що відноситься до збірки, включаючи маніфест збірки. Маніфест докладно описує збірку, включаючи унікальний ідентифікатор (за допомогою хешу, номера версії, і т.д.), дані про експортованих компонентах, розширену інформацію про тип (підтримувану загальною системою типів (Common Type System - CTS)), зовнішні посилання, і список файлів в збірці. Середа CLR широко використовує метадані.
  • Код проміжного мови (Intermediate Language - IL) - абстрактний, незалежний від мови код, який задовольняє вимогам загального проміжного мови (Common Intermediate Language - CIL). NET CLR. Термін "проміжний" відноситься до природи коду IL, володіє міжмовної і кроссплатформенной сумісністю. Цей проміжний мову, подібний байт-коду Java, дозволяє платформам і мовам підтримувати загальну середу. NET CLR. IL підтримує об'єктно-орієнтоване програмування (поліморфізм, успадкування, абстрактні типи, і т.д.), виключення, події, і різні структури даних.

4. Використання в інших операційних системах

Формат PE також використовується ReactOS, оскільки ReactOS призначена для того, щоб бути двійково сумісної з Windows на рівні коду. Крім того, він історично використовувався багатьма іншими операційними системами, включаючи SkyOS і BeOS R3. Однак, і SkyOS, і BeOS в кінцевому рахунку перейшли на формат ELF.

Оскільки платформа розробки Mono намір бути двійково сумісної з Microsoft. NET, вона використовує той же формат PE, що і в реалізації Microsoft.

На платформі x86 в Unix-подібних операційних системах, деякі двійкові файли Windows (у форматі PE) можуть бути виконані за допомогою Wine. HX DOS Extender також використовує формат PE для власних 32-розрядних двійкових файлів DOS, крім того, може в деякій мірі виконати існуючі двійкові файли Windows в DOS, діючи, таким чином, як Wine для DOS.

Mac OS X 10.5 має можливість завантажувати і інтерпретувати PE файли, однак вони не є двійково сумісними з Windows.