The Portable Executable (PE) format is a file format for executables, object code, DLLs and others used in 32-bit and 64-bit versions of Windows operating systems. The PE format is a data structure that encapsulates the information necessary for the Windows OS loader to manage the wrapped executable code. This includes dynamic library references for linking, API export and import tables, resource management data and thread-local storage (TLS) data. On NT operating systems, the PE format is used for EXE, DLL, SYS (device driver), MUI and other file types. The Unified Extensible Firmware Interface (UEFI) specification states that PE is the standard executable format in EFI environments.

On Windows NT operating systems, PE currently supports the x86-32, x86-64 (AMD64/Intel 64), IA-64, ARM and ARM64 instruction set architectures (ISAs). Prior to Windows 2000, Windows NT (and thus PE) supported the MIPS, Alpha, and PowerPC ISAs. Because PE is used on Windows CE, it continues to support several variants of the MIPS, ARM (including Thumb), and SuperH ISAs.

Analogous formats to PE are ELF (used in Linux and most other versions of Unix) and Mach-O (used in macOS and iOS).

History 

Microsoft migrated to the PE format from the 16-bit NE formats with the introduction of the Windows NT 3.1 operating system. All later versions of Windows, including Windows 95/98/ME and the Win32s addition to Windows 3.1x, support the file structure. The format has retained limited legacy support to bridge the gap between DOS-based and NT systems. For example, PE/COFF headers still include a DOS executable program, which is by default a DOS stub that displays a message like "This program cannot be run in DOS mode" (or similar), though it can be a full-fledged DOS version of the program (a later notable case being the Windows 98 SE installer). This constitutes a form of fat binary. PE also continues to serve the changing Windows platform. Some extensions include the .NET PE format (see below), a version with 64-bit address space support called PE32+, and a specification for Windows CE.

Technical details

Layout

A PE file consists of a number of headers and sections that tell the dynamic linker how to map the file into memory. An executable image consists of several different regions, each of which require different memory protection; so the start of each section must be aligned to a page boundary. For instance, typically the .text section (which holds program code) is mapped as execute/read-only, and the .data section (holding global variables) is mapped as no-execute/read write. However, to avoid wasting space, the different sections are not page aligned on disk. Part of the job of the dynamic linker is to map each section to memory  individually and assign the correct permissions to the resulting regions, according to the instructions found in the headers.

Import table
One section of note is the import address table (IAT), which is used as a lookup table when the application is calling a function in a different module. It can be in the form of both import by ordinal and import by name. Because a compiled program cannot know the memory location of the libraries it depends upon, an indirect jump is required whenever an API call is made.  As the dynamic linker loads modules and joins them together, it writes actual addresses into the IAT slots, so that they point to the memory locations of the corresponding library functions.  Though this adds an extra jump over the cost of an intra-module call resulting in a performance penalty, it provides a key benefit: The number of memory pages that need to be copy-on-write changed by the loader is minimized, saving memory and disk I/O time. If the compiler knows ahead of time that a call will be inter-module (via a dllimport attribute) it can produce more optimized code that simply results in an indirect call opcode.

Relocations

