close

Portable ausführbare Datei

Zur Navigation gehen Zur Suche gehen
Portable ausführbare Datei
Entwickler
Microsoft
Allgemeine Information
Dateierweiterung .cpl, .exe, .dll, .ocx, .sys, .scr, .drv
Mime Typ application/vnd.microsoft.portable-executable, application/x-msdownload und application/efi
Uniform Type Identifier com.microsoft.windows-executable
magische Zahl MZ
Formattyp Binär , ausführbar , Objektcode , gemeinsam genutzte Bibliotheken
verlängert von DOS MZ ausführbar ,
COFF
Norm(en) Microsoft PE- und COFF-Spezifikation (Version 8)
offenes Format ?

Das Portable Executable (PE)-Format ist ein Dateiformat für ausführbare Dateien, Objektcodedateien, DLLs (Dynamic Link Libraries), FON-Schriftartendateien [ 1 ] und andere, die in 32-Bit- und 64-Bit-Versionen des Systems verwendet werden Windows -Betriebssystem . Der Begriff "tragbar" bezieht sich auf die Vielseitigkeit des Formats in zahlreichen Umgebungen von Betriebssystem-Softwarearchitekturen. [ 2 ] Das PE-Format ist eine Datenstruktur, die die Informationen kapselt, die der Windows-Loader benötigt, um den ausführbaren Code zu verwalten, der sie umschließt. Dazu gehören Verweise auf Dynamic Link Libraries zum Verknüpfen, Importieren und Exportieren von API -Tabellen , Ressourcendatenverwaltung und Thread-Local-Storage-Daten (TLS-Daten). Auf Windows NT -basierten Betriebssystemen wird das PE-Format für EXE , DLL , SYS ( Gerätetreiber ) und andere Dateitypen verwendet. Die Extensible Firmware Interface (EFI)-Spezifikation gibt an, dass PE das Standardformat für ausführbare Dateien in EFI-Umgebungen ist.

PE ist eine modifizierte Version des Unix - COFF -Formats. Außerdem ist PE/COFF ein alternativer Name in der Windows-Entwicklung.

Auf Windows NT-Betriebssystemen unterstützt PE derzeit die Befehlssätze IA - 32 , IA-64 und x86-64 (AMD/Intel64) (ISA ). Vor Windows 2000 unterstützte Windows NT (und damit PE) die Befehlssätze MIPS , DEC Alpha und PowerPC . Da PE in Windows CE verwendet wird, unterstützt es weiterhin mehrere Varianten der MIPS-, ARM- (einschließlich Thumb) und SuperH-Architekturen .

Die Hauptkonkurrenten von PE sind ELF (unter Linux und vielen anderen Unix- ähnlichen Systemen verwendet ) und Mach-O (unter Mac OS X verwendet ).

Geschichte

Microsoft ist mit der Einführung des Betriebssystems Windows NT 3.1 auf das PE-Format umgestiegen . Alle neueren Versionen von Windows, einschließlich Windows 95, 98 und ME, unterstützen die PE-Dateistruktur. Das Format behielt eine begrenzte Legacy-Unterstützung bei, um die Lücke zwischen DOS-basierten Systemen und NT-basierten Systemen zu schließen. Beispielsweise enthalten PE/COFF-Header immer noch ein ausführbares MS-DOS-Programm, das standardmäßig ein Schnipsel ist, das die einfache Meldung "Dieses Programm kann nicht im DOS-Modus ausgeführt werden" (oder ähnliches) anzeigt. [ 2 ] Auch PE passt sich weiterhin der sich ändernden Windows-Plattform an. Zu den Erweiterungen gehören das PE .NET-Format ( siehe unten ), eine Version für 64-Bit-Binärdateien namens PE32+ (oder manchmal PE+) und eine Spezifikation für Windows CE.

Technische Details

Diagramm PE (de).png

Entwurf

Eine PE-Datei besteht aus einer Reihe von Headern und Abschnitten, die dem dynamischen Linker mitteilen, wie die Datei im Speicher zugewiesen werden soll. Ein ausführbares Image besteht aus mehreren unterschiedlichen Zonen, die jeweils unterschiedlichen Speicherschutz erfordern, sodass der Beginn jedes Abschnitts an einer Seitengrenze ausgerichtet werden muss. Zum Beispiel wird normalerweise der .text- Abschnitt (der Programmcode enthält) als „execute/read-only“ abgebildet, und der .data -Abschnitt (der die globalen Variablen enthält) wird als „no-execute/read-write“ abgebildet. Um jedoch keinen Speicherplatz zu verschwenden, sind die verschiedenen Abschnitte auf der Festplatte nicht seitenausgerichtet. Ein Teil der Aufgabe des dynamischen Linkers besteht darin, jeden Abschnitt einzeln im Speicher abzubilden und den resultierenden Regionen die richtigen Berechtigungen gemäß den Anweisungen in den Headern zuzuweisen.

