Portable Executable
Розширення: | .exe , .dll , .sys , .scr , .drv , .efi , .acm , .ax , .mui або .tsp ![]() |
---|---|
MIME-тип: | application/vnd.microsoft.portable-executable[1] і application/efi[2] ![]() |
Формат Portable Executable ( PE ) — це формат файлів для виконуваних файлів, об’єктного коду, бібліотек динамічного компонування (DLL) і двійкових файлів, які використовуються в 32-розрядних і 64-розрядних операційних системах Windows, а також у середовищах UEFI . [3] Це стандартний формат для бінарних програмних файлів у системах на базі Windows NT: виконуваних програм (.exe
), динамічних бібліотек (.dll
), системних драйверів (.sys
), .mui
. За своєю суттю формат PE є структурованим контейнером даних, який надає завантажувачу операційної системи Windows усе необхідне для належного керування виконуваним кодом, який він містить. Контейнер може містити посилання для динамічно пов’язаних бібліотек, таблиці для імпорту та експорту API, дані керування ресурсами та інформації про локальне сховище потоків (TLS).
Відповідно до специфікації Unified Extensible Firmware Interface (UEFI), формат PE також є прийнятним стандартом для виконуваних файлів у середовищах EFI. [4] У системах Windows NT він підтримує набори інструкцій IA-32, x86-64 (AMD64/Intel 64), IA-64, ARM і ARM64. Старіші версії Windows NT, що могли працювати на архітерктурах MIPS, DEC Alpha і PowerPC, також використовували формат PE. Крім того, завдяки використанню в Windows CE PE зберіг сумісність із декількома варіантами MIPS, ARM (включно з ARM Thumb) і SuperH.[5]
Функціонально формат PE подібний до інших форматів виконуваних файлів для певної платформи, таких як формат ELF, який використовується в Linux і більшості Unix-подібних систем, а також формат Mach-O, який існує в macOS і iOS .
Корпорація Microsoft вперше представила формат PE у Windows NT 3.1, замінивши старий 16-розрядний формат New Executable (NE). Незабаром після цього Windows 95, 98, ME та розширення Win32s для Windows 3.1x прийняли структуру PE. Кожен PE-файл містить заголовок виконуваного файлу DOS, який зазвичай відображає повідомлення « Цю програму неможливо запустити в режимі DOS ». Однак цей розділ DOS можна замінити повнофункціональною програмою DOS, як показано в інсталяторі Windows 98 SE. Розробники можуть додати таку програму за допомогою параметра /STUB
із компонувальником Microsoft, фактично створюючи так званий «жирний двійковий файл» (англ. fat binary).[6]
З часом формат PE розширився разом із платформою Windows. Відомими розширеннями є .NET PE для керованого коду, PE32+ для підтримки 64-розрядного адресного простору та спеціалізована версія для Windows CE .
Щоб визначити, чи PE-файл призначений для 32-розрядної чи 64-розрядної архітектури, можна перевірити поле Machine в IMAGE_FILE_HEADER
. Загальними машинними значеннями є 0x014c
для 32-розрядних процесорів Intel і 0x8664
для процесорів x86_64. Крім того, поле Magic в IMAGE_OPTIONAL_HEADER
показує, чи є адреси 32-бітними чи 64-бітними. Значення 0x10B
вказує на 32-розрядний (PE32) файл, тоді як 0x20B
вказує на 64-розрядний (PE32+) файл.
Файл PE складається з кількох заголовків і розділів, які вказують динамічному компонувальнику, як відобразити файл у пам’яті. Виконуваний образ складається з кількох різних областей, кожна з яких потребує різних атрибутів захисту пам’яті. Щоб забезпечити правильне вирівнювання, початок кожного розділу має бути вирівняно за межею сторінки. [7] Наприклад, розділ .text, який містить програмний код, зазвичай відображається як виконання/лише читання. І навпаки, розділ .data, який містить глобальні змінні, відображається як заборонений на виконання/читання і запис. Однак для економії місця розділи не вирівнюються на диску таким чином. Динамічний компонувальник відображає кожен розділ у пам’яті окремо та призначає правильні дозволи на основі інформації в заголовках. [8]
Таблиця адрес імпорту (IAT) використовується як таблиця пошуку, коли програма викликає функцію в іншому модулі. Імпорт можна вказати за порядковим номером або за назвою. Оскільки скомпільована програма не може заздалегідь знати розташування залежних від неї бібліотек, для викликів API необхідний непрямий перехід. Оскільки динамічний компонувальник утримує модулі та вирішує залежності, він заповнює слоти IAT фактичними адресами відповідних функцій бібліотеки. Незважаючи на те, що це додає додаткову інструкцію jmp, спричиняючи погіршення продуктивності порівняно з міжмодульними викликами, це мінімізує кількість сторінок пам’яті, для яких потрібні зміни копіювання під час запису, таким чином зберігаючи пам’ять і зменшуючи обсяг дискового вводу-виводу. Якщо заздалегідь відомо, що виклик є міжмодульним (якщо це вказано атрибутом dllimport ), компілятор може створити оптимізований код за допомогою простого коду операції непрямого виклику. [8]
Файли PE за замовчуванням не залежать від позиції ; вони скомпільовані для роботи за певною фіксованою адресою пам’яті. Сучасні операційні системи використовують рандомізацію адресного простору (ASLR), щоб зловмисникам було важче використовувати вразливості, пов’язані з пам’яттю. ASLR працює шляхом випадкової зміни адреси пам’яті важливих частин програми кожного разу, коли вона завантажується. Це включає базову адресу самої програми, спільні бібліотеки (DLL) і області пам’яті, такі як купа та стек. ASLR змінює позиції в адресному просторі ключових областей даних процесу, включаючи базу виконуваного файлу та позиції стека, купи та бібліотек . Шляхом рандомізації цих адрес пам’яті кожного разу, коли процес завантажується програма, ASLR не дозволяє зловмисникам надійно передбачити розташування пам’яті.
У .NET, розділ коду PE містить заглушку, яка викликає запис запуску віртуальної машини CLR, _CorExeMain
або _CorDllMain
у mscoree.dll
, подібно до того, як це було у виконуваних файлах Visual Basic . Тоді віртуальна машина використовує наявні метадані .NET, на корінь яких (IMAGE_COR20_HEADER
, також званий «заголовок CLR») вказує запис IMAGE_DIRECTORY_ENTRY_COMHEADER
(раніше використовувався для метаданих COM+ у програмах COM+, звідки й назва[джерело?] ) у каталозі даних заголовка PE. IMAGE_COR20_HEADER
дуже нагадує додатковий заголовок PE, по суті, відіграючи його роль для завантажувача CLR.[9]
Дані, пов’язані з CLR, включно з власне кореневою структурою, зазвичай містяться в розділі загального коду .text
. Він складається з кількох каталогів: метаданих, вбудованих ресурсів, сильних імен і кількох для взаємодії з рідним кодом. Каталог метаданих — це набір таблиць із переліком усіх окремих сутностей .NET у збірці (англ. assembly, включаючи типи, методи, поля, константи, події, а також посилання між ними та на інші збірки.
Формат PE також використовується ReactOS, операційною системою з відкритим початковим кодом, створеною для бінарної сумісності з Windows. Історично він також використовувався іншими операційними системами, такими як SkyOS і BeOS R3. Однак і SkyOS, і BeOS з часом перейшли на ELF.[джерело?]
Платформа розробки Mono, яка прагне бути бінарно сумісною з Microsoft .NET Framework використовує той самий формат PE, що й реалізація Microsoft. Те саме стосується власної кросплатформеності Microsoft .NET Core .
У x86 (-64) Unix-подібних операційних системах двійкові файли Windows (у форматі PE) можна виконати за допомогою Wine . HX DOS Extender також використовує формат PE для власних 32-розрядних двійкових файлів DOS і може виконувати деякі двійкові файли Windows у DOS, таким чином діючи як еквівалент Wine для DOS.
Mac OS X 10.5 має можливість завантажувати та аналізувати файли PE, хоча вона не підтримує бінарну сумісність із Windows. [10]
Мікропрограмне забезпечення UEFI та EFI використовує PE-файли, а також угоду про виклик Windows ABI x64 для програм. PE використовується навіть на платформах, для яких Windows не існує (наприклад, RISC-V).
- a.out
- Порівняння форматів виконуваних файлів
- Стиснення виконуваного файлу
- ar (Unix)[a]
- Віртуалізація програмного забезпечення
- ↑ Внутрішній формат архівів ar, як правило, або COFF, або BSD
- ↑ https://www.iana.org/assignments/media-types/application/vnd.microsoft.portable-executable
- ↑ https://www.iana.org/assignments/media-types/application/efi
- ↑ Portable executable (PE) - Definition - Trend Micro IN. www.trendmicro.com. Процитовано 10 листопада 2022.
- ↑ UEFI Specification, version 2.8B (PDF).
- ↑ PE Format (Windows) (англ.). 20 лютого 2025. Процитовано 4 березня 2025.
- ↑ /STUB (MS-DOS Stub File Name). 3 серпня 2021.
- ↑ The Portable Executable File From Top to Bottom. Процитовано 21 жовтня 2017.
- ↑ а б Peering Inside the PE: A Tour of the Win32 Portable Executable File. 30 червня 2010. Процитовано 21 жовтня 2017.
- ↑ PE Format (Windows). Процитовано 21 жовтня 2017.
- ↑ Chartier, David (30 листопада 2007). Uncovered: Evidence that Mac OS X could run Windows apps soon. Ars Technica. Процитовано 3 грудня 2007.
... Steven Edwards describes the discovery that Leopard apparently contains an undocumented loader for Portable Executables, a type of file used in 32-bit and 64-bit versions of Windows. More poking around revealed that Leopard's own loader tries to find Windows DLL files when attempting to load a Windows binary.
- PE Format (latest online document, changes in time)
- Microsoft Portable Executable and Common Object File Format Specification. Revision 11.0, Jan 2017; Revision 10.0, Jun 2016; Revision 8.3, Feb 2013; Revision 8.2, Sep 2010; Revision 8.1, Feb 2008; Revision 8.0, May 2006; Revision 6.0, Feb 1999; Revision 5.0, Oct 1997; Revision 4.1, Aug 1994; Revision 4.0, Sep 1993
- Tool Interface Standard (TIS) Formats Specifications for Windows Version 1.0 (Intel Order Number 241597, TIS Committee, Feb 1993)
- Portable Executable Format (Micheal J. O'Leary, Microsoft Developer Support)
- Peering Inside the PE: A Tour of the Win32 Portable Executable File Format. Matt Pietrek, Microsoft Systems Journal, March 1994
- An In-Depth Look into the Win32 Portable Executable File Format. Matt Pietrek, MSDN Magazine. Part I, February 2002; Part II, March 2002
- The .NET File Format by Daniel Pistelli
- Ero Carrera's blog describing the PE header and how to walk through
- PE Internals provides an easy way to learn the Portable Executable File Format
- PE Explorer