PE files normally do not contain position-independent code. Instead they are compiled to a preferred base address, and all addresses emitted by the compiler/linker are fixed ahead of time. If a PE file cannot be loaded at its preferred address (because it's already taken by something else), the operating system will rebase it. This involves recalculating every absolute address and modifying the code to use the new values. The loader does this by comparing the preferred and actual load addresses, and calculating a delta value. This is then added to the preferred address to come up with the new address of the memory location.  Base relocations are stored in a list and added, as needed, to an existing memory location. The resulting code is now private to the process and no longer shareable, so many of the memory saving benefits of DLLs are lost in this scenario. It also slows down loading of the module significantly. For this reason rebasing is to be avoided wherever possible, and the DLLs shipped by Microsoft have base addresses pre-computed so as not to overlap. In the no rebase case PE therefore has the advantage of very efficient code, but in the presence of rebasing the memory usage hit can be expensive. This contrasts with ELF where fully position-independent code is usually preferred to load-time relocation, thus trading off execution time in favor of lower memory usage.

.NET, metadata, and the PE format
In a .NET executable, the PE code section contains a stub that invokes the CLR virtual machine startup entry, _CorExeMain or _CorDllMain in mscoree.dll, much like it was in Visual Basic executables. The virtual machine then makes use of .NET metadata present, the root of which, IMAGE_COR20_HEADER (also called "CLR header") is pointed to by IMAGE_DIRECTORY_ENTRY_COMHEADER entry in the PE header's data directory. IMAGE_COR20_HEADER strongly resembles PE's optional header, essentially playing its role for the CLR loader.

The CLR-related data, including the root structure itself, is typically contained in the common code section, .text. It is composed of a few directories: metadata, embedded resources, strong names and a few for native-code interoperability. Metadata directory is a set of tables that list all the distinct .NET entities in the assembly, including types, methods, fields, constants, events, as well as references between them and to other assemblies.

Use on other operating systems
The PE format is also used by ReactOS, as ReactOS is intended to be binary-compatible with Windows.  It has also historically been used by a number of other operating systems, including SkyOS and BeOS R3. However, both SkyOS and BeOS eventually moved to ELF.

As the Mono development platform intends to be binary compatible with the Microsoft .NET Framework, it uses the same PE format as the Microsoft implementation. The same goes for Microsoft's own cross-platform .NET Core.

On x86(-64) Unix-like operating systems, Windows binaries (in PE format) can be executed with Wine. The HX DOS Extender also uses the PE format for native DOS 32-bit binaries, plus it can, to some degree, execute existing Windows binaries in DOS, thus acting like an equivalent of Wine for DOS.

On IA-32 and x86-64 Linux one can also run Windows' DLLs under load library.

Mac OS X 10.5 has the ability to load and parse PE files, but is not binary compatible with Windows.

UEFI and EFI firmware use Portable Executable files as well as the Windows ABI x64 calling convention for applications.

See also
 EXE
 Executable and Linkable Format
 Mach-O
 a.out
 Comparison of executable file formats
 Executable compression
 ar (Unix) since all COFF libraries use that same format
 Application virtualization

References

External links
PE Format  (latest online document)
Microsoft Portable Executable and Common Object File Format Specification (revision 11.0, .docx format, Jan 2017)
Microsoft Portable Executable and Common Object File Format Specification (revision 10.0, .docx format, Jun 2016)
Microsoft Portable Executable and Common Object File Format Specification (revision 8.3, .docx format, Feb 2013)
Microsoft Portable Executable and Common Object File Format Specification (revision 8.2, .docx format, Sep 2010)
Microsoft Portable Executable and Common Object File Format Specification (revision 8.1, .docx format, Feb 2008)
Microsoft Portable Executable and Common Object File Format Specification (revision 8.0, .doc format, May 2006)
Microsoft Portable Executable and Common Object File Format Specification (revision 6.0, .doc format, Feb 1999)
Microsoft Portable Executable and Common Object File Format Specification (revision 5.0, .html format, Oct 1997)
Microsoft Portable Executable and Common Object File Format Specification (revision 4.1, .html format, Aug 1994)
Microsoft Portable Executable and Common Object File Format Specification (revision 4.0, .html format, 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 (archived from the original) by Matt Pietrek (Microsoft Systems Journal, March 1994)
Part I. An In-Depth Look into the Win32 Portable Executable File Format (archived from the original) by Matt Pietrek (MSDN Magazine, February 2002)
Part II. An In-Depth Look into the Win32 Portable Executable File Format (archived from the original by Matt Pietrek (MSDN Magazine, 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

Executable file formats
Windows administration
PE 포맷()은 윈도우 운영 체제에서 사용되는 실행 파일, DLL, object 코드, FON 폰트 파일 등을 위한 파일 형식이다. PE 포맷은 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구조체이다. 이것은 링킹을 위한 동적 라이브러리 참조, API 익스포트와 임포트 테이블, 자원 관리 데이터 그리고 TLS 데이터를 포함한다. 윈도우 NT 운영체제에서, PE 포맷은 EXE, DLL, SYS (디바이스 드라이버), 그리고 다른 파일 종류들에서 쓰인다. 통일 확장 펌웨어 인터페이스 (EFI) 설명서는 PE가 EFI 환경에서 표준 실행 파일 형식이라고 언급한다.

윈도우 NT 운영 체제에서, PE는 현재 IA-32, IA-64, x86-64 (AMD64/Intel64), 그리고 ARM instruction set architectures (ISAs)를 지원한다. 윈도우 2000 이전에서, 윈도우 NT는 (그리고 PE) MIPS, Alpha, 그리고 파워PC ISAs를 지원했다. PE가 윈도우 CE에서 사용되므로 이것은 MIPS, ARM (Thumb 포함), 그리고 SuperH ISA의 변형들을 지원하고 있다.

PE와 비슷한 형식으로 ELF (리눅스와 대부분의 다른 유닉스 버전들) 와 Mach-O (Mac OS X)가 있다.

역사 
마이크로소프트는 윈도우 NT 3.1 운영 체제의 도입과 함께 PE 포맷으로 옮긴다. 윈도우의 이후 버전들도 이 형식을 지원한다. 이 형식은 도스와 NT 시스템 사이의 차이를 연결하기 위한 한정된 유산을 가지고 있다. 예를 들면, PE/COFF 헤더들은 아직도 MS-DOS 실행 파일을 포함한다. 기본적으로 이것은 "This program cannot be run in DOS mode" 메시지를 보여주는 스텁이다. PE는 또한 윈도우 플랫폼의 변화를 계속해서 지원한다. 이것들은 .NET PE 포맷, PE32+로 불리는 64비트 버전 (가끔은 PE+), 그리고 윈도우 CE를 위한 명세서가 있다.

기술적 세부사항

레이아웃 

PE 파일은 동적 링커에게 파일을 메모리로 어떻게 매핑할지 설명하는 많은 헤더들과 섹션들로 이루어져 있다. 실행 가능한 이미지는 (각각 다른 메모리 보호를 요구하는) 여러 다른 영역으로 이루어져 있다. 그래서 각 섹션의 시작은 반드시 페이지 경계에 맞춰 정렬되어야 한다. 예를 들면, 전형적인 .text 섹션(프로그램 코드를 가지는)의 경우 execute/readwrite으로 매핑되어야 하고 .data 섹션(전역 변수들을 가지는)의 경우 no-execute/readwrite로 매핑되어야 한다. 그러나 공간 낭비를 피하기 위해서, 다른 섹션들은 디스크에서 페이지 정렬되어 있지 않다. 동적 링커의 일 중 하나는 각 섹션을 개별적으로 메모리에 매핑하고, 헤더에 있는 지시에 따라 그곳에 정확한 권한을 할당하는 것이다.

임포트 테이블 
import address table (IAT) 섹션은 응용 프로그램이 다른 모듈에서 함수를 호출할 때 검색 테이블로 사용된다. 이것은 서수에 의한 들여오기나 이름에 의한 들여오기가 될 수 있다. 컴파일 된 프로그램은 의존하는 라이브러리의 메모리 위치를 모르기 때문에 API 호출 시 간접적인 점프가 요구된다. 동적 링커가 모듈을 로드하고 연결시키고, 실제 주소를 IAT에 넣는다. 그 후 상응하는 라이브러리 함수의 메모리 위치를 가리키게 된다. 비록 이 추가로 인해 모듈 내부의 호출에도 추가적인 점프가 요구되지만 이것은 중요한 이점을 가진다. 로더에 의해 변경되며 copy-on-write가 요구되는 메모리 페이지들의 수가 최소화돼서 메모리와 디스크의 입출력 시간을 절약할 수 있다. 만약 컴파일러가 호출이 모듈 내부에서 일어나는 것이라고 미리 안다면 더 최적화된 코드를 생산할 수도 있다.

재배치 
PE 파일들은 위치 독립적 코드를 포함하지 않는다. 대신에 선호되는 우선되는 베이스 주소로 컴파일되고, 모든 주소들은 그 전에 고정된다. 만약 PE 파일이 우선되는 주소에 로드될 수 없다면(다른게 이미 위치하고 있는 경우) 운영 체제는 베이스 주소를 바꾼다. 이것은 모든 절대 주소를 다시 계산하고 새로운 값을 사용하도록 코드를 바꾸는 것을 포함한다. 로더는 이것을 우선되는 주소와 실제 로드될 주소를 비교하고 델타 값을 계산함으로써 수행한다. 그 후 우선되는 주소에 새로운 주소의 위치에 대한 값이 더해진다. 베이스 재배치들은 메모리 위치에 목록화되고 저장된다. 결과 코드는 이제 프로세스에 사적이 되고 공유될 수 없게 됨으로써 DLL의 수많은 메모리 절약 이점이 사라진다. 또한 모듈을 로딩하는 시간도 매우 느려지게 된다. 이 이유로 이러한 재배치는 가능한 한 피해지며, 마이크로소프트에서 나온 DLL들은 겹쳐질 수 없게 만들어져 있다.

다른 운영 체제에서의 사용 
x86의 유닉스 계열 운영체제들에서 몇몇 윈도우 바이너리들은 와인으로 돌아갈 수 있다.
맥 OS X 10.5는 PE 파일들을 로드하고 분석할 수 있는 기능을 갖지만 윈도우와 호환은 되지 않는다.

같이 보기 
 EXE
 A.out
 실행 파일 압축
 응용 프로그램 가상화

각주

관련 도서 
 《Windows 시스템 실행 파일의 구조와 원리》

외부 링크 
 마이크로소프트 PE Coff 파일포맷 스페시피케이션
 매트 피트렉, 최초의 PE 관련기사 (MSDN 매거진, 1994년 3월호) 
 Part I. An In-Depth Look into the Win32 Portable Executable File Format by Matt Pietrek (마이크로소프트 개발자 네트워크 매거진 MSDN Magazine, February 2002)
 Part II. An In-Depth Look into the Win32 Portable Executable File Format by Matt Pietrek (마이크로소프트 개발자 네트워크 매거진 MSDN Magazine, March 2002)
 PE File Format Diagram
 The .NET File Format by Daniel Pistelli
 Creating the smallest possible PE executable 97bytes
 Detailed description of the PE format by Johannes Plachy 
 윈도우 실행 정보

관련 도구 

 PEBrowse PE 파일 뷰어 유틸리티.
 CFF Explorer PE 편집기. 닷넷 프레임워크를 지원하는 최초의 PE 편집기.
 PE Explorer PE 파일 뷰어/편집기. (셰어웨어)
 yoda's LordPE Deluxe, 덤퍼가 포함된 PE 편집기.
 PEDUMP  콘솔 응용 프로그램 + 소스 코드(C++), 텍스트로 리디렉트한 다음 두 텍스트를 비교하기 좋음.
 GNU Binutils --target=i386-pe, --target=mips-pe
 Anywhere PE Viewer 자바 응용 프로그램.
 PE PE (.exe, .ocx, .dll 등)을 읽어서 섹션(section)을 볼 수 있고 리소스를 불러오거나 내보낼 수 있음.
 SK PEInfo for Windows CE 윈도우 CE용 PE 뷰어.
 pefile 파이썬(프로그래밍) 모듈.
 anal_pe  명령 줄 기반의 도구. 리눅스와 윈도우에서 동작.

파일 포맷
실행 파일 포맷