Abschnittstabelle

Die Abschnittstabelle befindet sich direkt hinter dem PE-Header. Dies ist eine Tabelle, die mehrere IMAGE_SECTION_HEADER- Strukturen enthält . Diese Strukturen enthalten Informationen über die Abschnitte der Binärdateien, die in den Speicher geladen werden sollen.

Das NumberOfSections -Feld der IMAGE_FILE_HEADER - Struktur gibt an, wie viele Einträge in der Tabelle vorhanden sind. Das von Windows unterstützte Maximum beträgt 96 Abschnitte.

Ein Prototyp einer Schnitttabelle sieht so aus:

typedef struct _IMAGE_SECTION_HEADER {   
  BYTE - Name [ IMAGE_SIZEOF_SHORT_NAME ];  
  Gewerkschaft  {
      DWORD Physikalische Adresse ; 
      DWORD Virtuelle Größe ; 
  } Verschiedenes ; 
  DWORD Virtuelle Adresse ; 
  DWORD SizeOfRawData ; 
  DWORD PointerToRawData ; 
  DWORD PointerToRelocations ; 
  DWORD PointerToLinenumbers ; 
  WORD AnzahlUmzüge ;  
  WORD AnzahlZeilennummern ;  
  DWORD- Eigenschaften ; 
} IMAGE_SECTION_HEADER , * PIMAGE_SECTION_HEADER ;  

Jeder Abschnitt hat einen 8-stelligen Namen; Dieser Name ist nicht signifikant, aber Sie können normalerweise Folgendes finden:

Name Beschreibung
.Text Der Code (Anweisungen) des Programms
.bss Nicht initialisierte Variablen
.Uhr Die Umzugstabelle
.Daten Initialisierte Variablen
.rsrc Die Ressourcen der Datei (Cursor, Sounds, Menüs...)
.rDaten schreibgeschützte Daten
.idata Die Importtabelle
.upx Signatur einer UPX-Komprimierung, typisch für UPX-Software
.aspack Signatur eines ASPACK-Pakets, typisch für ASPACK-Software
.adata Signatur eines ASPACK-Pakets, typisch für ASPACK-Software

IMPORT-Tabelle

Ein erwähnenswerter Abschnitt ist die Import-Adresstabelle (IAT), die als Nachschlagetabelle verwendet wird, wenn die Anwendung eine Funktion in einem anderen Modul aufruft. Dies kann in Form von Import nach Ordnungszahl oder Import nach Namen erfolgen. Da ein kompiliertes Programm den Speicherort der Bibliotheken, von denen es direkt abhängt, nicht kennen kann, ist bei jedem API-Aufruf ein indirekter Sprung erforderlich. Während der dynamische Linker die Module lädt und verbindet, schreibt er die aktuelle Adresse in die IAT-Slots, sodass sie auf die entsprechenden Speicherstellen in der Funktionsbibliothek zeigen. Obwohl dies die Kosten eines modulinternen Aufrufs zusätzlich erhöht, was zu einer Leistungseinbuße führt, bietet es einen entscheidenden Vorteil: Es minimiert die Anzahl der Speicherseiten, die vom Lader durch Copy-on-Write geändert werden müssen. , Einsparung von Speicher und Festplatten-I/O-Zeit. Wenn der Compiler im Voraus weiß, dass es sich um einen Aufruf zwischen Modulen handelt (über das Attribut dllimport ), kann er optimierteren Code erzeugen, der einfach in einen indirekten Opcode -Aufruf übersetzt wird .

Umzüge

PE-Dateien enthalten keinen positionsunabhängigen Code . Stattdessen werden sie zu einer bevorzugten Basisadresse kompiliert , und allen vom Compiler/Linker ausgegebenen Adressen wird ein Präfix vorangestellt. Wenn eine PE-Datei nicht an ihrer bevorzugten Adresse geladen werden kann (weil sie bereits von etwas anderem belegt wurde), wird sie vom Betriebssystem zurückgesetzt. Dies beinhaltet das Neuberechnen jeder absoluten Adresse und das Modifizieren des Codes, um die neuen Werte zu verwenden. Dazu vergleicht das Ladegerät die aktuelle und bevorzugte Ladeadresse und errechnet einen Deltawert . Diese wird dann zu der bevorzugten Adresse addiert, um zu der neuen Speicherplatzadresse zu gelangen. Basisumzüge werden in einer Liste gespeichert und bei Bedarf einem bestehenden Speicherplatz hinzugefügt. Der resultierende Code ist jetzt für den Prozess privat und wird nicht mehr gemeinsam genutzt, sodass viele der speichersparenden Vorteile von DLLs in diesem Szenario verloren gehen. Es verlangsamt auch das Laden des Moduls erheblich. Aus diesem Grund wird eine Neuausrichtung nach Möglichkeit vermieden, und von Microsoft bereitgestellte DLLs verfügen über vorberechnete Basisadressen, sodass sie sich nicht überschneiden. Somit bietet PE im Fall ohne Reset den Vorteil eines sehr effizienten Codes, aber bei vorhandenem Reset kann der Erfolg bei der Speichernutzung kostspielig sein. Dies steht im Gegensatz zu ELF, das vollständig positionsunabhängigen Code und eine globale Offset-Tabelle verwendet, die die Laufzeit gegenüber der Speichernutzung zugunsten der letzteren abwägt.

.NET, Metadaten und das PE-Format

Das .NET Framework von Microsoft hat das PE-Format um Funktionen erweitert, die die Common Language Runtime (CLR) unterstützen. Zu den hinzugefügten Funktionen gehören CLR-Header und CLR-Datenabschnitte. Beim Laden einer Binärdatei übergibt der OS-Loader die Ausführung an die CLR, indem er auf die PE/COFF-IMPORT-Tabelle verweist. Die CLR lädt dann den CLR-Header und die Datenabschnitte.

Der CLR -Datenabschnitt enthält zwei wichtige Segmente, Metadatencode und Intermediate Language (IL)-Code:

  • Die Metadaten enthalten für die Assembly relevante Informationen, einschließlich des Assemblymanifests. Ein Manifest beschreibt die Assembly detailliert, einschließlich eindeutiger Identifizierung (unter Verwendung eines Hashs , einer Versionsnummer usw.), Daten in exportierten Komponenten, umfassender Typinformationen (unterstützt durch das Common Type System (CTS)), externer Referenzen und einer Liste von Dateien innerhalb der Assembly. Die CLR-Umgebung macht umfangreichen Gebrauch von Metadaten. [ 3 ]
  • Der IL -Code ist ein abstrakter, sprachunabhängiger Code, der die Anforderungen der Common Intermediate Language (CIL) der CLR erfüllt . Der Begriff „ intermediär “ bezieht sich auf die sprach- und plattformübergreifende Kompatibilität des IL -Codes . Diese Zwischensprache , ähnlich dem Java-Bytecode , ermöglicht es Plattformen und Sprachen, die gemeinsame CLR zu unterstützen . IL unterstützt objektorientierte Programmierung (Polymorphismus, Vererbung, abstrakte Typen usw.), Ausnahmen, Ereignisse und verschiedene Datenstrukturen.

Verwendung auf anderen Betriebssystemen

Das PE-Format wird auch von ReactOS verwendet , da dieses Betriebssystem binärkompatibel mit Windows sein soll. Das PE-Format wurde in der Vergangenheit auch von einigen Betriebssystemen verwendet, darunter SkyOS und BeOS R3. Allerdings wurden sowohl SkyOS als auch BeOS in das ELF -Format portiert .

Da die Mono-Entwicklungsplattform binärkompatibel mit Microsoft .NET ist, verwendet sie das gleiche PE-Format wie die Microsoft-Implementierung.

Auf 32-Bit- Unix - ähnlichen Betriebssystemen können einige Windows-Binärdateien (im PE-Format) mit Wine ausgeführt werden . HX DOS Extender verwendet auch das PE-Format für native 32-Bit-DOS-Binärdateien, außerdem kann er bis zu einem gewissen Grad vorhandene Windows-Binärdateien unter DOS ausführen und sich so verhalten, als wäre es Wine für DOS.

Mac OS X 10.5 kann PE-Dateien laden und parsen, ist aber nicht binärkompatibel mit Windows. [ 4 ]

Referenzen

  1. Tatham, Simon. "mkwinfont" (auf Englisch) . Abgerufen am 31. Oktober 2012 . 
  2. a b Microsoft , Hrsg. (1. November 2006). „Gemeinsames Objektdateiformat (COFF-Format)“ . Microsoft-Support . Abgerufen am 5. April 2013 . 
  3. Microsoft (Hrsg.). "Metadaten und die Struktur der PE-Datei" . MSDNLibrary . Abgerufen am 5. April 2013 . 
  4. ^ Chartier, David (30. November 2007). "Aufgedeckt: Beweise dafür, dass Mac OS X bald Windows-Apps ausführen könnte" . Ars Technica . Abgerufen am 3. Dezember 2007 . «... Steven Edwards beschreibt die Entdeckung, dass Leopard offenbar einen undokumentierten Loader für Portable Executables enthält, einen Dateityp, der in 32-Bit- und 64-Bit-Versionen von Windows verwendet wird. Weiteres Herumstochern ergab, dass Leopards eigener Loader versucht, Windows-DLL-Dateien zu finden, wenn er versucht, eine Windows-Binärdatei zu laden. » 

Siehe auch

  • Nachtrag: Vergleich ausführbarer Dateiformate
  • exe

Externe Links