PE-Format
Diese Spezifikation beschreibt die Struktur von ausführbaren Dateien (Imagedateien) und Objektdateien unter Windows Betriebssystemfamilie. Diese Dateien werden als PE-Dateien (Portable Executable) bzw. COFF-Dateien (Common Object File Format) bezeichnet.
Hinweis
Dieses Dokument wird als Hilfe bei der Entwicklung von Tools und Anwendungen für Windows bereitgestellt. Es ist jedoch nicht garantiert, dass es sich in jeder Hinsicht um eine vollständige Spezifikation handelt. Microsoft behält sich das Recht vor, dieses Dokument ohne vorherige Ankündigung zu ändern.
Diese Revision der Microsoft Portable Executable und Common Object File Format Specification ersetzt alle vorherigen Revisionen dieser Spezifikation.
Allgemeine Konzepte
In diesem Dokument wird die Struktur von ausführbaren Dateien (Imagedateien) und Objektdateien unter der Microsoft Windows-Betriebssystemfamilie angegeben. Diese Dateien werden als PE-Dateien (Portable Executable) bzw. COFF-Dateien (Common Object File Format) bezeichnet. Der Name "Portable Executable" bezieht sich auf die Tatsache, dass das Format nicht architekturspezifisch ist.
Bestimmte Konzepte, die in dieser Spezifikation angezeigt werden, werden in der folgenden Tabelle beschrieben:
| Name | BESCHREIBUNG |
|---|---|
| Attributzertifikat |
Ein Zertifikat, das verwendet wird, um überprüfbare Anweisungen einem Bild zu zuordnen. Eine Reihe verschiedener überprüfbarer Anweisungen kann einer Datei zugeordnet werden. eine der nützlichsten ist eine Anweisung eines Softwareherstellers, die angibt, wie der Nachrichtenh digest des Images erwartet wird. Ein Nachrichtenh digest ähnelt einer Prüfsumme, mit der Ausnahme, dass es äußerst schwierig zu forge sein ist. Daher ist es sehr schwierig, eine Datei so zu ändern, dass sie den gleichen Nachrichtenh digest wie die ursprüngliche Datei hat. Die Anweisung kann mithilfe von Kryptografieschemas mit öffentlichem oder privatem Schlüssel als vom Hersteller vorgenommen überprüft werden. In diesem Dokument werden Details zu Anderen Attributzertifikaten beschrieben, als das Einfügen in Bilddateien zu ermöglichen. |
| Datums-/Uhrzeitstempel |
Ein Stempel, der für verschiedene Zwecke an mehreren Stellen in einer PE- oder COFF-Datei verwendet wird. In den meisten Fällen ist das Format jedes Stempels identisch mit dem Format, das von den Zeitfunktionen in der C-Laufzeitbibliothek verwendet wird. Informationen zu Ausnahmen finden Sie in der Beschreibung von IMAGE _ DEBUG _ TYPE _ REPRO im Debugtyp. Wenn der Stempelwert 0 oder 0xFFFFFFFF ist, stellt er keinen echten oder aussagekräftigen Datums-/Uhrzeitstempel dar. |
| Dateizeiger |
Der Speicherort eines Elements in der Datei selbst, bevor es vom Linker (im Fall von Objektdateien) oder vom Lader (bei Bilddateien) verarbeitet wird. Anders ausgedrückt: Dies ist eine Position innerhalb der Datei, die auf dem Datenträger gespeichert ist. |
| Linker |
Ein Verweis auf den Linker, der mit dem Microsoft Visual Studio. |
| Objektdatei |
Eine Datei, die als Eingabe für den Linker angegeben wird. Der Linker erzeugt eine Bilddatei, die wiederum vom Lader als Eingabe verwendet wird. Der Begriff "Objektdatei" impliziert nicht notwendigerweise eine Verbindung mit der objektorientierten Programmierung. |
| reserviert, muss 0 sein. |
Eine Beschreibung eines Felds, das angibt, dass der Wert des Felds für Generatoren 0 (null) sein muss, und Consumers das Feld ignorieren müssen. |
| Relative virtuelle Adresse (RVA) |
In einer Bilddatei ist dies die Adresse eines Elements, nachdem es in den Arbeitsspeicher geladen wurde, und die Basisadresse der Imagedatei wird davon subtrahiert. Das RVA eines Elements unterscheidet sich fast immer von seiner Position innerhalb der Datei auf dem Datenträger (Dateizeiger). In einer Objektdatei ist ein RVA weniger aussagekräftig, da Speicherspeicherorte nicht zugewiesen werden. In diesem Fall wäre ein RVA eine Adresse innerhalb eines Abschnitts (weiter unten in dieser Tabelle beschrieben), auf den später während der Verknüpfung eine Verschiebung angewendet wird. Der Einfachheit halber sollte ein Compiler nur das erste RVA in jedem Abschnitt auf 0 (null) festlegen. |
| section |
Die grundlegende Code- oder Dateneinheit in einer PE- oder COFF-Datei. Beispielsweise kann der ganze Code in einer Objektdatei innerhalb eines einzelnen Abschnitts kombiniert werden, oder (je nach Compilerverhalten) kann jede Funktion einen eigenen Abschnitt belegen. Mit mehr Abschnitten kommt es zu mehr Dateiaufwand, aber der Linker kann die Verknüpfung im Code selektiver ausführen. Ein Abschnitt ähnelt einem Segment in der Intel 8086-Architektur. Alle Rohdaten in einem Abschnitt müssen zusammenhängend geladen werden. Darüber hinaus kann eine Bilddatei eine Reihe von Abschnitten enthalten, z. B. TLS oder .reloc, die besondere Zwecke haben. |
| Virtuelle Adresse (VA) |
Identisch mit RVA, mit der Ausnahme, dass die Basisadresse der Imagedatei nicht subtrahiert wird. Die Adresse wird als VA bezeichnet, da Windows unabhängig vom physischen Speicher einen eindeutigen VA-Raum für jeden Prozess erstellt. Für fast alle Zwecke sollte eine VA nur als Adresse betrachtet werden. Eine Va ist nicht so vorhersagbar wie ein RVA, da das Lader das Image möglicherweise nicht an seinem bevorzugten Speicherort laden kann. |
Übersicht
In der folgenden Liste wird das ausführbare Microsoft PE-Format mit der Basis des Imageheader oben beschrieben. Der Abschnitt vom MS-DOS 2.0-kompatiblen EXE-Header bis zum nicht verwendeten Abschnitt direkt vor dem PE-Header ist der MS-DOS 2.0-Abschnitt und wird nur für MS-DOS-Kompatibilität verwendet.
MS-DOS 2.0-kompatibler EXE-Header
unused
OEM-Bezeichner
Informationen zum Gerätehersteller
Offset zu PE-Header
MS-DOS 2.0 Stub Program and Relocation Table
unused
PE-Header (an 8-Byte-Grenze ausgerichtet)
Abschnittsheader
Bildseiten:
Importinformationen
Exportinformationen
Basisverlagerungen
Ressourceninfo
In der folgenden Liste wird das Microsoft COFF-Objektmodulformat beschrieben:
Microsoft COFF-Header
Abschnittsheader
Rohdaten:
code
data
Debuginformationen
Standortverlagerungen
Dateiheader
- MS-DOS-Stub (nur Image)
- Signatur (nur Image)
- COFF-Dateiheader (Objekt und Bild)
- Optionaler Header (nur Bild)
Der PE-Dateiheader besteht aus einem Microsoft MS-DOS-Stub, der PE-Signatur, dem COFF-Dateiheader und einem optionalen Header. Ein COFF-Objektdateiheader besteht aus einem COFF-Dateiheader und einem optionalen Header. In beiden Fällen folgen direkt auf die Dateiheader Abschnittsheader.
MS-DOS-Stub (nur Image)
Der MS-DOS-Stub ist eine gültige Anwendung, die unter MS-DOS ausgeführt wird. Sie wird am Anfang des EXE-Images platziert. Der Linker platziert hier einen Standardstub, der die Meldung "Dieses Programm kann nicht im DOS-Modus ausgeführt werden" aus gibt, wenn das Image in MS-DOS ausgeführt wird. Der Benutzer kann mithilfe der /STUB-Linkeroption einen anderen Stub angeben.
An der 0x3c hat der Stub den Dateioffset zur PE-Signatur. Diese Informationen ermöglichen Windows, die Imagedatei ordnungsgemäß auszuführen, obwohl sie über einen MS-DOS-Stub verfügt. Dieser Dateioffset wird während der Verknüpfung 0x3c Speicherort platziert.
Signatur (nur Image)
Nach dem MS-DOS-Stub ist am Dateioffset, der bei offset 0x3c angegeben ist, eine 4-Byte-Signatur, die die Datei als Bilddatei im PE-Format identifiziert. Diese Signatur ist "PE \ 0 \ 0" (die Buchstaben "P" und "E" gefolgt von zwei NULL-Bytes).
COFF-Dateiheader (Objekt und Bild)
Am Anfang einer Objektdatei oder unmittelbar nach der Signatur einer Bilddatei ist ein COFF-Standarddateiheader im folgenden Format. Beachten Sie, dass Windows-Lader die Anzahl der Abschnitte auf 96 beschränkt.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
2 |
Machine |
Die Zahl, die den Typ des Zielcomputers identifiziert. Weitere Informationen finden Sie unter Computertypen. |
| 2 |
2 |
NumberOfSections |
Die Anzahl der Abschnitte. Dies gibt die Größe der Abschnittstabelle an, die unmittelbar auf die Header folgt. |
| 4 |
4 |
TimeDateStamp |
Die niedrigen 32 Bits der Anzahl von Sekunden seit dem 1. Januar 1970 00:00 (ein C-Laufzeitwert t), der angibt, wann die Datei erstellt _ wurde. |
| 8 |
4 |
PointerToSymbolTable |
Der Dateioffset der COFF-Symboltabelle oder 0 (null), wenn keine COFF-Symboltabelle vorhanden ist. Dieser Wert sollte für ein Image 0 (null) sein, da COFF-Debuginformationen veraltet sind. |
| 12 |
4 |
NumberOfSymbols |
Die Anzahl der Einträge in der Symboltabelle. Diese Daten können verwendet werden, um die Zeichenfolgentabelle zu suchen, die unmittelbar auf die Symboltabelle folgt. Dieser Wert sollte für ein Image 0 (null) sein, da COFF-Debuginformationen veraltet sind. |
| 16 |
2 |
SizeOfOptionalHeader |
Die Größe des optionalen Headers, der für ausführbare Dateien, aber nicht für Objektdateien erforderlich ist. Dieser Wert sollte für eine Objektdatei NULL sein. Eine Beschreibung des Headerformats finden Sie unter Optionaler Header (nur Bild). |
| 18 |
2 |
Merkmale |
Die Flags, die die Attribute der Datei angeben. Informationen zu bestimmten Flagwerten finden Sie unter Merkmale. |
Computertypen
Das Feld Computer verfügt über einen der folgenden Werte, die den CPU-Typ angeben. Eine Imagedatei kann nur auf dem angegebenen Computer oder auf einem System ausgeführt werden, das den angegebenen Computer emuliert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| _ _ IMAGEDATEICOMPUTER _ UNBEKANNT |
0x0 |
Es wird davon ausgegangen, dass der Inhalt dieses Felds auf jeden Computertyp anwendbar ist. |
| _ _ IMAGEDATEICOMPUTER _ AM33 |
0x1d3 |
Matsushita AM33 |
| _ _ IMAGEDATEICOMPUTER _ AMD64 |
0x8664 |
x64 |
| IMAGE _ FILE _ MACHINE _ ARM |
0x1c0 |
ARM Little Endian |
| _ _ IMAGEDATEICOMPUTER _ ARM64 |
0xaa64 |
ARM64 Little-Endian |
| _ _ IMAGEDATEICOMPUTER _ ARMNT |
0x1c4 |
ARM Thumb-2 Little Endian |
| _ _ BILDDATEICOMPUTER _ EBC |
0xebc |
EFI-Bytecode |
| _ _ IMAGEDATEICOMPUTER _ I386 |
0x14c |
Intel 386- oder höher-Prozessoren und kompatible Prozessoren |
| _ _ IMAGEDATEICOMPUTER _ IA64 |
0x200 |
Intel Itanium-Prozessorfamilie |
| _ _ IMAGEDATEICOMPUTER _ LOONGARCH32 |
0x6232 |
LoongArch-32-Bit-Prozessorfamilie |
| _ _ IMAGEDATEICOMPUTER _ LOONGARCH64 |
0x6264 |
LoongArch-64-Bit-Prozessorfamilie |
| _ _ IMAGEDATEICOMPUTER _ M32R |
0x9041 |
Little-Endian M32R |
| _ _ IMAGEDATEICOMPUTER _ MIPS16 |
0x266 |
MIPS16 |
| _ _ IMAGEDATEICOMPUTER _ MIPSFPU |
0x366 |
MIPS mit FPU |
| _ _ IMAGEDATEICOMPUTER _ MIPSFPU16 |
0x466 |
MIPS16 mit FPU |
| _ _ IMAGEDATEICOMPUTER _ POWERPC |
0x1f0 |
Power PC Little-Endian |
| _ _ IMAGEDATEICOMPUTER _ POWERPCFP |
0x1f1 |
Power PC mit Gleitkommaunterstützung |
| _ _ IMAGEDATEICOMPUTER _ R4000 |
0x166 |
MIPS little endian |
| _ _ IMAGEDATEICOMPUTER _ RISCV32 |
0x5032 |
RISC-V 32-Bit-Adressraum |
| _ _ IMAGEDATEICOMPUTER _ RISCV64 |
0x5064 |
RISC-V 64-Bit-Adressraum |
| _ _ IMAGEDATEICOMPUTER _ RISCV128 |
0x5128 |
RISC-V 128-Bit-Adressraum |
| _ _ IMAGEDATEICOMPUTER _ SH3 |
0x1a2 |
Hitachi SH3 |
| _ _ IMAGEDATEICOMPUTER _ SH3DSP |
0x1a3 |
Sh3 DSP für Sh3 |
| _ _ IMAGEDATEICOMPUTER _ SH4 |
0x1a6 |
Hitachi SH4 |
| _ _ IMAGEDATEICOMPUTER _ SH5 |
0x1a8 |
Hitachi SH5 |
| _ _ BILDDATEICOMPUTERFINGER _ |
0x1c2 |
Ziehpunkt |
| _ _ IMAGEDATEICOMPUTER _ WCEMIPSV2 |
0x169 |
MIPS Little-Endian WCE v2 |
Merkmale
Das Feld Merkmale enthält Flags, die Attribute der Objekt- oder Bilddatei angeben. Die folgenden Flags sind derzeit definiert:
| Flag | Wert | BESCHREIBUNG |
|---|---|---|
| _ _ IMAGEDATEI: _ ENTFERNTE VERLAGERUNGEN |
0x0001 |
Nur Image, Windows CE und Microsoft Windows NT und höher. Dies gibt an, dass die Datei keine Basisverlagerungen enthält und daher an der bevorzugten Basisadresse geladen werden muss. Wenn die Basisadresse nicht verfügbar ist, meldet das Lader einen Fehler. Das Standardverhalten des Linkers ist das Entfernen von Basisverlagerungen aus ausführbaren Dateien (EXE). |
| AUSFÜHRBARES _ IMAGE DER _ _ BILDDATEI |
0x0002 |
Nur Bild. Dies gibt an, dass die Imagedatei gültig ist und ausgeführt werden kann. Wenn dieses Flag nicht festgelegt ist, weist es auf einen Linkerfehler hin. |
| _ _ BILDDATEIZEILE _ NUMS _ ENTFERNT |
0x0004 |
COFF-Zeilennummern wurden entfernt. Dieses Flag ist veraltet und sollte 0 (null) sein. |
| IMAGEDATEI _ _ – LOKALE _ SYMS _ ENTFERNT |
0x0008 |
COFF-Symboltabelleneinträge für lokale Symbole wurden entfernt. Dieses Flag ist veraltet und sollte 0 (null) sein. |
| BILDDATEI _ _ AGGRESSIVE _ WS _ TRIM |
0x0010 |
Veraltet. Arbeitssatz aggressiv kürzen. Dieses Flag ist für Windows 2000 und höher veraltet und muss 0 (null) sein. |
| _IMAGEDATEI, DIE GROßE ADRESSEN _ _ _ KENNT |
0x0020 |
Die Anwendung kann > 2-GB-Adressen verarbeiten. |
| 0x0040 |
Dieses Flag ist für die zukünftige Verwendung reserviert. |
|
| _ _ BILDDATEIBYTES _ IN UMGEKEHRTER _ LO |
0x0080 |
Little-Endian: Das am wenigsten signifikante Bit (LSB) ist dem wichtigsten Bit (MSB) im Arbeitsspeicher voraus. Dieses Flag ist veraltet und sollte 0 (null) sein. |
| _IMAGEDATEI– _ 32-BIT-COMPUTER _ |
0x0100 |
Der Computer basiert auf einer 32-Bit-Wortarchitektur. |
| _IMAGEDATEI _ _ DEBUGGEN ENTFERNT |
0x0200 |
Debuginformationen werden aus der Imagedatei entfernt. |
| _WECHSELDATENTRÄGER _ DER BILDDATEI AUS AUSTAUSCH _ _ _ AUSFÜHREN |
0x0400 |
Wenn sich das Bild auf einem Wechselmedium befindet, laden Sie es vollständig, und kopieren Sie es in die Auslagerungsdatei. |
| IMAGEDATEI _ _ NET RUN FROM _ _ _ SWAP |
0x0800 |
Wenn sich das Image auf Netzwerkmedien befindet, laden Sie es vollständig, und kopieren Sie es in die Auslagerungsdatei. |
| _ _ IMAGEDATEISYSTEM |
0x1000 |
Die Imagedatei ist eine Systemdatei, kein Benutzerprogramm. |
| _ _ IMAGEDATEI-DLL |
0x2000 |
Die Imagedatei ist eine Dynamic Link Library (DLL). Solche Dateien werden für fast alle Zwecke als ausführbare Dateien betrachtet, obwohl sie nicht direkt ausgeführt werden können. |
| IMAGEDATEI _ _ NUR SYSTEM _ _ EINRICHTEN |
0x4000 |
Die Datei sollte nur auf einem Uniprozessorcomputer ausgeführt werden. |
| _BILDDATEIBYTES _ UMGEKEHRT _ _ HI |
0x8000 |
Big-Endian: Der MSB ist der LSB im Arbeitsspeicher voraus. Dieses Flag ist veraltet und sollte 0 (null) sein. |
Optionaler Header (nur Bild)
Jede Bilddatei verfügt über einen optionalen Header, der Informationen für das Ladefeld enthält. Dieser Header ist in dem Sinne optional, dass einige Dateien (insbesondere Objektdateien) ihn nicht haben. Für Bilddateien ist dieser Header erforderlich. Eine Objektdatei kann einen optionalen Header haben, aber im Allgemeinen hat dieser Header keine Funktion in einer Objektdatei, außer die Größe zu erhöhen.
Beachten Sie, dass die Größe des optionalen Headers nicht festgelegt ist. Das Feld SizeOfOptionalHeader im COFF-Header muss verwendet werden, um zu überprüfen, ob ein Test in der Datei für ein bestimmtes Datenverzeichnis nicht über SizeOfOptionalHeader hinaus geht. Weitere Informationen finden Sie unter COFF-Dateiheader (Objekt und Bild).
Das NumberOfRvaAndSizes-Feld des optionalen Headers sollte auch verwendet werden, um sicherzustellen, dass kein Test für einen bestimmten Datenverzeichniseintrag über den optionalen Header hinausgeht. Darüber hinaus ist es wichtig, die optionale Magic-Zahl für Header auf Formatkompatibilität zu überprüfen.
Die optionale Header-Magic-Zahl bestimmt, ob es sich bei einem Image um eine ausführbare PE32- oder PE32+-Datei handelt.
| Magische Zahl | PE-Format |
|---|---|
| 0x10b |
PE32 |
| 0x20b |
PE32+ |
PE32+-Images ermöglichen einen 64-Bit-Adressraum und beschränken die Bildgröße auf 2 Gigabyte. Andere PE32+-Änderungen werden in den entsprechenden Abschnitten behandelt.
Der optionale Header selbst besteht aus drei Hauptteilen.
| Offset (PE32/PE32+) | Größe (PE32/PE32+) | Headerteil | BESCHREIBUNG |
|---|---|---|---|
| 0 |
28/24 |
Standardfelder |
Felder, die für alle Implementierungen von COFF definiert sind, einschließlich UNIX. |
| 28/24 |
68/88 |
Windows-spezifische Felder |
Zusätzliche Felder zur Unterstützung bestimmter Features von Windows (z. B. Subsysteme). |
| 96/112 |
Variable |
Datenverzeichnisse |
Adress-/Größenpaare für spezielle Tabellen, die sich in der Imagedatei befinden und vom Betriebssystem verwendet werden (z. B. die Importtabelle und die Exporttabelle). |
Optionale Standardfelder für Header (nur Bild)
Die ersten acht Felder des optionalen Headers sind Standardfelder, die für jede Implementierung von COFF definiert sind. Diese Felder enthalten allgemeine Informationen, die zum Laden und Ausführen einer ausführbaren Datei nützlich sind. Sie sind für das PE32+-Format unverändert.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
2 |
Magic |
Die ganze Zahl ohne Vorzeichen, die den Status der Bilddatei identifiziert. Die häufigste Zahl ist 0x10B, die sie als normale ausführbare Datei identifiziert. 0x107 identifiziert es als ROM-Image und 0x20B als ausführbare PE32+-Datei. |
| 2 |
1 |
MajorLinkerVersion |
Die Hauptversionsnummer des Linker. |
| 3 |
1 |
MinorLinkerVersion |
Die Nebenversionsnummer des Linker. |
| 4 |
4 |
SizeOfCode |
Die Größe des Codeabschnitts (Text) oder die Summe aller Codeabschnitte, wenn mehrere Abschnitte enthalten sind. |
| 8 |
4 |
SizeOfInitializedData |
Die Größe des initialisierten Datenabschnitts oder die Summe aller dieser Abschnitte, wenn mehrere Datenabschnitte sind. |
| 12 |
4 |
SizeOfUninitializedData |
Die Größe des Abschnitts für nicht initialisierte Daten (BSS) oder die Summe aller dieser Abschnitte, wenn mehrere BSS-Abschnitte verfügbar sind. |
| 16 |
4 |
AddressOfEntryPoint |
Die Adresse des Einstiegspunkts relativ zur Imagebasis, wenn die ausführbare Datei in den Arbeitsspeicher geladen wird. Bei Programmbildern ist dies die Startadresse. Bei Gerätetreibern ist dies die Adresse der Initialisierungsfunktion. Ein Einstiegspunkt ist für DLLs optional. Wenn kein Einstiegspunkt vorhanden ist, muss dieses Feld 0 (null) sein. |
| 20 |
4 |
BaseOfCode |
Die Adresse, die relativ zur Imagebasis des Codeanfangsabschnitts ist, wenn er in den Arbeitsspeicher geladen wird. |
PE32 enthält dieses zusätzliche Feld, das in PE32+ nicht vorhanden ist, und folgt BaseOfCode.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 24 |
4 |
BaseOfData |
Die Adresse, die relativ zur Imagebasis des Datenanfangsabschnitts ist, wenn er in den Arbeitsspeicher geladen wird. |
Optionale Header Windows-Specific Felder (nur Bild)
Die nächsten 21 Felder sind eine Erweiterung des optionalen COFF-Headerformats. Sie enthalten zusätzliche Informationen, die für den Linker und das Lader in der Windows.
| Offset (PE32/ PE32+) | Größe (PE32/ PE32+) | Feld | BESCHREIBUNG |
|---|---|---|---|
| 28/24 |
4/8 |
Imagebase |
Die bevorzugte Adresse des ersten Byte des Bilds beim Laden in den Arbeitsspeicher; muss ein Vielfaches von 64.000 sein. Der Standardwert für DLLs ist 0x10000000. Der Standardwert für Windows CE-EXEs ist 0x00010000. Der Standardwert für Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98 und Windows Me ist 0x00400000. |
| 32/32 |
4 |
SectionAlignment |
Die Ausrichtung (in Bytes) von Abschnitten beim Laden in den Arbeitsspeicher. Er muss größer oder gleich FileAlignment sein. Der Standard für die Architektur ist die Seitengröße. |
| 36/36 |
4 |
FileAlignment |
Der Ausrichtungsfaktor (in Byte), der verwendet wird, um die Rohdaten von Abschnitten in der Imagedatei auszurichten. Der Wert sollte eine Leistung von 2 zwischen 512 und 64.000 (einschließlich) haben. Der Standardwert liegt bei 512. Wenn sectionAlignment kleiner als die Seitengröße der Architektur ist, muss FileAlignment mit SectionAlignment übereinstimmen. |
| 40/40 |
2 |
MajorOperatingSystemVersion |
Die Hauptversionsnummer des erforderlichen Betriebssystems. |
| 42/42 |
2 |
MinorOperatingSystemVersion |
Die Nebenversionsnummer des erforderlichen Betriebssystems. |
| 44/44 |
2 |
MajorImageVersion |
Die Hauptversionsnummer des Images. |
| 46/46 |
2 |
MinorImageVersion |
Die Nebenversionsnummer des Images. |
| 48/48 |
2 |
MajorSubsystemVersion |
Die Hauptversionsnummer des Subsystems. |
| 50/50 |
2 |
MinorSubsystemVersion |
Die Nebenversionsnummer des Subsystems. |
| 52/52 |
4 |
Win32VersionValue |
Reserviert, muss 0 (null) sein. |
| 56/56 |
4 |
SizeOfImage |
Die Größe (in Bytes) des Bilds, einschließlich aller Header, während das Bild in den Arbeitsspeicher geladen wird. Es muss ein Vielfaches von SectionAlignment sein. |
| 60/60 |
4 |
SizeOfHeaders |
Die kombinierte Größe eines MS-DOS-Stubs, eines PE-Headers und von Abschnittsheadern, die auf ein Vielfaches von FileAlignment aufgerundet sind. |
| 64/64 |
4 |
Prüfsumme |
Die Prüfsumme der Bilddatei. Der Algorithmus zum Berechnen der Prüfsumme wird in die IMAGHELP.DLL. Folgendes wird zur Ladezeit auf Überprüfung überprüft: alle Treiber, alle dll-Dateien, die beim Start geladen werden, und alle DLLs, die in einen kritischen Windows werden. |
| 68/68 |
2 |
Subsystem |
Das Subsystem, das zum Ausführen dieses Images erforderlich ist. Weitere Informationen finden Sie unter Windows Subsystem. |
| 70/70 |
2 |
DllCharacteristics |
Weitere Informationen finden Sie weiter unten in dieser Spezifikation unter DLL-Merkmale. |
| 72/72 |
4/8 |
SizeOfStackReserve |
Die Größe des Stapels, der reserviert werden soll. Nur Für SizeOfStackCommit wird ein Committed ausführen. Der Rest wird seite für Seite zur Verfügung gestellt, bis die Reservegröße erreicht ist. |
| 76/80 |
4/8 |
SizeOfStackCommit |
Dier Größe des Stapels, für den ein Commit ausgeführt wird. |
| 80/88 |
4/8 |
SizeOfHeapReserve |
Die Größe des Speicherplatzes für den lokalen Heap, der reserviert werden soll. Es wird nur ein Committed für SizeOfHeapCommit verwendet. Der Rest wird seite für Seite zur Verfügung gestellt, bis die Reservegröße erreicht ist. |
| 84/96 |
4/8 |
SizeOfHeapCommit |
Die Größe des Speicherplatzes für den lokalen Heap, für den ein Commit ausgeführt werden soll. |
| 88/104 |
4 |
LoaderFlags |
Reserviert, muss 0 (null) sein. |
| 92/108 |
4 |
NumberOfRvaAndSizes |
Die Anzahl der Datenverzeichniseinträge im Rest des optionalen Headers. Jeder beschreibt einen Speicherort und eine Größe. |
Windows Subsystem
Die folgenden Werte, die für das Feld Subsystem des optionalen Headers definiert sind, bestimmen, Windows Subsystem (falls vorhanden) zum Ausführen des Images erforderlich ist.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ SUBSYSTEM _ UNKNOWN |
0 |
Ein unbekanntes Subsystem |
| IMAGE _ SUBSYSTEM _ NATIVE |
1 |
Gerätetreiber und native Windows Prozesse |
| _WINDOWS-GUI DES IMAGE-SUBSYSTEMS _ _ |
2 |
Das Windows GUI-Subsystem (Graphical User Interface) |
| IMAGE _ SUBSYSTEM _ WINDOWS _ CUI |
3 |
Das Windows Zeichensubsystem |
| IMAGE _ SUBSYSTEM _ OS2 _ CUI |
5 |
Das Betriebssystem/2-Zeichensubsystem |
| IMAGE _ SUBSYSTEM _ POSIX _ CUI |
7 |
Das Posix-Zeichensubsystem |
| _ _ SYSTEMEIGENES IMAGESUBSYSTEMFENSTER _ |
8 |
Nativer Win9x-Treiber |
| IMAGE _ SUBSYSTEM _ WINDOWS _ CE _ GUI |
9 |
Windows CE |
| EFI-ANWENDUNG FÜR DAS _ IMAGESUBSYSTEM _ _ |
10 |
Eine EFI-Anwendung (Extensible Firmware Interface) |
| _ _ _ EFI-STARTDIENSTTREIBER _ FÜR DAS IMAGESUBSYSTEM _ |
11 |
Ein EFI-Treiber mit Startdiensten |
| _ _ EFI-LAUFZEITTREIBER FÜR DAS IMAGESUBSYSTEM _ _ |
12 |
Einen EFI-Treiber mit Laufzeitdiensten |
| IMAGE _ SUBSYSTEM _ EFI _ ROM |
13 |
Ein EFI-ROM-Image |
| _BILDSUBSYSTEM _ XBOX |
14 |
XBOX |
| _ _ WINDOWS-STARTANWENDUNG FÜR DAS IMAGESUBSYSTEM _ _ |
16 |
Windows Startanwendung. |
DLL-Merkmale
Die folgenden Werte werden für das Feld DllCharacteristics des optionalen Headers definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| 0x0001 |
Reserviert, muss 0 (null) sein. |
|
| 0x0002 |
Reserviert, muss 0 (null) sein. |
|
| 0x0004 |
Reserviert, muss 0 (null) sein. |
|
| 0x0008 |
Reserviert, muss 0 (null) sein. |
|
| IMAGE _ DLLCHARACTERISTICS _ HIGH _ ENTROPY _ VA |
0x0020 |
Das Image kann einen virtuellen 64-Bit-Adressraum mit hoher Entropie verarbeiten. |
| IMAGE _ DLLCHARACTERISTICS_ DYNAMISCHE _ BASIS |
0x0040 |
DIE DLL kann zur Ladezeit verschoben werden. |
| IMAGE _ DLLCHARACTERISTICS_ INTEGRITÄT ERZWINGEN _ |
0x0080 |
Überprüfungen der Codeintegrität werden erzwungen. |
| IMAGE _ DLLCHARACTERISTICS_ NX _ COMPAT |
0x0100 |
Das Image ist NX-kompatibel. |
| IMAGE _ DLLCHARACTERISTICS _ NO _ ISOLATION |
0x0200 |
Isolationsbewusst, aber isolieren Sie das Image nicht. |
| IMAGE _ DLLCHARACTERISTICS _ NO _ SEH |
0x0400 |
Verwendet keine strukturierte Ausnahmebehandlung (SE). In diesem Image kann kein SE Handler aufgerufen werden. |
| IMAGE _ DLLCHARACTERISTICS _ NO _ BIND |
0x0800 |
Binden Sie das Image nicht. |
| IMAGE _ DLLCHARACTERISTICS _ APPCONTAINER |
0x1000 |
Das Image muss in einem AppContainer ausgeführt werden. |
| IMAGE _ DLLCHARACTERISTICS _ WDM _ DRIVER |
0x2000 |
Ein WDM-Treiber. |
| IMAGE _ DLLCHARACTERISTICS _ GUARD _ CF |
0x4000 |
Image unterstützt Control Flow Guard. |
| IMAGE _ DLLCHARACTERISTICS _ TERMINAL _ SERVER _ AWARE |
0x8000 |
Terminalserver-fähigen. |
Optionale Headerdatenverzeichnisse (nur Bild)
Jedes Datenverzeichnis gibt die Adresse und Größe einer Tabelle oder Zeichenfolge an, die Windows verwendet. Diese Datenverzeichniseinträge werden alle in den Arbeitsspeicher geladen, sodass das System sie zur Laufzeit verwenden kann. Ein Datenverzeichnis ist ein 8-Byte-Feld mit der folgenden Deklaration:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
Das erste Feld, VirtualAddress, ist tatsächlich das RVA der Tabelle. Das RVA ist die Adresse der Tabelle relativ zur Basisadresse des Images, wenn die Tabelle geladen wird. Das zweite Feld gibt die Größe in Bytes an. Die Datenverzeichnisse, die den letzten Teil des optionalen Headers bilden, sind in der folgenden Tabelle aufgeführt.
Beachten Sie, dass die Anzahl der Verzeichnisse nicht festgelegt ist. Bevor Sie nach einem bestimmten Verzeichnis suchen, überprüfen Sie das Feld NumberOfRvaAndSizes im optionalen Header.
Gehen Sie außerdem nicht davon aus, dass die RVAs in dieser Tabelle auf den Anfang eines Abschnitts zeigen oder dass die Abschnitte, die bestimmte Tabellen enthalten, bestimmte Namen haben.
| Offset (PE/PE32+) | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 96/112 |
8 |
Tabelle exportieren |
Adresse und Größe der Exporttabelle. Weitere Informationen finden Sie im Abschnitt .edata (nur Bild). |
| 104/120 |
8 |
Tabelle importieren |
Die Adresse und Größe der Importtabelle. Weitere Informationen finden Sie im Abschnitt .idata. |
| 112/128 |
8 |
Ressourcentabelle |
Adresse und Größe der Ressourcentabelle. Weitere Informationen finden Sie im Rsrc-Abschnitt. |
| 120/136 |
8 |
Ausnahmetabelle |
Adresse und Größe der Ausnahmetabelle. Weitere Informationen finden Sie im PDATA-Abschnitt. |
| 128/144 |
8 |
Zertifikattabelle |
Adresse und Größe der Attributzertifikattabelle. Weitere Informationen finden Sie unter Die Attributzertifikattabelle (nur Bild). |
| 136/152 |
8 |
Basisverlagerungstabelle |
Die Adresse und Größe der Basisverlagerungstabelle. Weitere Informationen finden Sie im Abschnitt .reloc (nur Image). |
| 144/160 |
8 |
Debug |
Die Startadresse und Größe der Debugdaten. Weitere Informationen finden Sie im Abschnitt .debug. |
| 152/168 |
8 |
Architektur |
Reserviert, muss 0 sein |
| 160/176 |
8 |
Global Ptr |
Die RVA des Werts, der im globalen Zeigerregister gespeichert werden soll. Der Größen member dieser Struktur muss auf 0 (null) festgelegt werden. |
| 168/184 |
8 |
TLS-Tabelle |
Die Adresse und Größe der TABELLE für den lokalen Threadspeicher (TLS). Weitere Informationen finden Sie im TLS-Abschnitt. |
| 176/192 |
8 |
Laden der Konfigurationstabelle |
Adresse und Größe der Lastenkonfigurationstabelle. Weitere Informationen finden Sie unter Die Ladekonfigurationsstruktur (nur Image). |
| 184/200 |
8 |
Gebundener Import |
Die Adresse und Größe der gebundenen Importtabelle. |
| 192/208 |
8 |
IAT |
Adresse und Größe der Importadressentabelle. Weitere Informationen finden Sie unter Import Address Table. |
| 200/216 |
8 |
Deskriptor für verzögerten Import |
Die Verzögerte Importdeskriptoradresse und -größe. Weitere Informationen finden Sie unter Verzögertes Laden von Importtabellen (nur Image). |
| 208/224 |
8 |
CLR-Laufzeitheader |
Die Adresse und Größe des CLR-Laufzeitheaders. Weitere Informationen finden Sie unter Der Cormeta-Abschnitt (nur Objekt). |
| 216/232 |
8 |
Reserviert, muss 0 (null) sein |
Der Eintrag Zertifikattabelle verweist auf eine Tabelle mit Attributzertifikaten. Diese Zertifikate werden nicht als Teil des Images in den Arbeitsspeicher geladen. Daher ist das erste Feld dieses Eintrags, bei dem es sich normalerweise um ein RVA handelt, stattdessen ein Dateizeiger.
Abschnittstabelle (Abschnittsheader)
Jede Zeile der Abschnittstabelle ist tatsächlich ein Abschnittsheader. Diese Tabelle folgt unmittelbar auf den optionalen Header( sofern verfügbar). Diese Positionierung ist erforderlich, da der Dateiheader keinen direkten Zeiger auf die Abschnittstabelle enthält. Stattdessen wird die Position der Abschnittstabelle bestimmt, indem die Position des ersten Byte nach den Headern berechnet wird. Stellen Sie sicher, dass Sie die Größe des optionalen Headers wie im Dateiheader angegeben verwenden.
Die Anzahl der Einträge in der Abschnittstabelle wird durch das NumberOfSections-Feld im Dateiheader angegeben. Einträge in der Abschnittstabelle werden beginnend mit eins nummeriert (1). Die Code- und Datenspeicherabschnittseinträge befinden sich in der vom Linker ausgewählten Reihenfolge.
In einer Bilddatei müssen die VAs für Abschnitte vom Linker zugewiesen werden, damit sie in aufsteigender Reihenfolge und nebeneinander liegen, und sie müssen ein Vielfaches des SectionAlignment-Werts im optionalen Header sein.
Jeder Abschnittsheader (Abschnittstabelleneintrag) hat das folgende Format für insgesamt 40 Bytes pro Eintrag.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
8 |
Name |
Eine UTF-8-codierte 8-Byte-Zeichenfolge mit NULL-Aufgefülltes. Wenn die Zeichenfolge genau 8 Zeichen lang ist, gibt es keinen abschließenden NULL-Wert. Bei längeren Namen enthält dieses Feld einen Schrägstrich (/), gefolgt von einer ASCII-Darstellung einer Dezimalzahl, die ein Offset in die Zeichenfolgentabelle ist. Ausführbare Bilder verwenden keine Zeichenfolgentabelle und unterstützen keine Abschnittsnamen, die länger als 8 Zeichen sind. Lange Namen in Objektdateien werden abgeschnitten, wenn sie an eine ausführbare Datei ausgegeben werden. |
| 8 |
4 |
VirtualSize |
Die Gesamtgröße des Abschnitts beim Laden in den Arbeitsspeicher. Wenn dieser Wert größer als SizeOfRawData ist, wird der Abschnitt mit null Aufgefüllt. Dieses Feld ist nur für ausführbare Bilder gültig und sollte für Objektdateien auf 0 festgelegt werden. |
| 12 |
4 |
VirtualAddress |
Bei ausführbaren Bildern die Adresse des ersten Byte des Abschnitts relativ zur Imagebasis, wenn der Abschnitt in den Arbeitsspeicher geladen wird. Bei Objektdateien ist dieses Feld die Adresse des ersten Byte, bevor die Verschiebung angewendet wird. Der Einfachheit halber sollten Compiler dies auf 0 (null) festlegen. Andernfalls handelt es sich um einen beliebigen Wert, der während der Verschiebung von Offsets subtrahiert wird. |
| 16 |
4 |
SizeOfRawData |
Die Größe des Abschnitts (für Objektdateien) oder die Größe der initialisierten Daten auf dem Datenträger (für Imagedateien). Bei ausführbaren Bildern muss dies ein Vielfaches von FileAlignment aus dem optionalen Header sein. Wenn dieser kleiner als VirtualSize ist, wird der Rest des Abschnitts mit null gefüllt. Da das Feld SizeOfRawData gerundet ist, das Feld VirtualSize jedoch nicht, ist es möglich, dass SizeOfRawData auch größer als VirtualSize ist. Wenn ein Abschnitt nur nicht initialisierte Daten enthält, sollte dieses Feld 0 (null) sein. |
| 20 |
4 |
PointerToRawData |
Der Dateizeiger auf die erste Seite des Abschnitts in der COFF-Datei. Bei ausführbaren Bildern muss dies ein Vielfaches von FileAlignment aus dem optionalen Header sein. Bei Objektdateien sollte der Wert an einer 4-Byte-Grenze ausgerichtet werden, um eine optimale Leistung zu erzielen. Wenn ein Abschnitt nur nicht initialisierte Daten enthält, sollte dieses Feld 0 (null) sein. |
| 24 |
4 |
PointerToRelocations |
Der Dateizeiger auf den Anfang der Verschiebungseinträge für den Abschnitt. Dieser Wert wird für ausführbare Images auf 0 (null) festgelegt, oder , wenn keine Verschiebungen vorhanden sind. |
| 28 |
4 |
PointerToLinenumbers |
Der Dateizeiger auf den Anfang der Zeilennummerneinträge für den Abschnitt. Dies wird auf 0 (null) festgelegt, wenn keine COFF-Zeilennummern vorhanden sind. Dieser Wert sollte für ein Image 0 (null) sein, da COFF-Debuginformationen veraltet sind. |
| 32 |
2 |
NumberOfRelocations |
Die Anzahl der Verschiebungseinträge für den Abschnitt. Dies ist für ausführbare Images auf 0 (null) festgelegt. |
| 34 |
2 |
NumberOfLinenumbers |
Die Anzahl der Zeilennummerneinträge für den Abschnitt. Dieser Wert sollte für ein Image 0 (null) sein, da COFF-Debuginformationen veraltet sind. |
| 36 |
4 |
Merkmale |
Die Flags, die die Merkmale des Abschnitts beschreiben. Weitere Informationen finden Sie unter Abschnittsflags. |
Abschnittsflags
Die Abschnittsflags im Feld Merkmale des Abschnittsheaders geben die Merkmale des Abschnitts an.
| Flag | Wert | BESCHREIBUNG |
|---|---|---|
| 0x00000000 |
Für die zukünftige Verwendung reserviert. |
|
| 0x00000001 |
Für die zukünftige Verwendung reserviert. |
|
| 0x00000002 |
Für die zukünftige Verwendung reserviert. |
|
| 0x00000004 |
Für die zukünftige Verwendung reserviert. |
|
| IMAGE _ SCN _ TYPE _ NO _ PAD |
0x00000008 |
Der Abschnitt sollte nicht an die nächste Grenze aufgefüllt werden. Dieses Flag ist veraltet und wird durch IMAGE _ SCN _ ALIGN _ 1BYTES ersetzt. Dies ist nur für Objektdateien gültig. |
| 0x00000010 |
Für die zukünftige Verwendung reserviert. |
|
| IMAGE _ SCN _ CNT _ CODE |
0x00000020 |
Der Abschnitt enthält ausführbaren Code. |
| IMAGE _ SCN _ CNT _ INITIALIZED _ DATA |
0x00000040 |
Der Abschnitt enthält initialisierte Daten. |
| IMAGE _ SCN _ CNT _ UNINITIALIZED _ DATA |
0x00000080 |
Der Abschnitt enthält nicht initialisierte Daten. |
| IMAGE _ SCN _ LNK _ OTHER |
0x00000100 |
Für die zukünftige Verwendung reserviert. |
| IMAGE _ SCN _ LNK _ INFO |
0x00000200 |
Der Abschnitt enthält Kommentare oder andere Informationen. Der Abschnitt .dre wies diesen Typ auf. Dies gilt nur für Objektdateien. |
| 0x00000400 |
Für die zukünftige Verwendung reserviert. |
|
| IMAGE _ SCN _ LNK _ REMOVE |
0x00000800 |
Der Abschnitt wird nicht Teil des Images. Dies ist nur für Objektdateien gültig. |
| IMAGE _ SCN _ LNK _ COMDAT |
0x00001000 |
Der Abschnitt enthält COMDAT-Daten. Weitere Informationen finden Sie unter COMDAT-Abschnitte (nur Objekt). Dies ist nur für Objektdateien gültig. |
| IMAGE _ SCN _ GPREL |
0x00008000 |
Der Abschnitt enthält Daten, auf die über den globalen Zeiger (GP) verwiesen wird. |
| IMAGE _ SCN _ MEM _ PURGEABLE |
0x00020000 |
Für die zukünftige Verwendung reserviert. |
| IMAGE _ SCN _ MEM _ 16BIT |
0x00020000 |
Für die zukünftige Verwendung reserviert. |
| IMAGE _ SCN _ MEM _ LOCKED |
0x00040000 |
Für die zukünftige Verwendung reserviert. |
| IMAGE _ SCN _ MEM _ PRELOAD |
0x00080000 |
Für die zukünftige Verwendung reserviert. |
| IMAGE _ SCN _ ALIGN _ 1BYTES |
0x00100000 |
Ausrichten von Daten an einer 1-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 2BYTES |
0x00200000 |
Ausrichten von Daten an einer 2-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 4BYTES |
0x00300000 |
Ausrichten von Daten an einer 4-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 8BYTES |
0x00400000 |
Ausrichten von Daten an einer 8-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 16BYTES |
0x00500000 |
Ausrichten von Daten an einer 16-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 32BYTES |
0x00600000 |
Ausrichten von Daten an einer 32-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 64BYTES |
0x00700000 |
Ausrichten von Daten an einer 64-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 128BYTES |
0x00800000 |
Ausrichten von Daten an einer 128-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 256BYTES |
0x00900000 |
Ausrichten von Daten an einer 256-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 512BYTES |
0x00A00000 |
Ausrichten von Daten an einer 512-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 1024BYTES |
0x00B00000 |
Ausrichten von Daten an einer 1024-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 2048BYTES |
0x00C00000 |
Ausrichten von Daten an einer 2048-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 4096BYTES |
0x00D00000 |
Ausrichten von Daten an einer 4096-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ ALIGN _ 8192BYTES |
0x00E00000 |
Ausrichten von Daten an einer 8192-Byte-Grenze. Nur für Objektdateien gültig. |
| IMAGE _ SCN _ LNK _ NRELOC _ OVFL |
0x01000000 |
Der Abschnitt enthält erweiterte Verschiebungen. |
| IMAGE _ SCN _ MEM _ DISCARDABLE |
0x02000000 |
Der Abschnitt kann bei Bedarf verworfen werden. |
| IMAGE _ SCN _ MEM _ NOT _ CACHED |
0x04000000 |
Der Abschnitt kann nicht zwischengespeichert werden. |
| IMAGE _ SCN _ MEM _ NOT _ PAGED |
0x08000000 |
Der Abschnitt ist nicht aussetzbar. |
| IMAGE _ SCN _ MEM _ SHARED |
0x10000000 |
Der Abschnitt kann im Arbeitsspeicher freigegeben werden. |
| IMAGE _ SCN _ MEM _ EXECUTE |
0x20000000 |
Der Abschnitt kann als Code ausgeführt werden. |
| IMAGE _ SCN _ MEM _ READ |
0x40000000 |
Der Abschnitt kann gelesen werden. |
| IMAGE _ SCN _ MEM _ WRITE |
0x80000000 |
In den Abschnitt kann geschrieben werden. |
IMAGE _ SCN _ LNK _ NRELOC OVFL gibt an, dass die Anzahl der Verschiebungen für den Abschnitt die 16 Bits überschreitet, die für ihn _ im Abschnittsheader reserviert sind. Wenn das Bit festgelegt ist und das Feld NumberOfRelocations im Abschnittsheader 0xffff ist, wird die tatsächliche Anzahl der Verschiebungen im 32-Bit-Feld VirtualAddress der ersten Verschiebung gespeichert. Es ist ein Fehler, wenn IMAGE _ SCN _ LNK _ NRELOC OVFL festgelegt ist und weniger als 0xffff im Abschnitt _ angezeigt werden.
Grouped Sections (Object Only)
Das "$"? -Zeichen (Dollarzeichen) hat eine besondere Interpretation in Abschnittsnamen in Objektdateien.
Wenn der Bildabschnitt bestimmt wird, der den Inhalt eines Objektabschnitts enthält, verwirft der Linker das "$"? und alle zeichen, die darauf folgen. Daher ein Objektabschnitt mit dem Namen . text$X trägt tatsächlich zum Textabschnitt im Bild bei.
Die Zeichen, die auf "$" folgen? bestimmt die Reihenfolge der Beiträge zum Bildabschnitt. Alle Beiträge mit demselben Objektabschnittsnamen werden zusammenhängend im Bild zugeordnet, und die Beiträge werden in lexikalischer Reihenfolge nach Objektabschnittsnamen sortiert. Aus diesem Grund werden alle Objekte in Objektdateien mit dem Abschnittsnamen .text$X nach den .text$W-Beiträgen und vor den .text$Y-Beiträgen zusammenkommen.
Der Abschnittsname in einer Bilddatei enthält nie "$"? befinden.
Anderer Inhalt der Datei
- Abschnittsdaten
- COFF-Verschiebungen (nur Objekt)
- COFF-Zeilennummern (veraltet)
- COFF-Symboltabelle
- Hilfssymboldatensätze
- COFF-Zeichenfolgentabelle
- Attributzertifikattabelle (nur Bild)
- Verzögertes Laden von Importtabellen (nur Image)
Die bisher beschriebenen Datenstrukturen bis einschließlich des optionalen Headers befinden sich alle an einem festen Offset vom Anfang der Datei (oder vom PE-Header, wenn die Datei ein Bild ist, das einen MS-DOS-Stub enthält).
Der Rest eines COFF-Objekts oder einer Bilddatei enthält Datenblöcke, die nicht notwendigerweise an einem bestimmten Dateioffset liegen. Stattdessen werden die Speicherorte durch Zeiger im optionalen Header oder einem Abschnittsheader definiert.
Eine Ausnahme sind Bilder mit einem SectionAlignment-Wert, der kleiner als die Seitengröße der Architektur ist (4 K für Intel x86 und für MIPS und 8 K für Itanium). Eine Beschreibung von SectionAlignment finden Sie unter OptionalEr Header (nur Bild). In diesem Fall gelten Einschränkungen für den Dateioffset der Abschnittsdaten, wie in Abschnitt 5.1, "Abschnittsdaten" beschrieben. Eine weitere Ausnahme ist, dass Attributzertifikat- und Debuginformationen ganz am Ende einer Imagedatei platziert werden müssen, während die Attributzertifikattabelle unmittelbar vor dem Debugabschnitt steht, da das Lademodul diese nicht dem Arbeitsspeicher zuteilt. Die Regel über Attributzertifikat- und Debuginformationen gilt jedoch nicht für Objektdateien.
Abschnittsdaten
Initialisierte Daten für einen Abschnitt bestehen aus einfachen Byteblöcken. Für Abschnitte, die alle Nullen enthalten, müssen die Abschnittsdaten jedoch nicht eingeschlossen werden.
Die Daten für jeden Abschnitt befinden sich am Dateioffset, der durch das Feld PointerToRawData im Abschnittsheader angegeben wurde. Die Größe dieser Daten in der Datei wird durch das Feld SizeOfRawData angegeben. Wenn SizeOfRawData kleiner als VirtualSize ist, wird der Rest mit Nullen aufschlossen.
In einer Bilddatei müssen die Abschnittsdaten an einer Grenze ausgerichtet werden, wie im Feld FileAlignment im optionalen Header angegeben. Abschnittsdaten müssen in der Reihenfolge der RVA-Werte für die entsprechenden Abschnitte angezeigt werden (wie die einzelnen Abschnittsheader in der Abschnittstabelle).
Es gibt zusätzliche Einschränkungen für Bilddateien, wenn der SectionAlignment-Wert im optionalen Header kleiner als die Seitengröße der Architektur ist. Für solche Dateien muss der Speicherort der Abschnittsdaten in der Datei mit dem Speicherort im Arbeitsspeicher übereinstimmen, wenn das Bild geladen wird, sodass der physische Offset für Abschnittsdaten mit dem RVA identisch ist.
COFF-Verschiebungen (nur Objekt)
Objektdateien enthalten COFF-Verschiebungen, die angeben, wie die Abschnittsdaten geändert werden sollen, wenn sie in der Bilddatei platziert und anschließend in den Arbeitsspeicher geladen werden.
Bilddateien enthalten keine COFF-Verschiebungen, da allen Referenzsymbolen bereits Adressen in einem flachen Adressraum zugewiesen wurden. Ein Image enthält Verschiebungsinformationen in Form von Basisverlagerungen im Abschnitt .reloc (es sei denn, das Image verfügt über das ATTRIBUT IMAGE _ FILE _ RELOCS _ STRIPPED). Weitere Informationen finden Sie im Abschnitt .reloc (nur Image).
Für jeden Abschnitt in einer Objektdatei enthält ein Array von Datensätzen fester Länge die COFF-Verschiebungen des Abschnitts. Die Position und Länge des Arrays werden im Abschnittsheader angegeben. Jedes Element des Arrays hat das folgende Format.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
VirtualAddress |
Die Adresse des Elements, auf das die Verschiebung angewendet wird. Dies ist der Offset vom Anfang des Abschnitts plus dem Wert des RVA/Offset-Felds des Abschnitts. Siehe Abschnittstabelle (Abschnittsheader). Wenn das erste Byte des Abschnitts beispielsweise die Adresse 0x10, hat das dritte Byte die Adresse 0x12. |
| 4 |
4 |
SymbolTableIndex |
Ein nullbasierter Index in der Symboltabelle. Dieses Symbol gibt die Adresse an, die für die Verschiebung verwendet werden soll. Wenn das angegebene Symbol über eine Abschnittsspeicherklasse verfügt, ist die Adresse des Symbols die Adresse mit dem ersten Abschnitt desselben Namens. |
| 8 |
2 |
type |
Ein -Wert, der die Art der Verschiebung angibt, die ausgeführt werden soll. Gültige Verschiebungstypen hängen vom Computertyp ab. Weitere Informationen finden Sie unter Typindikatoren. |
Wenn das Symbol, auf das durch das Feld SymbolTableIndex verwiesen wird, über die Speicherklasse IMAGE SYM CLASS SECTION verfügt, ist die Adresse des Symbols der _ _ Anfang des _ Abschnitts. Der Abschnitt befindet sich in der Regel in derselben Datei, außer wenn die Objektdatei Teil eines Archivs (Bibliothek) ist. In diesem Fall ist der Abschnitt in jeder anderen Objektdatei im Archiv zu finden, die über denselben Archivmitgliedsnamen wie die aktuelle Objektdatei verfügt. (Die Beziehung mit dem Namen des Archivmitglieds wird beim Verknüpfen von Importtabellen verwendet, d.h. im Abschnitt .idata.)
Typindikatoren
Das Feld Typ des Verschiebungsdatensatz gibt an, welche Art von Verschiebung durchgeführt werden soll. Für jeden Computertyp werden unterschiedliche Verschiebungstypen definiert.
x64-Prozessoren
Die folgenden Verschiebungstypindikatoren werden für x64- und kompatible Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ AMD64 _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ AMD64 _ ADDR64 |
0x0001 |
Die 64-Bit-Va des Verschiebungsziels. |
| IMAGE _ REL _ AMD64 _ ADDR32 |
0x0002 |
Die 32-Bit-Va des Verschiebungsziels. |
| IMAGE _ REL _ AMD64 _ ADDR32NB |
0x0003 |
Die 32-Bit-Adresse ohne Imagebasis (RVA). |
| IMAGE _ REL _ AMD64 _ REL32 |
0x0004 |
Die relative 32-Bit-Adresse aus dem Byte nach der Verschiebung. |
| IMAGE _ REL _ AMD64 _ REL32 _ 1 |
0x0005 |
Die 32-Bit-Adresse relativ zum Byteabstand 1 von der Verschiebung. |
| IMAGE _ REL _ AMD64 _ REL32 _ 2 |
0x0006 |
Die 32-Bit-Adresse relativ zum Byteabstand 2 von der Verschiebung. |
| IMAGE _ REL _ AMD64 _ REL32 _ 3 |
0x0007 |
Die 32-Bit-Adresse relativ zum Byteabstand 3 von der Verschiebung. |
| IMAGE _ REL _ AMD64 _ REL32 _ 4 |
0x0008 |
Die 32-Bit-Adresse relativ zum Byteabstand 4 von der Verschiebung. |
| IMAGE _ REL _ AMD64 _ REL32 _ 5 |
0x0009 |
Die 32-Bit-Adresse relativ zum Byteabstand 5 von der Verschiebung. |
| ABSCHNITT "IMAGE _ REL _ AMD64" _ |
0x000A |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ AMD64 _ SECREL |
0x000B |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ AMD64 _ SECREL7 |
0x000C |
Ein 7-Bit-Offset ohne Vorzeichen von der Basis des Abschnitts, der das Ziel enthält. |
| IMAGE _ REL _ AMD64 _ TOKEN |
0x000D |
CLR-Token. |
| IMAGE _ REL _ AMD64 _ SREL32 |
0x000E |
Ein 32-Bit-Wert, der von einer Spanne signiert ist und in das -Objekt ausgegeben wird. |
| IMAGE _ REL _ AMD64-PAAR _ |
0x000F |
Ein Paar, das unmittelbar auf jeden span-abhängigen Wert folgen muss. |
| IMAGE _ REL _ AMD64 _ SSPAN32 |
0x0010 |
Ein 32-Bit-Wert, der von einer Spanne signiert ist und zur Linkzeit angewendet wird. |
ARM-Prozessoren
Die folgenden Indikatoren für den Verschiebungstyp werden für ARM-Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ ARM _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ ARM _ ADDR32 |
0x0001 |
Die 32-Bit-Va des Ziels. |
| IMAGE _ REL _ ARM _ ADDR32NB |
0x0002 |
Die 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ ARM _ BRANCH24 |
0x0003 |
Die relative 24-Bit-Verschiebung zum Ziel. |
| IMAGE _ REL _ ARM _ BRANCH11 |
0x0004 |
Der Verweis auf einen Unterroutinenaufruf. Der Verweis besteht aus zwei 16-Bit-Anweisungen mit 11-Bit-Offsets. |
| IMAGE _ REL _ ARM _ REL32 |
0x000A |
Die relative 32-Bit-Adresse aus dem Byte nach der Verschiebung. |
| _ARM-ABSCHNITT "IMAGE _ REL" _ |
0x000E |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ ARM _ SECREL |
0x000F |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ ARM _ MOV32 |
0x0010 |
Die 32-Bit-VA des Ziels. Diese Verschiebung wird mithilfe einer MOVW-Anweisung für die niedrigen 16 Bits angewendet, gefolgt von einem MOVT für die hohen 16 Bits. |
| BILD _ REL _ THUMB _ MOV32 |
0x0011 |
Die 32-Bit-VA des Ziels. Diese Verschiebung wird mithilfe einer MOVW-Anweisung für die niedrigen 16 Bits angewendet, gefolgt von einem MOVT für die hohen 16 Bits. |
| IMAGE _ REL _ THUMB _ BRANCH20 |
0x0012 |
Die Anweisung wird mit der relativen Verschiebung von 21 Bit zum 2-Byte-ausgerichteten Ziel korrigiert. Das am wenigsten signifikante Teil der Verschiebung ist immer 0 (null) und wird nicht gespeichert. Diese Verschiebung entspricht einer bedingte 32-Bit-Thumb-2-B-Anweisung. |
| Nicht verwendet |
0x0013 |
|
| IMAGE _ REL _ THUMB _ BRANCH24 |
0x0014 |
Die Anweisung wird mit der relativen Verschiebung von 25 Bit zum 2-Byte-ausgerichteten Ziel korrigiert. Das am wenigsten signifikante Teil der Verschiebung ist 0 (null) und wird nicht gespeichert. Diese Verschiebung entspricht einer Thumb-2 B-Anweisung. |
| IMAGE _ REL _ THUMB _ BLX23 |
0x0015 |
Die Anweisung wird mit der relativen Verschiebung von 25 Bit zum 4-Byte-ausgerichteten Ziel korrigiert. Die niedrigen 2 Bits der Verschiebung sind 0 (null) und werden nicht gespeichert. Diese Verschiebung entspricht einer Thumb-2 BLX-Anweisung. |
| IMAGE _ REL _ ARM _ PAIR |
0x0016 |
Die Verschiebung ist nur gültig, wenn sie unmittelbar auf eine _ ARM-REFHI- oder _ THUMB-REFHI folgt. SymbolTableIndex enthält eine Verschiebung und keinen Index in der Symboltabelle. |
ARM64-Prozessoren
Die folgenden Verlagerungstypindikatoren sind für ARM64-Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ ARM64 _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ ARM64 _ ADDR32 |
0x0001 |
Die 32-Bit-VA des Ziels. |
| IMAGE _ REL _ ARM64 _ ADDR32NB |
0x0002 |
Das 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ ARM64 _ BRANCH26 |
0x0003 |
Die relative Verschiebung von 26 Bit zum Ziel für B- und BL-Anweisungen. |
| IMAGE _ REL _ ARM64 _ PAGEBASE _ REL21 |
0x0004 |
Die Seitenbasis des Ziels für die ADRP-Anweisung. |
| IMAGE _ REL _ ARM64 _ REL21 |
0x0005 |
Die relative Verschiebung von 12 Bit zum Ziel für die Anweisung ADR |
| IMAGE _ REL _ ARM64 _ PAGEOFFSET _ 12A |
0x0006 |
Der 12-Bit-Seitenoffset des Ziels, für Anweisungen ADD/ADDS (direkt) mit null Verschiebung. |
| IMAGE _ REL _ ARM64 _ PAGEOFFSET _ 12L |
0x0007 |
Der 12-Bit-Seitenoffset des Ziels für die Anweisung LDR (indexed, unsigned immediate). |
| IMAGE _ REL _ ARM64 _ SECREL |
0x0008 |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ ARM64 _ SECREL _ LOW12A |
0x0009 |
Bit 0:11 des Abschnittsoffsets des Ziels, für Anweisungen ADD/ADDS (direkt) mit Nullverschiebung. |
| IMAGE _ REL _ ARM64 _ SECREL _ HIGH12A |
0x000A |
Bit 12:23 des Abschnittsoffsets des Ziels, für Anweisungen ADD/ADDS (direkt) mit Nullverschiebung. |
| IMAGE _ REL _ ARM64 _ SECREL _ LOW12L |
0x000B |
Bit 0:11 des Abschnittsoffsets des Ziels für die Anweisung LDR (indexed, unsigned immediate). |
| IMAGE _ REL _ ARM64 _ TOKEN |
0x000C |
CLR-Token. |
| IMAGE _ REL _ ARM64 _ SECTION |
0x000D |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ ARM64 _ ADDR64 |
0x000E |
Die 64-Bit-Va des Verschiebungsziels. |
| IMAGE _ REL _ ARM64 _ BRANCH19 |
0x000F |
Der 19-Bit-Offset zum Verschiebungsziel für die bedingte B-Anweisung. |
| IMAGE _ REL _ ARM64 _ BRANCH14 |
0x0010 |
Der 14-Bit-Offset zum Verschiebungsziel für die Anweisungen TBZ und TBNZ. |
| IMAGE _ REL _ ARM64 _ REL32 |
0x0011 |
Die relative 32-Bit-Adresse aus dem Byte nach der Verschiebung. |
SuperH-Prozessoren
Die folgenden Verlagerungstypindikatoren sind für SH3- und SH4-Prozessoren definiert. SH5-spezifische Verschiebungen werden als SHM (SH Media) bezeichnet.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ SH3 _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ SH3 _ DIRECT16 |
0x0001 |
Ein Verweis auf die 16-Bit-Position, die die Va des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ DIRECT32 |
0x0002 |
Die 32-Bit-Va des Zielsymbols. |
| IMAGE _ REL _ SH3 _ DIRECT8 |
0x0003 |
Ein Verweis auf die 8-Bit-Position, die die Va des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ DIRECT8 _ WORD |
0x0004 |
Ein Verweis auf die 8-Bit-Anweisung, die die effektive 16-Bit-Va des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ DIRECT8 _ LONG |
0x0005 |
Ein Verweis auf die 8-Bit-Anweisung, die die effektive 32-Bit-Va des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ DIRECT4 |
0x0006 |
Ein Verweis auf die 8-Bit-Position, deren niedrige 4 Bits die Va des Zielsymbols enthalten. |
| IMAGE _ REL _ SH3 _ DIRECT4 _ WORD |
0x0007 |
Ein Verweis auf die 8-Bit-Anweisung, deren niedrige 4 Bits die effektive 16-Bit-Va des Zielsymbols enthalten. |
| IMAGE _ REL _ SH3 _ DIRECT4 _ LONG |
0x0008 |
Ein Verweis auf die 8-Bit-Anweisung, deren niedrige 4 Bits die effektive 32-Bit-Va des Zielsymbols enthalten. |
| IMAGE _ REL _ SH3 _ PCREL8 _ WORD |
0x0009 |
Ein Verweis auf die 8-Bit-Anweisung, die den effektiven relativen 16-Bit-Offset des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ PCREL8 _ LONG |
0x000A |
Ein Verweis auf die 8-Bit-Anweisung, die den effektiven relativen 32-Bit-Offset des Zielsymbols enthält. |
| IMAGE _ REL _ SH3 _ PCREL12 _ WORD |
0x000B |
Ein Verweis auf die 16-Bit-Anweisung, deren niedrige 12 Bits den effektiven relativen 16-Bit-Offset des Zielsymbols enthalten. |
| IMAGE _ REL _ SH3 _ _ STARTOF-ABSCHNITT |
0x000C |
Ein Verweis auf eine 32-Bit-Position, bei der es sich um die Va des Abschnitts handelt, der das Zielsymbol enthält. |
| ABSCHNITT "IMAGE _ REL _ SH3 _ _ SIZEOF" |
0x000D |
Ein Verweis auf die 32-Bit-Position, die der Größe des Abschnitts mit dem Zielsymbol ist. |
| ABSCHNITT _ "IMAGE REL _ _ SH3" |
0x000E |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ SH3 _ SECREL |
0x000F |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ SH3 _ DIRECT32 _ NB |
0x0010 |
Die 32-Bit-RVA des Zielsymbols. |
| IMAGE _ REL _ SH3 _ GPREL4 _ LONG |
0x0011 |
Gp relative. |
| IMAGE _ REL _ SH3 _ TOKEN |
0x0012 |
CLR-Token. |
| IMAGE _ REL _ SHM _ PCRELPT |
0x0013 |
Der Offset von der aktuellen Anweisung in longwords. Wenn das NOMODE-Bit nicht festgelegt ist, fügen Sie die Umkehrung des niedrigen Bits bei Bit 32 ein, um PTA oder PTB auszuwählen. |
| IMAGE _ REL _ SHM _ REFLO |
0x0014 |
Die unteren 16 Bits der 32-Bit-Adresse. |
| IMAGE _ REL _ SHM _ REFHALF |
0x0015 |
Die hohen 16 Bits der 32-Bit-Adresse. |
| IMAGE _ REL _ SHM _ REVER |
0x0016 |
Die niedrigen 16 Bits der relativen Adresse. |
| IMAGE _ REL _ SHM _ RELHALF |
0x0017 |
Die hohen 16 Bits der relativen Adresse. |
| IMAGE _ REL _ SHM _ PAIR |
0x0018 |
Die Verschiebung ist nur gültig, wenn sie unmittelbar auf eine REFHALF-, RELHALF- oder RE REATORS-Verschiebung folgt. Das Feld SymbolTableIndex der Verschiebung enthält eine Verschiebung und keinen Index in der Symboltabelle. |
| IMAGE _ REL _ SHM _ NOMODE |
0x8000 |
Die Verschiebung ignoriert den Abschnittsmodus. |
IBM PowerPC-Prozessoren
Die folgenden Verschiebungstypindikatoren werden für PowerPC definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ PPC _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ PPC _ ADDR64 |
0x0001 |
Die 64-Bit-Va des Ziels. |
| IMAGE _ REL _ PPC _ ADDR32 |
0x0002 |
Die 32-Bit-Va des Ziels. |
| IMAGE _ REL _ PPC _ ADDR24 |
0x0003 |
Die unteren 24 Bits der Va des Ziels. Dies ist nur gültig, wenn das Zielsymbol absolut ist und auf den ursprünglichen Wert erweitert werden kann. |
| IMAGE _ REL _ PPC _ ADDR16 |
0x0004 |
Die niedrigen 16 Bits der Va des Ziels. |
| IMAGE _ REL _ PPC _ ADDR14 |
0x0005 |
Die niedrigen 14 Bits der Va des Ziels. Dies ist nur gültig, wenn das Zielsymbol absolut ist und auf seinen ursprünglichen Wert erweitert werden kann. |
| IMAGE _ REL _ PPC _ REL24 |
0x0006 |
Ein 24-Bit-PC-relativer Offset zum Speicherort des Symbols. |
| IMAGE _ REL _ PPC _ REL14 |
0x0007 |
Ein 14-Bit-PC-relativer Offset zum Speicherort des Symbols. |
| IMAGE _ REL _ PPC _ ADDR32NB |
0x000A |
Das 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ PPC _ SECREL |
0x000B |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| ABSCHNITT _ "IMAGE REL _ _ PPC" |
0x000C |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ PPC _ SECREL16 |
0x000F |
Der 16-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ PPC _ REFHI |
0x0010 |
Die hohen 16 Bits der 32-Bit-Va des Ziels. Dies wird für die erste Anweisung in einer Sequenz mit zwei Anweisungen verwendet, die eine vollständige Adresse lädt. Auf diese Verschiebung muss unmittelbar eine PAIR-Verschiebung folgen, deren SymbolTableIndex eine 16-Bit-Verschiebung mit Vorzeichen enthält, die den oberen 16 Bits hinzugefügt wird, die von der Position entfernt wurden, die verschoben wird. |
| IMAGE _ REL _ PPC _ REFLO |
0x0011 |
Die niedrigen 16 Bits der Va des Ziels. |
| IMAGE _ REL _ PPC _ PAIR |
0x0012 |
Eine Verschiebung, die nur gültig ist, wenn sie unmittelbar nach einer REFHI- oder SECRELHI-Verschiebung erfolgt. SymbolTableIndex enthält eine Verschiebung und keinen Index in der Symboltabelle. |
| IMAGE _ REL _ PPC _ SECRELLO |
0x0013 |
Die niedrigen 16 Bits des 32-Bit-Offsets des Ziels vom Anfang des Abschnitts. |
| IMAGE _ REL _ PPC _ GPREL |
0x0015 |
Die 16-Bit-Verschiebung des Ziels relativ zum GP-Register. |
| IMAGE _ REL _ PPC _ TOKEN |
0x0016 |
Das CLR-Token. |
Intel 386-Prozessoren
Die folgenden Verlagerungstypindikatoren sind für Intel 386 und kompatible Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ I386 _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ I386 _ DIR16 |
0x0001 |
Wird nicht unterstützt. |
| IMAGE _ REL _ I386 _ REL16 |
0x0002 |
Wird nicht unterstützt. |
| IMAGE _ REL _ I386 _ DIR32 |
0x0006 |
Die 32-Bit-Va des Ziels. |
| IMAGE _ REL _ I386 _ DIR32NB |
0x0007 |
Das 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ I386 _ SEG12 |
0x0009 |
Wird nicht unterstützt. |
| ABSCHNITT "IMAGE _ REL _ I386" _ |
0x000A |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ I386 _ SECREL |
0x000B |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ I386 _ TOKEN |
0x000C |
Das CLR-Token. |
| ABBILDUNG _ REL _ I386 _ SECREL7 |
0x000D |
Ein 7-Bit-Offset von der Basis des Abschnitts, der das Ziel enthält. |
| IMAGE _ REL _ I386 _ REL32 |
0x0014 |
Die relative Verschiebung von 32 Bit zum Ziel. Dies unterstützt den relativen x86-Branch und Aufrufanweisungen. |
Intel Itanium-Prozessorfamilie (IPF)
Die folgenden Verlagerungstypindikatoren sind für die Intel Itanium-Prozessorfamilie und kompatible Prozessoren definiert. Beachten Sie, dass verschiebungen in Anweisungen den Offset und die Slotnummer des Pakets für den Verschiebungsoffset verwenden.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ IA64 _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ IA64 _ IMM14 |
0x0001 |
Auf die Anweisungsverlagerung kann eine ADDEND-Verschiebung folgen, deren Wert der Zieladresse hinzugefügt wird, bevor sie in den angegebenen Slot im IMM14-Paket eingefügt wird. Das Verschiebungsziel muss absolut sein, oder das Image muss korrigiert werden. |
| IMAGE _ REL _ IA64 _ IMM22 |
0x0002 |
Auf die Anweisungsverlagerung kann eine ADDEND-Verschiebung folgen, deren Wert der Zieladresse hinzugefügt wird, bevor sie in den angegebenen Slot im IMM22-Paket eingefügt wird. Das Verschiebungsziel muss absolut sein, oder das Image muss korrigiert werden. |
| IMAGE _ REL _ IA64 _ IMM64 |
0x0003 |
Die Slotnummer dieser Verschiebung muss eins (1) sein. Auf die Verschiebung kann eine ADDEND-Verschiebung folgen, deren Wert der Zieladresse hinzugefügt wird, bevor sie in allen drei Slots des IMM64-Pakets gespeichert wird. |
| IMAGE _ REL _ IA64 _ DIR32 |
0x0004 |
Die 32-Bit-Va des Ziels. Dies wird nur für /LARGEADDRESSAWARE:NO-Images unterstützt. |
| IMAGE _ REL _ IA64 _ DIR64 |
0x0005 |
Die 64-Bit-Va des Ziels. |
| IMAGE _ REL _ IA64 _ PCREL21B |
0x0006 |
Die Anweisung wird mit der relativen Verschiebung von 25 Bit auf das 16-Bit-ausgerichtete Ziel korrigiert. Die unteren 4 Bits der Verschiebung sind 0 (null) und werden nicht gespeichert. |
| IMAGE _ REL _ IA64 _ PCREL21M |
0x0007 |
Die Anweisung wird mit der relativen Verschiebung von 25 Bit auf das 16-Bit-ausgerichtete Ziel korrigiert. Die niedrigen 4 Bits der Verschiebung, die 0 (null) sind, werden nicht gespeichert. |
| IMAGE _ REL _ IA64 _ PCREL21F |
0x0008 |
Die LSBs des Offsets dieser Verschiebung müssen die Slotnummer enthalten, während der Rest die Paketadresse ist. Das Bündel wird mit der relativen Verschiebung von 25 Bit auf das 16-Bit-ausgerichtete Ziel festgelegt. Die unteren 4 Bits der Verschiebung sind 0 (null) und werden nicht gespeichert. |
| IMAGE _ REL _ IA64 _ GPREL22 |
0x0009 |
Auf die Anweisungsverlagerung kann eine ADDEND-Verschiebung folgen, deren Wert der Zieladresse hinzugefügt wird, und dann ein 22-Bit-GP-relativer Offset, der berechnet und auf das GPREL22-Bündel angewendet wird. |
| IMAGE _ REL _ IA64 _ LTOFF22 |
0x000A |
Die Anweisung wird mit dem 22-Bit-GP-relativen Offset zum Literaltabelleneintrag des Zielsymbols korrigiert. Der Linker erstellt diesen Literaltabelleneintrag basierend auf dieser Verschiebung und der möglicherweise folgenden ADDEND-Verschiebung. |
| ABSCHNITT _ "IMAGE REL _ IA64" _ |
0x000B |
Der 16-Bit-Abschnittsindex des Abschnitts enthält das Ziel. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ IA64 _ SECREL22 |
0x000C |
Die Anweisung wird mit dem 22-Bit-Offset des Ziels vom Anfang des Abschnitts korrigiert. Auf diese Verschiebung kann sofort eine ADDEND-Verschiebung folgen, deren Feld Wert den 32-Bit-Offset ohne Vorzeichen des Ziels vom Anfang des Abschnitts enthält. |
| IMAGE _ REL _ IA64 _ SECREL64I |
0x000D |
Die Slotnummer für diese Verschiebung muss eins (1) sein. Die Anweisung wird mit dem 64-Bit-Offset des Ziels vom Anfang des Abschnitts korrigiert. Auf diese Verschiebung kann sofort eine ADDEND-Verschiebung folgen, deren Feld Wert den 32-Bit-Offset ohne Vorzeichen des Ziels vom Anfang des Abschnitts enthält. |
| IMAGE _ REL _ IA64 _ SECREL32 |
0x000E |
Die Adresse der Daten, die mit dem 32-Bit-Offset des Ziels vom Anfang des Abschnitts korrigiert werden sollen. |
| IMAGE _ REL _ IA64 _ DIR32NB |
0x0010 |
Die 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ IA64 _ SREL14 |
0x0011 |
Dies wird auf eine signierte 14-Bit-Direkt- angewendet, die den Unterschied zwischen zwei umsetzbaren Zielen enthält. Dies ist ein deklaratives Feld für den Linker, das angibt, dass der Compiler diesen Wert bereits ausgegeben hat. |
| IMAGE _ REL _ IA64 _ SREL22 |
0x0012 |
Dies wird auf eine signierte 22-Bit-Direkt- angewendet, die den Unterschied zwischen zwei umsetzbaren Zielen enthält. Dies ist ein deklaratives Feld für den Linker, das angibt, dass der Compiler diesen Wert bereits ausgegeben hat. |
| IMAGE _ REL _ IA64 _ SREL32 |
0x0013 |
Dies wird auf eine signierte 32-Bit-Direkt- angewendet, die den Unterschied zwischen zwei umsetzbaren Werten enthält. Dies ist ein deklaratives Feld für den Linker, das angibt, dass der Compiler diesen Wert bereits ausgegeben hat. |
| IMAGE _ REL _ IA64 _ UREL32 |
0x0014 |
Dies wird auf einen 32-Bit-Direktwert ohne Vorzeichen angewendet, der den Unterschied zwischen zwei umsetzbaren Werten enthält. Dies ist ein deklaratives Feld für den Linker, das angibt, dass der Compiler diesen Wert bereits ausgegeben hat. |
| IMAGE _ REL _ IA64 _ PCREL60X |
0x0015 |
Ein 60-Bit-PC-relatives Fixup, das immer als BRL-Anweisung eines MLX-Pakets bleibt. |
| IMAGE _ REL _ IA64 _ PCREL60B |
0x0016 |
Eine 60-Bit-PC-relative Korrektur. Wenn die Zielverschiebung in ein signiertes 25-Bit-Feld passt, konvertieren Sie das gesamte Paket in ein MBB-Paket mit NOP. B in Slot 1 und eine 25-Bit-BR-Anweisung (mit den vier niedrigsten Bits, die alle 0 (null) und verworfen wurden) in Slot 2. |
| IMAGE _ REL _ IA64 _ PCREL60F |
0x0017 |
Eine 60-Bit-PC-relative Korrektur. Wenn die Zielverschiebung in ein signiertes 25-Bit-Feld passt, konvertieren Sie das gesamte Paket in ein MFB-Paket mit NOP. F in Slot 1 und eine 25-Bit-ANWEISUNG (4 niedrigste Bits alle 0 (null) und verworfen) im Slot 2. |
| IMAGE _ REL _ IA64 _ PCREL60I |
0x0018 |
Eine 60-Bit-PC-relative Korrektur. Wenn die Zielverschiebung in ein signiertes 25-Bit-Feld passt, konvertieren Sie das gesamte Paket in ein MIB-Paket mit NOP. I in Slot 1 and a 25-bit (4 lowest bits all zero and dropped) BR-Anweisung in Slot 2. |
| IMAGE _ REL _ IA64 _ PCREL60M |
0x0019 |
Eine 60-Bit-PC-relative Korrektur. Wenn die Zielverschiebung in ein signiertes 25-Bit-Feld passt, konvertieren Sie das gesamte Bündel in ein MMB-Bündel mit NOP. M in Slot 1 und eine 25-Bit-BR-Anweisung (4 niedrigste Bits, alle null und verworfen) in Slot 2. |
| IMAGE _ REL _ IA64 _ IMMGPREL64 |
0x001a |
Ein 64-Bit-GP-relatives Fixup. |
| IMAGE _ REL _ IA64 _ TOKEN |
0x001b |
Ein CLR-Token. |
| IMAGE _ REL _ IA64 _ GPREL32 |
0x001c |
Ein 32-Bit-GP-relatives Fixup. |
| IMAGE _ REL _ IA64 _ ADDEND |
0x001F |
Die Verschiebung ist nur gültig, wenn sie unmittelbar auf eine der folgenden Verschiebungen folgt: IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I oder SECREL32. Der Wert enthält den Add-In, der auf Anweisungen innerhalb eines Pakets angewendet werden soll, nicht für Daten. |
MIPS-Prozessoren
Die folgenden Verlagerungstypindikatoren werden für MIPS-Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ MIPS _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ MIPS _ REFHALF |
0x0001 |
Die hohen 16 Bits der 32-Bit-Va des Ziels. |
| IMAGE _ REL _ MIPS _ REFWORD |
0x0002 |
Die 32-Bit-Va des Ziels. |
| IMAGE _ REL _ MIPS _ JMPADDR |
0x0003 |
Die niedrigen 26 Bits der Va des Ziels. Dies unterstützt die MIPS J- und JAL-Anweisungen. |
| IMAGE _ REL _ MIPS _ REFHI |
0x0004 |
Die hohen 16 Bits der 32-Bit-Va des Ziels. Dies wird für die erste Anweisung in einer Sequenz mit zwei Anweisungen verwendet, die eine vollständige Adresse lädt. Auf diese Verschiebung muss unmittelbar eine PAIR-Verschiebung folgen, deren SymbolTableIndex eine 16-Bit-Verschiebung mit Vorzeichen enthält, die den oberen 16 Bits hinzugefügt wird, die von der Position übernommen werden, die verschoben wird. |
| IMAGE _ REL _ MIPS _ REFLO |
0x0005 |
Die niedrigen 16 Bits der Va des Ziels. |
| IMAGE _ REL _ MIPS _ GPREL |
0x0006 |
Eine 16-Bit-Verschiebung des Ziels relativ zum GP-Register. |
| IMAGE _ REL _ MIPS _ LITERAL |
0x0007 |
Identisch mit IMAGE _ REL _ MIPS _ GPREL. |
| _ABSCHNITT "IMAGE REL _ _ MIPS" |
0x000A |
Der 16-Bit-Abschnittsindex des Abschnitts enthält das Ziel. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ MIPS _ SECREL |
0x000B |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| ABBILDUNG: _ REL _ MIPS _ SECRELLO |
0x000C |
Die niedrigen 16 Bits des 32-Bit-Offsets des Ziels vom Anfang des Abschnitts. |
| ABBILDUNG: _ REL _ MIPS _ SECRELHI |
0x000D |
Die hohen 16 Bits des 32-Bit-Offsets des Ziels vom Anfang des Abschnitts. Eine _ IMAGE REL _ MIPS _ PAIR-Verschiebung muss sofort auf diese folgen. Der SymbolTableIndex der PAIR-Verschiebung enthält eine 16-Bit-Verschiebung mit Vorzeichen, die den oberen 16 Bits hinzugefügt wird, die von der Position übernommen werden, die verschoben wird. |
| IMAGE _ REL _ MIPS _ JMPADDR16 |
0x0010 |
Die niedrigen 26 Bits der Va des Ziels. Dies unterstützt die MIPS16-JAL-Anweisung. |
| IMAGE _ REL _ MIPS _ REFWORDNB |
0x0022 |
Das 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ MIPS _ PAIR |
0x0025 |
Die Verschiebung ist nur gültig, wenn sie unmittelbar nach einer REFHI- oder SECRELHI-Verschiebung erfolgt. SymbolTableIndex enthält eine Verschiebung und keinen Index in der Symboltabelle. |
Soll M32R
Die folgenden Verlagerungstypindikatoren sind für die M32R-Prozessoren definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ M32R _ ABSOLUTE |
0x0000 |
Die Verschiebung wird ignoriert. |
| IMAGE _ REL _ M32R _ ADDR32 |
0x0001 |
Die 32-Bit-Va des Ziels. |
| IMAGE _ REL _ M32R _ ADDR32NB |
0x0002 |
Das 32-Bit-RVA des Ziels. |
| IMAGE _ REL _ M32R _ ADDR24 |
0x0003 |
Die 24-Bit-Va des Ziels. |
| IMAGE _ REL _ M32R _ GPREL16 |
0x0004 |
Der 16-Bit-Offset des Ziels vom GP-Register. |
| IMAGE _ REL _ M32R _ PCREL24 |
0x0005 |
Der 24-Bit-Offset des Ziels vom Programmzähler (PC), um 2 Bits nach links verschoben und mit Vorzeichen erweitert |
| IMAGE _ REL _ M32R _ PCREL16 |
0x0006 |
Der 16-Bit-Offset des Ziels vom PC, um 2 Bits nach links verschoben und mit Vorzeichen erweitert |
| IMAGE _ REL _ M32R _ PCREL8 |
0x0007 |
Der 8-Bit-Offset des Ziels vom PC, um 2 Bits nach links verschoben und mit Vorzeichen erweitert |
| IMAGE _ REL _ M32R _ REFHALF |
0x0008 |
Die 16 MSBs der Ziel-VA. |
| IMAGE _ REL _ M32R _ REFHI |
0x0009 |
Die 16 MSBs der Ziel-VA, angepasst für die LSB-Sign-Erweiterung. Dies wird für die erste Anweisung in einer Sequenz mit zwei Anweisungen verwendet, die eine vollständige 32-Bit-Adresse lädt. Auf diese Verschiebung muss unmittelbar eine PAIR-Verschiebung folgen, deren SymbolTableIndex eine 16-Bit-Verschiebung mit Vorzeichen enthält, die den oberen 16 Bits hinzugefügt wird, die von der Position übernommen werden, die verschoben wird. |
| IMAGE _ REL _ M32R _ REFLO |
0x000A |
Die 16 LSBs der Ziel-VA. |
| IMAGE _ REL _ M32R _ PAIR |
0x000B |
Die Verschiebung muss der REFHI-Verschiebung folgen. Der SymbolTableIndex enthält eine Verschiebung und keinen Index in der Symboltabelle. |
| ABSCHNITT _ "IMAGE REL _ M32R" _ |
0x000C |
Der 16-Bit-Abschnittsindex des Abschnitts, der das Ziel enthält. Dies wird verwendet, um Debuginformationen zu unterstützen. |
| IMAGE _ REL _ M32R _ SECREL |
0x000D |
Der 32-Bit-Offset des Ziels vom Anfang des Abschnitts. Dies wird verwendet, um Debuginformationen und statischen lokalen Threadspeicher zu unterstützen. |
| IMAGE _ REL _ M32R _ TOKEN |
0x000E |
Das CLR-Token. |
COFF-Zeilennummern (veraltet)
COFF-Zeilennummern werden nicht mehr erstellt und in Zukunft nicht mehr verwendet.
COFF-Zeilennummern geben die Beziehung zwischen Code und Zeilennummern in Quelldateien an. Das Microsoft-Format für COFF-Zeilennummern ähnelt dem COFF-Standardformat, wurde jedoch erweitert, um zu ermöglichen, dass ein einzelner Abschnitt mit Zeilennummern in mehreren Quelldateien in Beziehung steht.
COFF-Zeilennummern bestehen aus einem Array von Datensätzen fester Länge. Der Speicherort (Dateioffset) und die Größe des Arrays werden im Abschnittsheader angegeben. Jeder Zeilennummerdatensatz hat das folgende Format.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Typ ( * ) |
Dies ist eine Vereinigung aus zwei Feldern: SymbolTableIndex und VirtualAddress. Ob SymbolTableIndex oder RVA verwendet wird, hängt vom Wert von Linenumber ab. |
| 4 |
2 |
Linenumber |
Bei einem Wert ungleich 0 (null) gibt dieses Feld eine einsbasierte Zeilennummer an. Bei 0 (null) wird das Feld Type als Symboltabellenindex für eine Funktion interpretiert. |
Das Feld Type ist eine Vereinigung aus zwei 4-Byte-Feldern: SymbolTableIndex und VirtualAddress.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
SymbolTableIndex |
Wird verwendet, wenn Linenumber 0 (null) ist: Index zum Symboltabelleneintrag für eine Funktion. Dieses Format wird verwendet, um die Funktion anzugeben, auf die eine Gruppe von Zeilennummerdatensätzen verweist. |
| 0 |
4 |
VirtualAddress |
Wird verwendet, wenn Linenumber nicht 0 (null) ist: das RVA des ausführbaren Codes, der der angegebenen Quellzeile entspricht. In einer Objektdatei enthält dies die Va innerhalb des Abschnitts. |
Ein Zeilennummerneintrag kann entweder das Feld Linenumber auf 0 (null) festlegen und auf eine Funktionsdefinition in der Symboltabelle zeigen, oder er kann als Standardeintrag für Zeilennummern verwendet werden, indem eine positive ganze Zahl (Zeilennummer) und die entsprechende Adresse im Objektcode angegeben werden.
Eine Gruppe von Zeilennummereinträgen beginnt immer mit dem ersten Format: dem Index eines Funktionssymbols. Wenn dies der erste Zeilennummerdatensatz im Abschnitt ist, ist dies auch der COMDAT-Symbolname für die Funktion, wenn das COMDAT-Flag des Abschnitts festgelegt ist. Weitere Informationen finden Sie unter COMDAT-Abschnitte (nur Objekt). Der Hilfsdatensatz der Funktion in der Symboltabelle verfügt über einen Zeiger auf das Feld Linenumber, das auf denselben Zeilennummerndatensatz zeigt.
Auf einen Datensatz, der eine Funktion identifiziert, folgt eine beliebige Anzahl von Zeilennummerneinträgen, die tatsächliche Zeilennummerninformationen enthalten (d. h. Einträge mit Zeilennummer größer als 0 (null). Diese Einträge sind einsbasierte Einträge relativ zum Anfang der Funktion und stellen jede Quellzeile in der Funktion dar, mit Ausnahme der ersten Zeile.
Beispielsweise würde der erste Zeilennummerndatensatz für das folgende Beispiel die ReverseSign-Funktion angeben (SymbolTableIndex von ReverseSign und Linenumber auf 0 festgelegt). Anschließend folgen Datensätze mit den Linenumber-Werten 1, 2 und 3, die den Quellzeilen wie gezeigt entspricht:
// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2: return -1 * i;
3: }
COFF-Symboltabelle
Die Symboltabelle in diesem Abschnitt wird vom herkömmlichen COFF-Format geerbt. Sie unterscheiden sich von Microsoft Visual C++ Debuginformationen. Eine Datei kann sowohl eine COFF-Symboltabelle als auch Visual C++ Debuginformationen enthalten, und die beiden werden getrennt gehalten. Einige Microsoft-Tools verwenden die Symboltabelle für eingeschränkte, aber wichtige Zwecke, z. B. die Kommunikation von COMDAT-Informationen mit dem Linker. Abschnitts- und Dateinamen sowie Code- und Datensymbole sind in der Symboltabelle aufgeführt.
Die Position der Symboltabelle wird im COFF-Header angegeben.
Die Symboltabelle ist ein Array von Datensätzen, die jeweils 18 Bytes lang sind. Jeder Datensatz ist entweder ein Standarddatensatz oder ein Hilfsdatensatz für Symboltabellen. Ein Standarddatensatz definiert ein Symbol oder einen Namen und hat das folgende Format.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
8 |
Name ( * ) |
Der Name des Symbols, dargestellt durch eine Vereinigung von drei -Strukturen. Ein Array von 8 Bytes wird verwendet, wenn der Name nicht mehr als 8 Bytes lang ist. Weitere Informationen finden Sie unter Symbolnamendarstellung. |
| 8 |
4 |
Wert |
Der Wert, der dem Symbol zugeordnet ist. Die Interpretation dieses Felds hängt von SectionNumber und StorageClass ab. Eine typische Bedeutung ist die umsetzbare Adresse. |
| 12 |
2 |
SectionNumber |
Die ganze Zahl mit Vorzeichen, die den Abschnitt mit einem 1-basierten Index in der Abschnittstabelle identifiziert. Einige Werte haben eine besondere Bedeutung, wie in Abschnitt 5.4.2, "Section Number Values", definiert. |
| 14 |
2 |
type |
Eine Zahl, die den Typ darstellt. Microsoft-Tools legen dieses Feld auf 0x20 (Funktion) oder 0x0 (keine Funktion) fest. Weitere Informationen finden Sie unter Typdarstellung. |
| 16 |
1 |
StorageClass |
Ein aufzählter Wert, der die Speicherklasse darstellt. Weitere Informationen finden Sie unter Storage-Klasse. |
| 17 |
1 |
NumberOfAuxSymbols |
Die Anzahl der zusätzlichen Symboltabelleneinträge, die diesem Datensatz folgen. |
Null oder mehr zusätzliche Symboltabelleneinträge folgen unmittelbar auf jeden Standard-Symboltabellen-Datensatz. In der Regel folgt jedoch nicht mehr als ein Hilfsdatensatz für Symboltabellen einem Standard-Symboltabellen-Datensatz (mit Ausnahme von .file-Datensätzen mit langen Dateinamen). Jeder zusätzliche Datensatz hat die gleiche Größe wie ein Standard-Symboltabellen-Datensatz (18 Byte), aber anstatt ein neues Symbol zu definieren, liefert der Hilfsdatensatz zusätzliche Informationen zum letzten definierten Symbol. Die Auswahl der zu verwendenden Formate hängt vom Feld StorageClass ab. Derzeit definierte Formate für zusätzliche Symboltabellendatensätze werden in Abschnitt 5.5, "Hilfssymboldatensätze", angezeigt.
Tools, die COFF-Symboltabellen lesen, müssen zusätzliche Symboldatensätze ignorieren, deren Interpretation unbekannt ist. Dadurch kann das Symboltabellenformat erweitert werden, um neue zusätzliche Datensätze hinzuzufügen, ohne vorhandene Tools zu unterbrichten.
Symbolnamendarstellung
Das Feld ShortName in einer Symboltabelle besteht aus 8 Bytes, die den Namen selbst enthalten, wenn es nicht mehr als 8 Bytes lang ist, oder das Feld ShortName gibt einen Offset in die Zeichenfolgentabelle ein. Um zu bestimmen, ob der Name selbst oder ein Offset angegeben wird, testen Sie die ersten 4 Bytes auf Gleichheit auf 0 (null).
Standardmäßig werden die Namen als auf Null terminierte UTF-8-codierte Zeichenfolgen behandelt.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
8 |
ShortName |
Ein Array von 8 Bytes. Dieses Array wird auf der rechten Seite mit NULL-Werten aufschlossen, wenn der Name kleiner als 8 Bytes ist. |
| 0 |
4 |
Nullen |
Ein Feld, das auf alle Nullen festgelegt ist, wenn der Name länger als 8 Bytes ist. |
| 4 |
4 |
Offset |
Ein Offset in die Zeichenfolgentabelle. |
Abschnittsnummerwerte
Normalerweise ist das Feld Abschnittswert in einem Symboltabelleneintrag ein 1-basierter Index in der Abschnittstabelle. Dieses Feld ist jedoch eine ganze Zahl mit Vorzeichen und kann negative Werte enthalten. Die folgenden Werte, kleiner als 1, haben besondere Bedeutungen.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ SYM _ UNDEFINED |
0 |
Dem Symboldatensatz ist noch kein Abschnitt zugewiesen. Der Wert 0 (null) gibt an, dass ein Verweis auf ein externes Symbol an anderer Stelle definiert ist. Ein Wert von nicht 0 (null) ist ein allgemeines Symbol mit einer Größe, die durch den Wert angegeben wird. |
| BILD _ SYM _ ABSOLUTE |
-1 |
Das Symbol hat einen absoluten (nicht auffindbaren) Wert und ist keine Adresse. |
| IMAGE _ SYM _ DEBUG |
-2 |
Das Symbol stellt allgemeine Typ- oder Debuginformationen zur Verfügung, entspricht jedoch keinem Abschnitt. Microsoft-Tools verwenden diese Einstellung zusammen mit .file-Datensätzen (Speicherklasse FILE). |
Typdarstellung
Das Feld Typ eines Symboltabelleneintrags enthält 2 Bytes, wobei jedes Byte Typinformationen darstellt. Die LSB stellt den einfachen (Basisdatentyp) dar, und msb stellt den komplexen Typ dar, falls der typ ist:
| MSB | LSB |
|---|---|
| Komplexer Typ: none, pointer, function, array. |
Basistyp: ganze Zahl, Gleitkommazahl und so weiter. |
Die folgenden Werte werden für den Basistyp definiert, obwohl Microsoft-Tools dieses Feld im Allgemeinen nicht verwenden und LSB auf 0 festlegen. Stattdessen werden Visual C++ Debuginformationen verwendet, um Typen anzugeben. Die möglichen COFF-Werte werden hier jedoch der Vollständigkeit halber aufgeführt.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ SYM _ TYPE _ NULL |
0 |
Keine Typinformationen oder unbekannter Basistyp. Microsoft-Tools verwenden diese Einstellung |
| IMAGE _ SYM _ TYPE _ VOID |
1 |
Kein gültiger Typ; Wird mit void-Zeigern und -Funktionen verwendet |
| IMAGE _ SYM _ TYPE _ CHAR |
2 |
Ein Zeichen (signiertes Byte) |
| IMAGE _ SYM _ TYPE _ SHORT |
3 |
Eine 2-Byte-Ganzzahl mit Vorzeichen |
| IMAGE _ SYM _ TYPE _ INT |
4 |
Ein natürlicher ganzzahliger Typ (normalerweise 4 Bytes in Windows) |
| IMAGE _ SYM _ TYPE _ LONG |
5 |
Eine 4-Byte-Ganzzahl mit Vorzeichen |
| IMAGE _ SYM _ TYPE _ FLOAT |
6 |
Eine 4-Byte-Gleitkommazahl |
| SYMBOLISCHER _ _ BILDTYP _ DOUBLE |
7 |
Eine 8-Byte-Gleitkommazahl |
| IMAGE _ SYM _ TYPE _ STRUCT |
8 |
Eine -Struktur |
| IMAGE _ SYM _ TYPE _ UNION |
9 |
Eine Union |
| _ENUM DES _ _ SYMBOLISCHEN BILDTYPS |
10 |
Ein aufzählter Typ |
| BILD _ _ _ SYM-TYP MOE |
11 |
Ein Member der Enumeration (ein bestimmter Wert) |
| IMAGE _ SYM _ TYPE _ BYTE |
12 |
Ein Byte; 1-Byte-Ganzzahl ohne Vorzeichen |
| _BILD: WORT VOM TYP "SYM" _ _ |
13 |
Ein Wort; 2-Byte-Ganzzahl ohne Vorzeichen |
| IMAGE _ SYM _ TYPE _ UINT |
14 |
Eine ganze Zahl ohne Vorzeichen natürlicher Größe (normalerweise 4 Bytes) |
| IMAGE _ SYM _ TYPE _ DWORD |
15 |
Eine 4-Byte-Ganzzahl ohne Vorzeichen |
Das wichtigste Byte gibt an, ob das Symbol ein Zeiger auf, eine Funktion, die zurückgibt, oder ein Array des Basistyps ist, der im LSB angegeben ist. Microsoft-Tools verwenden dieses Feld nur, um anzugeben, ob das Symbol eine Funktion ist, sodass die einzigen beiden resultierenden Werte für das Feld Typ 0x0 und 0x20 werden. Andere Tools können dieses Feld jedoch verwenden, um weitere Informationen zu kommunizieren.
Es ist sehr wichtig, das Funktionsattribut richtig anzugeben. Diese Informationen sind erforderlich, damit inkrementelle Verknüpfungen ordnungsgemäß funktionieren. Für einige Architekturen sind die Informationen möglicherweise für andere Zwecke erforderlich.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| BILD _ SYM _ DTYPE _ NULL |
0 |
Kein abgeleiteter Typ; Das Symbol ist eine einfache Skalarvariable. |
| _BILD: _ SYMBOLISCHER _ DTYPE-ZEIGER |
1 |
Das Symbol ist ein Zeiger auf den Basistyp. |
| IMAGE _ SYM _ _ DTYPE-FUNKTION |
2 |
Das Symbol ist eine Funktion, die einen Basistyp zurückgibt. |
| IMAGE _ SYM _ DTYPE _ ARRAY |
3 |
Das Symbol ist ein Array des Basistyps. |
Speicherklasse
Das Feld StorageClass der Symboltabelle gibt an, welche Art von Definition ein Symbol darstellt. In der folgenden Tabelle sind mögliche Werte aufgeführt. Beachten Sie, dass das Feld StorageClass eine 1-Byte-Ganzzahl ohne Vorzeichen ist. Der Sonderwert -1 sollte daher als entsprechung ohne Vorzeichen 0xFF werden.
Obwohl das herkömmliche COFF-Format viele Speicherklassenwerte verwendet, basieren Microsoft-Tools für die meisten symbolischen Informationen auf Visual C++ Debugformat und verwenden im Allgemeinen nur vier Speicherklassenwerte: EXTERNAL (2), STATIC (3), FUNCTION (101) und FILE (103). Mit Ausnahme der zweiten Spaltenüberschrift unten sollte "Value" als Wertfeld des Symboldatensatzes verwendet werden (dessen Interpretation von der Als Speicherklasse gefundenen Zahl abhängt).
| Konstante | Wert | Beschreibung/Interpretation des Felds Wert |
|---|---|---|
| IMAGE _ SYM _ CLASS _ END _ OF _ FUNCTION |
-1 (0xFF) |
Ein spezielles Symbol, das das Ende der Funktion zu Debugzwecken darstellt. |
| IMAGE _ SYM _ CLASS _ NULL |
0 |
Keine zugewiesene Speicherklasse. |
| IMAGE _ SYM _ CLASS _ AUTOMATIC |
1 |
Die automatische Variable (Stapelvariable). Das Feld Wert gibt den Stapelrahmenoffset an. |
| IMAGE _ SYM _ CLASS _ EXTERNAL |
2 |
Ein -Wert, den Microsoft-Tools für externe Symbole verwenden. Das Feld Wert gibt die Größe an, wenn die Abschnittsnummer IMAGE _ SYM _ UNDEFINED (0) lautet. Wenn die Abschnittsnummer nicht 0 (null) ist, gibt das Feld Wert den Offset innerhalb des Abschnitts an. |
| IMAGE _ SYM _ CLASS _ STATIC |
3 |
Der Offset des Symbols innerhalb des Abschnitts. Wenn das Feld Wert 0 (null) ist, stellt das Symbol einen Abschnittsnamen dar. |
| IMAGE _ SYM _ CLASS _ REGISTER |
4 |
Eine Registervariable. Das Feld Wert gibt die Registernummer an. |
| IMAGE _ SYM _ CLASS _ EXTERNAL _ DEF |
5 |
Ein Extern definiertes Symbol. |
| IMAGE _ SYM _ CLASS _ LABEL |
6 |
Eine Codebezeichnung, die innerhalb des Moduls definiert ist. Das Feld Wert gibt den Offset des Symbols innerhalb des Abschnitts an. |
| IMAGE _ SYM _ CLASS _ UNDEFINED _ LABEL |
7 |
Ein Verweis auf eine Codebezeichnung, die nicht definiert ist. |
| IMAGE _ SYM _ CLASS _ MEMBER _ OF _ STRUCT |
8 |
Der Strukturmember. Das Feld Wert gibt das n-th-Element an. |
| IMAGE _ SYM _ CLASS _ ARGUMENT |
9 |
Ein formales Argument (Parameter) einer Funktion. Das Feld Wert gibt das n-ten Argument an. |
| IMAGE _ SYM _ CLASS _ STRUCT _ TAG |
10 |
Der Tagnameneintrag der Struktur. |
| IMAGE _ SYM _ CLASS _ MEMBER _ OF _ UNION |
11 |
Ein Union-Member. Das Feld Wert gibt das n-th-Element an. |
| IMAGE _ SYM _ CLASS _ UNION _ TAG |
12 |
Der Union-Tagname-Eintrag. |
| TYPDEFINITION _ _ DER BILD-SYM-KLASSE _ _ |
13 |
Ein Typedef-Eintrag. |
| IMAGE _ SYM _ CLASS _ UNDEFINED _ STATIC |
14 |
Eine statische Datendeklaration. |
| IMAGE _ SYM _ CLASS _ ENUM _ TAG |
15 |
Ein tagname-Eintrag eines aufzählten Typs. |
| IMAGE _ _ _ SYM-KLASSENMITGLIED _ DER _ ENUM |
16 |
Ein Member einer Enumeration. Das Feld Wert gibt das n-te Element an. |
| IMAGE _ SYM _ CLASS _ REGISTER _ PARAM |
17 |
Ein Registerparameter. |
| IMAGE _ SYM _ CLASS _ BIT _ FIELD |
18 |
Ein Bitfeldverweis. Das Feld Wert gibt das n-te Bit im Bitfeld an. |
| IMAGE _ SYM _ CLASS _ BLOCK |
100 |
Ein BB-Datensatz (Anfang des Blocks) oder eb (Ende des Blocks). Das Feld Wert ist die umsetzbare Adresse des Codespeicherorts. |
| IMAGE _ _ SYM-KLASSENFUNKTION _ |
101 |
Ein Wert, der von Microsoft-Tools für Symboldatensätze verwendet wird, die den Umfang einer Funktion definieren: begin function (.bf), end function ( .ef ) und Zeilen in function ( .lf ). Für LF-Datensätze gibt das Feld Wert die Anzahl der Quellzeilen in der Funktion an. Für EF-Datensätze gibt das Feld Wert die Größe des Funktionscodes an. |
| IMAGE _ SYM _ CLASS _ END _ OF _ STRUCT |
102 |
Ein End-of-Structure-Eintrag. |
| IMAGE _ _ SYM-KLASSENDATEI _ |
103 |
Ein Wert, den Microsoft-Tools sowie das herkömmliche COFF-Format für den Quelldatei-Symboldatensatz verwenden. Auf das Symbol folgen zusätzliche Datensätze, die die Datei benennen. |
| ABSCHNITT ZUR _ IMAGE _ _ SYM-KLASSE |
104 |
Eine Definition eines Abschnitts (Microsoft-Tools verwenden stattdessen die STATIC-Speicherklasse). |
| IMAGE _ _ SYM-KLASSE _ WEAK _ EXTERNAL |
105 |
Ein schwaches externes . Weitere Informationen finden Sie unter Auxiliary Format 3: Weak Externals. |
| IMAGE _ SYM _ CLASS _ CLR _ TOKEN |
107 |
Ein CLR-Tokensymbol. Der Name ist eine ASCII-Zeichenfolge, die aus dem Hexadezimalwert des Tokens besteht. Weitere Informationen finden Sie unter CLR-Tokendefinition (nur Objekt). |
Hilfssymboldatensätze
Hilfssymboltabellen-Datensätze folgen immer einigen Standard-Symboltabellen-Datensätzen und gelten für diese. Ein Hilfsdatensatz kann ein beliebiges Format haben, das die Tools erkennen können, aber 18 Bytes müssen für sie zugeordnet werden, damit die Symboltabelle als Array regulärer Größe beibehalten wird. Derzeit erkennen Microsoft-Tools Hilfsformate für die folgenden Arten von Datensätzen: Funktionsdefinitionen, Funktions- und Endsymbole (BF und EF), schwache externe Daten, Dateinamen und Abschnittsdefinitionen.
Der herkömmliche COFF-Entwurf umfasst auch Hilfsdatensatzformate für Arrays und Strukturen. Microsoft-Tools verwenden diese nicht, sondern platzieren diese symbolischen Informationen in Visual C++ Debugformat in den Debugabschnitten.
Hilfsformat 1: Funktionsdefinitionen
Ein Symboltabellendatensatz markiert den Anfang einer Funktionsdefinition, wenn er über folgende Werte verfügt: eine Speicherklasse von EXTERNAL (2), einen Type-Wert, der angibt, dass es sich um eine Funktion (0x20) handelt, und eine Abschnittsnummer, die größer als 0 (null) ist. Beachten Sie, dass ein Symboltabellendatensatz, der über eine Abschnittsnummer von UNDEFINED (0) verfügt, die Funktion nicht definiert und keinen zusätzlichen Datensatz besitzt. Auf Funktionsdefinitionssymbol-Datensätze folgt ein Hilfsdatensatz im unten beschriebenen Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
TagIndex |
Der Symboltabellenindex des entsprechenden BF-Symboldatensatz (begin function). |
| 4 |
4 |
TotalSize |
Die Größe des ausführbaren Codes für die Funktion selbst. Wenn sich die Funktion in einem eigenen Abschnitt befindet, ist sizeOfRawData im Abschnittsheader größer oder gleich diesem Feld, je nach Ausrichtungsüberlegungen. |
| 8 |
4 |
PointerToLinenumber |
Der Dateioffset des ersten COFF-Zeilennummereintrags für die Funktion oder 0 (null), wenn kein Eintrag vorhanden ist. Weitere Informationen finden Sie unter COFF-Zeilennummern (veraltet). |
| 12 |
4 |
PointerToNextFunction |
Der Symboltabellenindex des Datensatzes für die nächste Funktion. Wenn die Funktion die letzte in der Symboltabelle ist, wird dieses Feld auf 0 (null) festgelegt. |
| 16 |
2 |
Nicht verwendet |
Hilfsformat 2: Bf- und EF-Symbole
Für jede Funktionsdefinition in der Symboltabelle beschreiben drei Elemente den Anfang, das Ende und die Anzahl der Zeilen. Jedes dieser Symbole verfügt über die Speicherklasse FUNCTION (101):
Ein Symboldatensatz mit dem Namen .bf (begin-Funktion). Das Feld Wert wird nicht verwendet.
Ein Symboldatensatz mit dem Namen .lf (Zeilen in funktion). Das Feld Wert gibt die Anzahl der Zeilen in der Funktion an.
Ein Symboldatensatz mit dem Namen .ef (Ende der Funktion). Das Feld Wert hat die gleiche Zahl wie das Feld Gesamtgröße im Funktionsdefinitionssymbol-Datensatz.
Auf die Bf- und EF-Symboldatensätze (jedoch nicht auf LF-Datensätze) folgt ein Hilfsdatensatz im folgenden Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Nicht verwendet |
|
| 4 |
2 |
Linenumber |
Die tatsächliche Ordinalzeilennummer (1, 2, 3 und so weiter) in der Quelldatei, die dem BF- oder EF-Datensatz entspricht. |
| 6 |
6 |
Nicht verwendet |
|
| 12 |
4 |
PointerToNextFunction (nur BF) |
Der Symboltabellenindex des nächsten BF-Symboldatensatzes. Wenn die Funktion die letzte in der Symboltabelle ist, wird dieses Feld auf 0 (null) festgelegt. Sie wird nicht für EF-Datensätze verwendet. |
| 16 |
2 |
Nicht verwendet |
Hilfsformat 3: Schwache externe Daten
"Schwache externe Objekte" sind ein Mechanismus für Objektdateien, der Flexibilität zur Linkzeit ermöglicht. Ein Modul kann ein nicht aufgelöstes externes Symbol (sym1) enthalten, aber es kann auch einen zusätzlichen Datensatz enthalten, der angibt, dass, wenn sym1 zur Linkzeit nicht vorhanden ist, stattdessen ein anderes externes Symbol (sym2) verwendet wird, um Verweise aufzulösen.
Wenn eine Definition von sym1 verknüpft ist, wird ein externer Verweis auf das Symbol normal aufgelöst. Wenn eine Definition von sym1 nicht verknüpft ist, verweisen alle Verweise auf das schwache externe für sym1 stattdessen auf sym2. Das externe Symbol sym2 muss immer verknüpft sein. In der Regel wird sie im Modul definiert, das den schwachen Verweis auf sym1 enthält.
Schwache externe Werte werden durch einen Symboltabellendatensatz mit EXTERNAL-Speicherklasse, UNDEF-Abschnittsnummer und einem Wert von 0 dargestellt. Auf den schwach-externen Symboldatensatz folgt ein Hilfsdatensatz im folgenden Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
TagIndex |
Der Symboltabellenindex von sym2. Das Symbol, das verknüpft werden soll, wenn sym1 nicht gefunden wird. |
| 4 |
4 |
Merkmale |
Der Wert IMAGE WEAK EXTERN SEARCH NOLIBRARY gibt an, dass _ _ keine _ _ Bibliothekssuche nach sym1 durchgeführt werden soll. Der Wert IMAGE _ WEAK EXTERN SEARCH LIBRARY gibt _ _ _ an, dass eine Bibliothekssuche nach sym1 durchgeführt werden soll. Der Wert IMAGE _ WEAK EXTERN SEARCH ALIAS gibt _ _ _ an, dass sym1 ein Alias für sym2 ist. |
| 8 |
10 |
Nicht verwendet |
Beachten Sie, dass das Feld Merkmale nicht in WINNT definiert ist. H; Stattdessen wird das Feld Gesamtgröße verwendet.
Hilfsformat 4: Dateien
Dieses Format folgt einem Symboltabellen-Datensatz mit der Speicherklasse FILE (103). Der Symbolname selbst sollte .file lauten, und der darauf folgende zusätzliche Datensatz gibt den Namen einer Quellcodedatei an.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
18 |
Dateiname |
Eine ANSI-Zeichenfolge, die den Namen der Quelldatei angibt. Dieser wird mit NULL-Werten aufschlossen, wenn er kleiner als die maximale Länge ist. |
Hilfsformat 5: Abschnittsdefinitionen
Dieses Format folgt einem Symboltabellen-Datensatz, der einen Abschnitt definiert. Ein solcher Datensatz verfügt über einen Symbolnamen, der dem Namen eines Abschnitts (z. B. .text oder .dre analog) und der Speicherklasse STATIC (3) ist. Der Hilfsdatensatz enthält Informationen zu dem Abschnitt, auf den er verweist. Daher werden einige der Informationen im Abschnittsheader dupliziert.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Länge |
Die Größe der Abschnittsdaten; identisch mit SizeOfRawData im Abschnittsheader. |
| 4 |
2 |
NumberOfRelocations |
Die Anzahl der Verschiebungseinträge für den Abschnitt. |
| 6 |
2 |
NumberOfLinenumbers |
Die Anzahl der Zeilennummereinträge für den Abschnitt. |
| 8 |
4 |
Prüfsumme |
Die Prüfsumme für personenbezogene Daten. Dies ist anwendbar, wenn das _ COMDAT-Flag IMAGE SCN _ LNK _ im Abschnittsheader festgelegt ist. Weitere Informationen finden Sie unter COMDAT-Abschnitte (nur Objekt). |
| 12 |
2 |
Number |
Ein-basierter Index in der Abschnittstabelle für den zugeordneten Abschnitt. Dies wird verwendet, wenn die COMDAT-Auswahleinstellung 5 ist. |
| 14 |
1 |
Auswahl |
Die COMDAT-Auswahlnummer. Dies gilt, wenn der Abschnitt ein COMDAT-Abschnitt ist. |
| 15 |
3 |
Nicht verwendet |
COMDAT-Abschnitte (nur Objekt)
Das Feld Auswahl des Zusätzlichen Format der Abschnittsdefinition ist anwendbar, wenn der Abschnitt ein COMDAT-Abschnitt ist. Ein COMDAT-Abschnitt ist ein Abschnitt, der von mehr als einer Objektdatei definiert werden kann. (Das Flag IMAGE _ SCN _ LNK _ COMDAT wird im Abschnittsflagsfeld des Abschnittsheaders festgelegt.) Das Feld Auswahl bestimmt, wie der Linker die verschiedenen Definitionen von COMDAT-Abschnitten auflöset.
Das erste Symbol mit dem Abschnittswert des COMDAT-Abschnitts muss das Abschnittssymbol sein. Dieses Symbol hat den Namen des Abschnitts, das Feld Wert gleich 0 (null), die Abschnittsnummer des zu verwendenden COMDAT-Abschnitts, das Feld Typ gleich IMAGE SYM TYPE NULL, das Feld Klasse gleich IMAGE SYM CLASS STATIC und einen Zusätzlichen _ _ _ _ _ _ Datensatz. Das zweite Symbol wird als "COMDAT-Symbol" bezeichnet und vom Linker in Verbindung mit dem Feld Auswahl verwendet.
Die Werte für das Feld Auswahl sind unten dargestellt.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| BILD _ COMDAT _ SELECT _ NODUPLICATES |
1 |
Wenn dieses Symbol bereits definiert ist, gibt der Linker den Fehler "Multiplizieren definierter Symbole" aus. |
| IMAGE _ COMDAT _ SELECT _ ANY |
2 |
Jeder Abschnitt, der dasselbe COMDAT-Symbol definiert, kann verknüpft werden. Der Rest wird entfernt. |
| IMAGE _ COMDAT _ SELECT _ SAME _ SIZE |
3 |
Der Linker wählt einen beliebigen Abschnitt unter den Definitionen für dieses Symbol aus. Wenn alle Definitionen nicht die gleiche Größe haben, wird ein Fehler mit einem "multiplizieren definierten Symbol" ausgegeben. |
| BILD _ COMDAT _ SELECT EXACT _ _ MATCH |
4 |
Der Linker wählt einen beliebigen Abschnitt unter den Definitionen für dieses Symbol aus. Wenn alle Definitionen nicht genau übereinstimmen, wird ein Multiplikationsfehler für definierte Symbole ausgegeben. |
| BILD _ COMDAT _ SELECT _ ASSOCIATIVE |
5 |
Der Abschnitt ist verknüpft, wenn ein bestimmter anderer COMDAT-Abschnitt verknüpft ist. Dieser andere Abschnitt wird durch das Feld Zahl des Hilfssymboldatensatzes für die Abschnittsdefinition angegeben. Diese Einstellung ist nützlich für Definitionen, die Komponenten in mehreren Abschnitten enthalten (z. B. Code in einem und Daten in einem anderen), wobei jedoch alle als Gruppe verknüpft oder verworfen werden müssen. Der andere Abschnitt, dem dieser Abschnitt zugeordnet ist, muss ein COMDAT-Abschnitt sein, der ein weiterer assoziativer COMDAT-Abschnitt sein kann. Die Abschnittsassoziationskette eines assoziativen COMDAT-Abschnitts kann keine Schleife bilden. Die Abschnittsassoziationskette muss schließlich zu einem COMDAT-Abschnitt gelangen, für den IMAGE _ COMDAT _ SELECT _ ASSOCIATIVE nicht festgelegt ist. |
| IMAGE _ COMDAT _ SELECT _ LARGEST |
6 |
Der Linker wählt die größte Definition aus allen Definitionen für dieses Symbol aus. Wenn mehrere Definitionen diese Größe haben, ist die Wahl zwischen ihnen willkürlich. |
CLR-Tokendefinition (nur Objekt)
Dieses Hilfssymbol folgt in der Regel dem IMAGE _ SYM _ CLASS _ CLR _ TOKEN. Es wird verwendet, um dem Namespace der COFF-Symboltabelle ein Token zu zuordnen.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
1 |
bAuxType |
Muss IMAGE _ AUX _ SYMBOL TYPE TOKEN DEF _ _ _ (1) sein. |
| 1 |
1 |
bReserved |
Reserviert, muss 0 (null) sein. |
| 2 |
4 |
SymbolTableIndex |
Der Symbolindex des COFF-Symbols, auf das diese CLR-Tokendefinition verweist. |
| 6 |
12 |
Reserviert, muss 0 (null) sein. |
COFF-Zeichenfolgentabelle
Unmittelbar nach der COFF-Symboltabelle befindet sich die COFF-Zeichenfolgentabelle. Die Position dieser Tabelle wird gefunden, indem die Symboltabellenadresse im COFF-Header verwendet und die Anzahl der Symbole multipliziert mit der Größe eines Symbols hinzugefügt wird.
Am Anfang der COFF-Zeichenfolgentabelle befinden sich 4 Bytes, die die Gesamtgröße (in Bytes) des Rests der Zeichenfolgentabelle enthalten. Diese Größe schließt das Größenfeld selbst ein, sodass der Wert an dieser Position 4 wäre, wenn keine Zeichenfolgen vorhanden wären.
Im Anschluss an die Größe folgen null-terminige Zeichenfolgen, auf die symbole in der COFF-Symboltabelle zeigen.
Attributzertifikattabelle (nur Bild)
Attributzertifikate können einem Image zugeordnet werden, indem eine Attributzertifikattabelle hinzugefügt wird. Die Attributzertifikattabelle besteht aus einem Satz zusammenhängender, quadword-ausgerichteter Attributzertifikateinträge. Zwischen dem ursprünglichen Ende der Datei und dem Anfang der Attributzertifikattabelle wird 0 Auf padding eingefügt, um diese Ausrichtung zu erreichen. Jeder Attributzertifikateintrag enthält die folgenden Felder.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
dwLength |
Gibt die Länge des Attributzertifikateintrags an. |
| 4 |
2 |
wRevision |
Enthält die Zertifikatversionsnummer. Weitere Informationen finden Sie im folgenden Text. |
| 6 |
2 |
wCertificateType |
Gibt den Inhaltstyp in bCertificate an. Weitere Informationen finden Sie im folgenden Text. |
| 8 |
Finden Sie hier |
bCertificate |
Enthält ein Zertifikat, z. B. eine Authenticode-Signatur. Weitere Informationen finden Sie im folgenden Text. |
Der virtuelle Adresswert aus dem Eintrag Zertifikattabelle im Optional Header Data Directory ist ein Dateioffset zum ersten Attributzertifikateintrag. Auf nachfolgende Einträge wird zugegriffen, indem die dwLength-Bytes dieses Eintrags, die auf ein 8-Byte-Vielfaches aufgerundet werden, ab dem Anfang des aktuellen Attributzertifikateintrags erhöht werden. Dies wird so lange fortgesetzt, bis die Summe der gerundeten dwLength-Werte dem Size-Wert aus dem Eintrag Certificates Table im Optional Header Data Directory entspricht. Wenn die Summe der gerundeten dwLength-Werte nicht dem Wert Size entspricht, ist entweder die Attributzertifikattabelle oder das Feld Size beschädigt.
Beispiel: Der Zertifikattabelleneintrag des optionalen Headerdatenverzeichnisses enthält Folgendes:
virtual address = 0x5000
size = 0x1000
Das erste Zertifikat beginnt am Offset 0x5000 dem Anfang der Datei auf dem Datenträger. So führen Sie alle Attributzertifikateinträge aus:
- Fügen Sie dem Startoffset den dwLength-Wert des ersten Attributzertifikats hinzu.
- Rundet den Wert von Schritt 1 auf das nächste 8-Byte-Vielfache, um den Offset des zweiten Attributzertifikateintrags zu finden.
- Fügen Sie den Offsetwert aus Schritt 2 dem dwLength-Wert des zweiten Attributzertifikateintrags hinzu, und runden Sie auf das nächste 8-Byte-Vielfache auf, um den Offset des dritten Attributzertifikateintrags zu bestimmen.
- Wiederholen Sie Schritt 3 für jedes nachfolgende Zertifikat, bis der berechnete Offset 0x6000 (0x5000 Start + 0x1000 Gesamtgröße) entspricht. Dies bedeutet, dass Sie die gesamte Tabelle durchschritten haben.
Alternativ können Sie die Zertifikateinträge aufzählen, indem Sie die Win32-Funktion ImageEnumerateCertificates in einer Schleife aufrufen. Einen Link zur Referenzseite der Funktion finden Sie unter Verweise auf.
Attributzertifikattabelleneinträge können jeden Zertifikattyp enthalten, solange der Eintrag über den richtigen dwLength-Wert, einen eindeutigen wRevision-Wert und einen eindeutigen wCertificateType-Wert verfügt. Der häufigste Typ des Zertifikattabelleneintrags ist eine WIN CERTIFICATE-Struktur, die in Wintrust.h dokumentiert und im weiteren _ Verlauf dieses Abschnitts erläutert wird.
Die Optionen für das WIN _ CERTIFICATE wRevision-Mitglied umfassen Folgendes (aber nicht beschränkt auf).
| Wert | Name | Notizen |
|---|---|---|
| 0x0100 |
WIN _ CERT _ REVISION _ 1 _ 0 |
Version 1, Legacyversion der Win _ Certificate-Struktur. Es wird nur zum Überprüfen von älteren Authenticode-Signaturen unterstützt. |
| 0x0200 |
WIN _ CERT _ REVISION _ 2 _ 0 |
Version 2 ist die aktuelle Version der Win _ Certificate-Struktur. |
Die Optionen für das WIN _ CERTIFICATE wCertificateType-Member umfassen (aber nicht beschränkt auf) die Elemente in der folgenden Tabelle. Beachten Sie, dass einige Werte derzeit nicht unterstützt werden.
| Wert | Name | Notizen |
|---|---|---|
| 0x0001 |
WIN _ _ CERT-TYP _ X509 |
bCertificate enthält ein X.509-Zertifikat Nicht unterstützt |
| 0x0002 |
WIN _ _ CERT-TYP _ _ PKCS-SIGNIERTE _ DATEN |
bCertificate enthält eine PKCS # 7 SignedData-Struktur. |
| 0x0003 |
WIN _ _ CERT-TYP _ RESERVIERT _ 1 |
Reserviert |
| 0x0004 |
WIN _ CERT _ TYPE _ TS _ STACK _ SIGNED |
Zertifikatsignatur für Terminalserverprotokollstapel Nicht unterstützt |
Der bCertificate-Member der WIN CERTIFICATE-Struktur enthält ein Bytearray variabler Länge mit dem durch _ wCertificateType angegebenen Inhaltstyp. Der von Authenticode unterstützte Typ ist WIN _ CERT _ TYPE _ PKCS _ SIGNED _ DATA, eine PKCS # 7 SignedData-Struktur. Weitere Informationen zum Format der digitalen Authenticode-Signatur finden Sie unter Windows Authenticode Portable Executable Signature Format.
Wenn der bCertificate-Inhalt nicht an einer Quadwordgrenze endet, wird der Attributzertifikateintrag vom Ende von bCertificate bis zur nächsten Quadwordgrenze mit Nullen aufschlossen.
Der dwLength-Wert ist die Länge der finalisierten WIN _ CERTIFICATE-Struktur und wird wie die folgenden berechnet:
dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)
Diese Länge sollte die Größe aller Beläge enthalten, die verwendet werden, um die Anforderung zu erfüllen, dass jede WIN _ CERTIFICATE-Struktur quadword-ausgerichtet ist:
dwLength += (8 - (dwLength & 7)) & 7;
Die Größe der Zertifikattabelle, die im Eintrag Zertifikattabelle unter Optional Header Data Directories (Image Only) (Optionale Headerdatenverzeichnisse (nur Bild)) angegeben ist,enthält die Auf padding.)
Weitere Informationen zur Verwendung der ImageHlp-API zum Aufzählen, Hinzufügen und Entfernen von Zertifikaten aus PE-Dateien finden Sie unter ImageHlp Functions ( ImageHlp-Funktionen).
Zertifikatdaten
Wie im vorherigen Abschnitt erwähnt, können die Zertifikate in der Attributzertifikattabelle einen beliebigen Zertifikattyp enthalten. Zertifikate, die die Integrität einer PE-Datei sicherstellen, können einen PE-Imagehash enthalten.
Ein PE-Imagehash (oder Dateihash) ähnelt einer Dateiüberprüfungssumme, da der Hashalgorithmus einen Nachrichtenhash erzeugt, der mit der Integrität einer Datei verknüpft ist. Eine Prüfsumme wird jedoch von einem einfachen Algorithmus erstellt und hauptsächlich verwendet, um zu erkennen, ob ein Speicherblock auf dem Datenträger fehlerhaft geworden ist und die dort gespeicherten Werte beschädigt wurden. Ein Dateihash ähnelt einer Prüfsumme, da er auch Dateibeschädigungen erkennt. Im Gegensatz zu den meisten Prüfsummenalgorithmen ist es jedoch sehr schwierig, eine Datei zu ändern, ohne den Dateihash von ihrem ursprünglichen unveränderten Wert zu ändern. Ein Dateihash kann daher verwendet werden, um absichtliche und sogar kleine Änderungen an einer Datei zu erkennen, z. B. solche, die von Viren, Hackern oder programmgesteuerten Antivirusprogrammen eingeführt werden.
Wenn der Image-Digest in einem Zertifikat enthalten ist, muss er bestimmte Felder im PE-Image ausschließen, z. B. den Eintrag Prüfsumme und Zertifikattabelle in Optionale Headerdatenverzeichnisse. Dies liegt daran, dass das Hinzufügen eines Zertifikats diese Felder ändert und dazu führen würde, dass ein anderer Hashwert berechnet wird.
Die Win32 ImageGetDigestStream-Funktion stellt einen Datenstrom aus einer PE-Zieldatei für Hashfunktionen zur Verfügung. Dieser Datenstrom bleibt konsistent, wenn Einer PE-Datei Zertifikate hinzugefügt oder daraus entfernt werden. Basierend auf den Parametern, die an ImageGetDigestStream übergeben werden, können andere Daten aus dem PE-Image bei der Hashberechnung weggelassen werden. Einen Link zur Referenzseite der Funktion finden Sie unter Verweise auf.
Delay-Load Tabellen importieren (nur Image)
Diese Tabellen wurden dem Image hinzugefügt, um einen einheitlichen Mechanismus zu unterstützen, mit dem Anwendungen das Laden einer DLL bis zum ersten Aufruf dieser DLL verzögern können. Das Layout der Tabellen entspricht dem der herkömmlichen Importtabellen, die in Abschnitt 6.4, The .idata Section , beschrieben werden. Hier werden nur einige Details erläutert.
Die Delay-Load Directory-Tabelle
Die Verzeichnistabelle delay-load ist das Gegenstück zur Importverzeichnistabelle. Sie kann über den Eintrag Deskriptor für verzögerten Import in der Liste optionaler Headerdatenverzeichnisse (Offset 200) abgerufen werden. Die Tabelle ist wie folgt angeordnet:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Attribute |
Muss Null sein. |
| 4 |
4 |
Name |
Die RVA des Namens der zu ladenden DLL. Der Name befindet sich im schreibgeschützten Datenabschnitt des Images. |
| 8 |
4 |
Modulhand handle |
Die RVA des Modulhandls (im Datenabschnitt des Images) der DLL, die verzögert geladen werden soll. Er wird für die Speicherung durch die Routine verwendet, die bereitgestellt wird, um das verzögerte Laden zu verwalten. |
| 12 |
4 |
Verzögerte Importadressentabelle |
Das RVA der Importadressentabelle mit verzögerungsbasiertem Ladevorgang. Weitere Informationen finden Sie unter Delay Import Address Table (IAT). |
| 16 |
4 |
Tabelle "Verzögerter Importname" |
Die RVA der Namenstabelle für verzögertes Laden, die die Namen der Importe enthält, die möglicherweise geladen werden müssen. Dies entspricht dem Layout der Importnamentabelle. Weitere Informationen finden Sie unter Hinweis-/Namenstabelle. |
| 20 |
4 |
Importtabelle mit gebundener Verzögerung |
Das RVA der gebundenen Adresstabelle für verzögertes Laden, sofern vorhanden. |
| 24 |
4 |
Importtabelle mit Verzögerung beim Entladen |
Die RVA der Entladungsverzögerungs-Adresstabelle, sofern vorhanden. Dies ist eine genaue Kopie der Tabelle mit den Verzögertimportadressen. Wenn der Aufrufer die DLL entlädt, sollte diese Tabelle über die Verzögerte Importadressentabelle zurückkopiert werden, damit nachfolgende Aufrufe der DLL weiterhin ordnungsgemäß den Länkmechanismus verwenden. |
| 28 |
4 |
Zeitstempel |
Der Zeitstempel der DLL, an die dieses Image gebunden wurde. |
Die Tabellen, auf die in dieser Datenstruktur verwiesen wird, sind genauso organisiert und sortiert wie ihre Entsprechungen für herkömmliche Importe. Weitere Informationen finden Sie im Abschnitt .idata.
Attribute
Derzeit sind keine Attributflags definiert. Der Linker legt dieses Feld im Bild auf 0 (null) fest. Dieses Feld kann verwendet werden, um den Datensatz zu erweitern, indem das Vorhandensein neuer Felder angegeben wird, oder es kann verwendet werden, um Verhalten für die Hilfsfunktionen zum Verzögern oder Entladen anzugeben.
Name
Der Name der DLL, die verzögert geladen werden soll, befindet sich im Abschnitt mit schreibgeschützten Daten des Images. Auf sie wird über das Feld szName verwiesen.
Modulhandle
Das Handle der DLL, die verzögert geladen werden soll, befindet sich im Datenabschnitt des Images. Das Phmod-Feld zeigt auf das Handle. Das bereitgestellte Hilfprogramm für verzögertes Laden verwendet diesen Speicherort, um das Handle in der geladenen DLL zu speichern.
Verzögerte Importadresstabelle
Der Verzögerte Importadresstabelle (Delay Import Address Table, IAT) wird durch den Delay Import-Deskriptor über das Feld pIAT verwiesen. Das Hilfprogramm für verzögertes Laden aktualisiert diese Zeiger mit den tatsächlichen Einstiegspunkten, sodass sich die Thunks nicht mehr in der aufrufenden Schleife befinden. Auf die Funktionszeiger wird mithilfe des Ausdrucks pINT->u1.Function zugegriffen.
Tabelle "Importname verzögern"
Die Tabelle mit verzögerten Importnamen (Delay Import Name Table, INT) enthält die Namen der Importe, die möglicherweise geladen werden müssen. Sie werden auf die gleiche Weise wie die Funktionszeiger in der IAT sortiert. Sie bestehen aus den gleichen Strukturen wie der Standard-INT und werden mithilfe des Ausdrucks pINT->u1.AddressOfData->Name[0] aufgerufen.
Verzögerte gebundene Importadresstabelle und Zeitstempel
Die Tabelle mit verzögert gebundenen Importadressen (DELAY Bound Import Address Table, BIAT) ist eine optionale Tabelle mit IMAGE _ THUNK _ DATA-Elementen, die zusammen mit dem Zeitstempelfeld der Verzeichnistabelle für verzögertes Laden durch eine Postprozessbindungsphase verwendet wird.
Verzögertes Entladen der Importadresstabelle
Die UiAT (Delay Unload Import Address Table) ist eine optionale Tabelle mit IMAGE _ THUNK _ DATA-Elementen, die der Entladecode verwendet, um eine explizite Entladeanforderung zu verarbeiten. Sie besteht aus initialisierten Daten im schreibgeschützten Abschnitt, bei denen es sich um eine genaue Kopie des ursprünglichen IAT handelt, der den Code auf die Thunks mit verzögerten Ladevorgang verweist. Bei der Entladeanforderung kann die Bibliothek freigegeben, der * Phmod gelöscht und die UIAT über den IAT geschrieben werden, um den Zustand des Vorabladens wiederherzustellen.
Spezielle Abschnitte
- Abschnitt ".debug"
- Drectve-Abschnitt (nur Objekt)
- Abschnitt ".edata" (nur Bild)
- Der .idata-Abschnitt
- Der PDATA-Abschnitt
- Abschnitt .reloc (nur Bild)
- Tls-Abschnitt
- Die Struktur der Auslastungskonfiguration (nur Image)
- Abschnitt ".rsrc"
- .cormeta-Abschnitt (nur Objekt)
- Der SXDATA-Abschnitt
Typische COFF-Abschnitte enthalten Code oder Daten, die Linker und Microsoft Win32-Lader ohne besondere Kenntnisse des Abschnittsinhalts verarbeiten. Der Inhalt ist nur für die Anwendung relevant, die verknüpft oder ausgeführt wird.
Einige COFF-Abschnitte haben jedoch besondere Bedeutungen, wenn sie in Objekt- oder Bilddateien gefunden werden. Tools und Ladeprogramme erkennen diese Abschnitte, da sie spezielle Flags im Abschnittsheader festgelegt haben, weil spezielle Positionen im optionalen Header des Bilds darauf zeigen oder weil der Abschnittsname selbst eine spezielle Funktion des Abschnitts angibt. (Auch wenn der Abschnittsname selbst keine spezielle Funktion des Abschnitts angibt, wird der Abschnittsname gemäß Konvention vorgegeben, sodass die Autoren dieser Spezifikation in allen Fällen auf einen Abschnittsnamen verweisen können.)
Die reservierten Abschnitte und ihre Attribute werden in der folgenden Tabelle beschrieben, gefolgt von detaillierten Beschreibungen für die Abschnittstypen, die in ausführbaren Dateien beibehalten werden, und die Abschnittstypen, die Metadaten für Erweiterungen enthalten.
| Abschnittsname | Inhalt | Merkmale |
|---|---|---|
| .bss |
Nicht initialisierte Daten (kostenloses Format) |
IMAGE _ SCN _ CNT _ UNINITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ WRITE |
| .cormeta |
CLR-Metadaten, die angeben, dass die Objektdatei verwalteten Code enthält |
IMAGE _ SCN _ LNK _ INFO |
| .data |
Initialisierte Daten (kostenloses Format) |
IMAGE _ SCN _ CNT _ _ INITIALISIERTES | DATENIMAGE _ SCN MEM READ IMAGE _ _ | _ SCN MEM _ _ WRITE |
| .debug$F |
Generierte FPO-Debuginformationen (nur Objekt, nur x86-Architektur und jetzt veraltet) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ DISCARDABLE |
| .debug$P |
Vorkompilierte Debugtypen (nur Objekt) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ DISCARDABLE |
| .debug$S |
Debugsymbole (nur Objekt) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ DISCARDABLE |
| .debug$T |
Debugtypen (nur Objekt) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ DISCARDABLE |
| .drective |
Linkeroptionen |
IMAGE _ SCN _ LNK _ INFO |
| .edata |
Exportieren von Tabellen |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ |
| .idata |
Importieren von Tabellen |
IMAGE _ SCN _ CNT _ _ INITIALISIERTES | DATENIMAGE _ SCN MEM READ IMAGE _ _ | _ SCN MEM _ _ WRITE |
| .idlsym |
Schließt registrierte SEH (nur Bild) zur Unterstützung von IDL-Attributen ein. Weitere Informationen finden Sie unter "IDL-Attribute" unter Verweise am Ende dieses Themas. |
IMAGE _ SCN _ LNK _ INFO |
| .pdata |
Ausnahmeinformationen |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ |
| .rdata |
Schreibgeschützte initialisierte Daten |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ |
| .reloc |
Bildverlagerungen |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ | IMAGE _ SCN _ MEM _ DISCARDABLE |
| .rsrc |
Ressourcenverzeichnis |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ |
| SBSS |
GP-relative nicht initialisierte Daten (kostenloses Format) |
IMAGE _ SCN _ CNT _ UNINITIALIZED _ DATA IMAGE | _ SCN MEM READ IMAGE _ _ | _ SCN MEM WRITE IMAGE _ _ | _ SCN _ GPREL Das IMAGE _ SCN _ GPREL-Flag sollte nur für IA64-Architekturen festgelegt werden. Dieses Flag ist für andere Architekturen nicht gültig. Das IMAGE _ _ SCN-GPREL-Flag gilt nur für Objektdateien. Wenn dieser Abschnittstyp in einer Bilddatei angezeigt wird, darf das IMAGE _ _ SCN-GPREL-Flag nicht festgelegt werden. |
| .sdata |
GP-relative initialisierte Daten (kostenloses Format) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA IMAGE | _ SCN MEM READ _ IMAGE _ | _ SCN MEM WRITE IMAGE _ _ | _ SCN _ GPREL Das IMAGE _ SCN _ GPREL-Flag sollte nur für IA64-Architekturen festgelegt werden. Dieses Flag ist für andere Architekturen nicht gültig. Das IMAGE _ _ SCN-GPREL-Flag gilt nur für Objektdateien. Wenn dieser Abschnittstyp in einer Bilddatei angezeigt wird, darf das IMAGE _ _ SCN-GPREL-Flag nicht festgelegt werden. |
| .srdata |
GP-relative schreibgeschützte Daten (kostenloses Format) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA IMAGE | _ SCN MEM READ _ IMAGE _ | _ SCN _ GPREL Das IMAGE _ SCN _ GPREL-Flag sollte nur für IA64-Architekturen festgelegt werden. Dieses Flag ist für andere Architekturen nicht gültig. Das IMAGE _ _ SCN-GPREL-Flag gilt nur für Objektdateien. Wenn dieser Abschnittstyp in einer Bilddatei angezeigt wird, darf das IMAGE _ _ SCN-GPREL-Flag nicht festgelegt werden. |
| .sxdata |
Registrierte Ausnahmehandlerdaten (freies Format und nur x86/Objekt) |
IMAGE _ SCN _ LNK _ INFO Enthält den Symbolindex jedes Ausnahmehandlers, auf den der Code in dieser Objektdatei verweist. Das Symbol kann für ein UNDEF-Symbol oder ein Symbol sein, das in diesem Modul definiert ist. |
| .text |
Ausführbarer Code (kostenloses Format) |
IMAGE _ SCN _ CNT _ CODE | IMAGE _ SCN _ MEM _ EXECUTE | IIMAGE _ SCN _ MEM _ READ |
| TLS |
Threadlokaler Speicher (nur Objekt) |
IMAGE _ SCN _ CNT _ _ INITIALISIERTES | DATENIMAGE _ SCN MEM READ IMAGE _ _ | _ SCN MEM _ _ WRITE |
| .tls$ |
Threadlokaler Speicher (nur Objekt) |
IMAGE _ SCN _ CNT _ _ INITIALISIERTES | DATENIMAGE _ SCN MEM READ IMAGE _ _ | _ SCN MEM _ _ WRITE |
| .vsdata |
GP-relative initialisierte Daten (kostenloses Format und nur für ARM-, SH4- und Thumb-Architekturen) |
IMAGE _ SCN _ CNT _ _ INITIALISIERTES | DATENIMAGE _ SCN MEM READ IMAGE _ _ | _ SCN MEM _ _ WRITE |
| .xdata |
Ausnahmeinformationen (kostenloses Format) |
IMAGE _ SCN _ CNT _ INITIALIZED _ DATA | IMAGE _ SCN _ MEM _ READ |
Einige der hier aufgeführten Abschnitte sind als "Nur Objekt" oder "Nur Bild" gekennzeichnet, um anzugeben, dass ihre spezielle Semantik nur für Objektdateien bzw. Bilddateien relevant ist. Ein Abschnitt, der als "Nur Bild" gekennzeichnet ist, wird möglicherweise weiterhin in einer Objektdatei angezeigt, um in die Bilddatei zu gelangen, aber der Abschnitt hat keine besondere Bedeutung für den Linker, sondern nur für das Bilddateiladeprogramm.
Abschnitt ".debug"
Der Abschnitt .debug wird in Objektdateien verwendet, um vom Compiler generierte Debuginformationen zu enthalten, und in Imagedateien, die alle generierten Debuginformationen enthalten. In diesem Abschnitt wird die Paketierung von Debuginformationen in Objekt- und Imagedateien beschrieben.
Im nächsten Abschnitt wird das Format des Debugverzeichnisses beschrieben, das sich an einer beliebigen Stelle im Image befinden kann. In den nachfolgenden Abschnitten werden die "Gruppen" in Objektdateien beschrieben, die Debuginformationen enthalten.
Der Standardwert für den Linker ist, dass Debuginformationen nicht dem Adressraum des Bilds zugeordnet werden. Ein DEBUG-Abschnitt ist nur vorhanden, wenn Debuginformationen im Adressraum zugeordnet sind.
Debugverzeichnis (nur Bild)
Bilddateien enthalten ein optionales Debugverzeichnis, das angibt, welche Form von Debuginformationen vorhanden ist und wo sie sich befinden. Dieses Verzeichnis besteht aus einem Array von Debugverzeichniseinträgen, deren Speicherort und Größe im optionalen Imageheader angegeben sind.
Das Debugverzeichnis kann sich in einem verwerfbaren DEBUG-Abschnitt befinden (sofern vorhanden), oder es kann in einem anderen Abschnitt in der Imagedatei enthalten sein oder überhaupt nicht in einem Abschnitt enthalten sein.
Jeder Debugverzeichniseintrag identifiziert den Speicherort und die Größe eines Blocks mit Debuginformationen. Die angegebene RVA kann 0 (null) sein, wenn die Debuginformationen nicht durch einen Abschnittsheader abgedeckt werden (d. b. sie befinden sich in der Imagedatei und werden nicht dem Laufzeitadressraum zugeordnet). Wenn es zugeordnet ist, ist das RVA seine Adresse.
Ein Debugverzeichniseintrag hat das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Merkmale |
Reserviert, muss 0 (null) sein. |
| 4 |
4 |
TimeDateStamp |
Die Uhrzeit und das Datum der Erstellung der Debugdaten. |
| 8 |
2 |
MajorVersion |
Die Hauptversionsnummer des Debugdatenformats. |
| 10 |
2 |
MinorVersion |
Die Nebenversionsnummer des Debugdatenformats. |
| 12 |
4 |
type |
Das Format der Debuginformationen. Dieses Feld ermöglicht die Unterstützung mehrerer Debugger. Weitere Informationen finden Sie unter Debugtyp. |
| 16 |
4 |
SizeOfData |
Die Größe der Debugdaten (ohne das Debugverzeichnis selbst). |
| 20 |
4 |
AddressOfRawData |
Die Adresse der Debugdaten beim Laden relativ zur Imagebasis. |
| 24 |
4 |
PointerToRawData |
Der Dateizeiger auf die Debugdaten. |
Debugtyp
Die folgenden Werte werden für das Feld Typ des Debugverzeichniseintrags definiert:
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| _ _ BILDDEBUGTYP _ UNBEKANNT |
0 |
Ein unbekannter Wert, der von allen Tools ignoriert wird. |
| _ _ BILDDEBUGTYP _ COFF |
1 |
Die COFF-Debuginformationen (Zeilennummern, Symboltabelle und Zeichenfolgentabelle). Auf diese Art von Debuginformationen wird auch von Feldern in Dateiheadern verwiesen. |
| CODEVIEW _ DES _ _ BILDDEBUGTYPS |
2 |
Die Visual C++ Debuginformationen. |
| _ _ _ BILDDEBUGTYP-FPO |
3 |
Die Auslassungsinformationen (FPO) des Framezeigers. Diese Informationen informieren den Debugger darüber, wie nicht standardmäßige Stapelrahmen interpretiert werden, die das EBP-Register für einen anderen Zweck als als Framezeiger verwenden. |
| _ _ BILDDEBUGTYP _ MISC |
4 |
Der Speicherort der DBG-Datei. |
| AUSNAHME BEIM _ _ DEBUGGEN VON _ BILDERN |
5 |
Eine Kopie des PDATA-Abschnitts. |
| IMAGE _ DEBUG _ TYPE _ FIXUP |
6 |
Reserviert. |
| _ _ BILDDEBUGTYP _ OMAP _ ZU _ SRC |
7 |
Die Zuordnung von einem RVA im Image zu einem RVA im Quellimage. |
| _ _ BILDDEBUGTYP _ OMAP _ AUS _ SRC |
8 |
Die Zuordnung von einem RVA im Quellimage zu einem RVA im Image. |
| _ _ BILDDEBUGTYP _ " BORLAND" |
9 |
Reserviert für Borland. |
| _ _ IMAGEDEBUGTYP _ RESERVIERT10 |
10 |
Reserviert. |
| _ _ IMAGEDEBUGTYP _ CLSID |
11 |
Reserviert. |
| _ _ IMAGEDEBUGTYP _ REPRO |
16 |
PE-Determinismus oder Reproduzierbarkeit. |
| _ _ BILDDEBUGTYP _ EX _ DLLCHARACTERISTICS | 20 | Erweiterte DLL-Eigenschaftenbits. |
Wenn das Feld Type auf IMAGE _ DEBUG _ TYPE FPO festgelegt ist, handelt es sich bei den Debugrohdaten um ein Array, in dem jeder Member den Stapelrahmen _ einer Funktion beschreibt. Nicht für jede Funktion in der Imagedatei müssen FPO-Informationen definiert sein, obwohl der Debugtyp FPO ist. Für Funktionen ohne FPO-Informationen wird davon ausgegangen, dass sie normale Stapelrahmen haben. Das Format für FPO-Informationen lautet wie folgt:
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
typedef struct _FPO_DATA {
DWORD ulOffStart; // offset 1st byte of function code
DWORD cbProcSize; // # bytes in function
DWORD cdwLocals; // # bytes in locals/4
WORD cdwParams; // # bytes in params/4
WORD cbProlog : 8; // # bytes in prolog
WORD cbRegs : 3; // # regs saved
WORD fHasSEH : 1; // TRUE if SEH in func
WORD fUseBP : 1; // TRUE if EBP has been allocated
WORD reserved : 1; // reserved for future use
WORD cbFrame : 2; // frame type
} FPO_DATA;
Das Vorhandensein eines Eintrags vom Typ IMAGE DEBUG TYPE REPRO gibt an, dass die PE-Datei auf eine Weise erstellt wurde, um _ _ _ Determinismus oder Reproduzierbarkeit zu erreichen. Wenn sich die Eingabe nicht ändert, ist die PE-Ausgabedatei garantiert bit-for-bit identisch, unabhängig davon, wann oder wo die PE erzeugt wird. Verschiedene Datums-/Uhrzeitstempelfelder in der PE-Datei werden mit einem Teil oder allen Bits aus einem berechneten Hashwert gefüllt, der PE-Dateiinhalt als Eingabe verwendet und daher nicht mehr das tatsächliche Datum und die Uhrzeit der Erstellung einer PE-Datei oder zugehöriger spezifischer Daten innerhalb der PE-Datei darstellen. Die Rohdaten dieses Debugeintrags können leer sein oder einen berechneten Hashwert enthalten, dem ein Vier-Byte-Wert vorangegangen ist, der die Hashwertlänge darstellt.
Wenn das Feld Typ auf IMAGE _ DEBUG _ TYPE EX _ DLLCHARACTERISTICS festgelegt ist, enthalten die Debugrohdaten erweiterte DLL-Eigenschaftenbits, zusätzlich zu denJenigen, die im optionalen Header des Images festgelegt werden _ können. Weitere Informationen finden Sie im Abschnitt Optionale Header-Windows-Specific Felder (nur Bild).
Erweiterte DLL-Merkmale
Die folgenden Werte werden für die erweiterten DLL-Eigenschaftenbits definiert.
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| _IMAGE-DLLCHARACTERISTICS _ _ EX-COMPAT _ | 0x0001 | Das Image ist MIT DEM SYSTEM -Image kompatibel. |
.debug$F (nur Objekt)
Die Daten in diesem Abschnitt wurden in Visual C++ Version 7.0 und höher durch einen umfangreicheren Satz von Daten ersetzt, die in einen .debug$S-Unterabschnitt ausgegeben werden.
Objektdateien können .debug$F-Abschnitte enthalten, deren Inhalt mindestens ein FPO DATA-Datensatz ist (Informationen zur Auslassung des _ Framezeigers). Weitere Informationen finden Sie unter "IMAGE _ DEBUG _ TYPE _ FPO" im Debugtyp.
Der Linker erkennt diese DEBUG$F-Datensätze. Wenn Debuginformationen generiert werden, sortiert der Linker die FPO DATA-Datensätze nach Prozedur-RVA und generiert einen _ Debugverzeichniseintrag für diese.
Der Compiler sollte keine FPO-Datensätze für Prozeduren generieren, die ein Standardframeformat haben.
.debug$S (nur Objekt)
Dieser Abschnitt enthält Visual C++ Debuginformationen (symbolische Informationen).
.debug$P (nur Objekt)
Dieser Abschnitt enthält Visual C++ Debuginformationen (vorkompilierte Informationen). Hierbei handelt es sich um freigegebene Typen für alle Objekte, die mithilfe des vorkompilierten Headers kompiliert wurden, der mit diesem -Objekt generiert wurde.
.debug$T (nur Objekt)
Dieser Abschnitt enthält Visual C++ Debuginformationen (Typinformationen).
Linkerunterstützung für Microsoft-Debuginformationen
Um Debuginformationen zu unterstützen, muss der Linker:
Sammelt alle relevanten Debugdaten aus den Abschnitten .debug$F, debug$S, .debug$P und .debug$T.
Verarbeitet diese Daten zusammen mit den vom Linker generierten Debuginformationen in der PDB-Datei und erstellt einen Debugverzeichniseintrag, um darauf zu verweisen.
Der Dretrope-Abschnitt (nur Objekt)
Ein Abschnitt ist ein Direktivenabschnitt, wenn das FLAG IMAGE SCN LNK INFO im Abschnittsheader festgelegt ist und den _ _ Abschnittsnamen _ .dre enthalten hat. Der Linker entfernt nach der Verarbeitung der Informationen einen DRE-Abschnitt, sodass der Abschnitt nicht in der verknüpften Bilddatei angezeigt wird.
Ein Dresaie-Abschnitt besteht aus einer Textzeichenfolge, die als ANSI oder UTF-8 codiert werden kann. Wenn die UTF-8-Byte-Reihenfolgenmarkierung (BOM, ein Drei-Byte-Präfix, das aus 0xEF, 0xBB und 0xBF besteht) nicht vorhanden ist, wird die Direktivenzeichenfolge als ANSI interpretiert. Die Direktivenzeichenfolge ist eine Reihe von Linkeroptionen, die durch Leerzeichen getrennt sind. Jede Option enthält einen Bindestrich, den Optionsnamen und ein beliebiges entsprechendes Attribut. Wenn eine Option Leerzeichen enthält, muss die Option in Anführungszeichen eingeschlossen werden. Der Abschnitt .drectve darf keine Verschiebungen oder Zeilennummern aufweisen.
Abschnitt ".edata" (nur Bild)
Der Abschnitt zum Exportieren von Daten mit dem Namen .edata enthält Informationen zu Symbolen, auf die andere Bilder über dynamisches Verknüpfen zugreifen können. Exportierte Symbole befinden sich in der Regel in DLLs, aber DLLs können auch Symbole importieren.
Eine Übersicht über die allgemeine Struktur des Exportabschnitts wird unten beschrieben. Die beschriebenen Tabellen sind in der Regel in der Datei in der angegebenen Reihenfolge zusammenhängend (dies ist jedoch nicht erforderlich). Nur die Exportverzeichnistabelle und die Exportadresstabelle sind erforderlich, um Symbole als Ordnungszahlen zu exportieren. (Eine Ordnungszahl ist ein Export, auf den direkt über den Index der Exportadresstabelle zugegriffen wird.) Die Name-Zeigertabelle, die Ordnungstabelle und die Exportnamentabelle sind vorhanden, um die Verwendung von Exportnamen zu unterstützen.
| Tabellenname | BESCHREIBUNG |
|---|---|
| Exportieren der Verzeichnistabelle |
Eine Tabelle mit nur einer Zeile (im Gegensatz zum Debugverzeichnis). Diese Tabelle gibt die Speicherorte und Größen der anderen Exporttabellen an. |
| Adresstabelle exportieren |
Ein Array von RVAs exportierter Symbole. Dies sind die tatsächlichen Adressen der exportierten Funktionen und Daten innerhalb des ausführbaren Codes und der Datenabschnitte. Andere Bilddateien können ein Symbol importieren, indem sie einen Index in diese Tabelle (eine Ordnungszahl) oder optional den öffentlichen Namen verwenden, der der Ordnungszahl entspricht, wenn ein öffentlicher Name definiert ist. |
| Namenszeigertabelle |
Ein Array von Zeigern auf die öffentlichen Exportnamen, sortiert in aufsteigender Reihenfolge. |
| Ordinaltabelle |
Ein Array der Ordnungszahlen, die Membern der Namenszeigertabelle entsprechen. Die Entsprechung erfolgt nach Position. daher müssen die Name-Zeigertabelle und die Ordnungstabelle dieselbe Anzahl von Membern aufweisen. Jede Ordnungszahl ist ein Index in der Exportadresstabelle. |
| Exportieren der Namenstabelle |
Eine Reihe von AUF NULL endende ASCII-Zeichenfolgen. Member der Namenszeigertabelle zeigen auf diesen Bereich. Diese Namen sind die öffentlichen Namen, über die die Symbole importiert und exportiert werden. sie sind nicht notwendigerweise mit den privaten Namen identisch, die in der Imagedatei verwendet werden. |
Wenn eine andere Bilddatei ein Symbol anhand des Namens importiert, durchsucht das Win32-Ladeprogramm die Namenszeigertabelle nach einer übereinstimmenden Zeichenfolge. Wenn eine übereinstimmende Zeichenfolge gefunden wird, wird die zugeordnete Ordnungszahl identifiziert, indem das entsprechende Element in der Ordnungstabelle gesucht wird (d. b. das Element der Ordnungstabelle mit demselben Index wie der Zeichenfolgenzeiger in der Namenszeigertabelle). Die resultierende Ordnungszahl ist ein Index in der Exportadresstabelle, der den tatsächlichen Speicherort des gewünschten Symbols angibt. Auf jedes Exportsymbol kann über eine Ordnungszahl zugegriffen werden.
Wenn eine andere Bilddatei ein Symbol nach Ordnungszahl importiert, ist es nicht erforderlich, die Namenszeigertabelle nach einer übereinstimmenden Zeichenfolge zu durchsuchen. Die direkte Verwendung einer Ordnungszahl ist daher effizienter. Ein Exportname ist jedoch einfacher zu merken und erfordert nicht, dass der Benutzer den Tabellenindex für das Symbol kennt.
Exportieren einer Verzeichnistabelle
Die Exportsymbolinformationen beginnen mit der Exportverzeichnistabelle, in der der Rest der Exportsymbolinformationen beschrieben wird. Die Exportverzeichnistabelle enthält Adressinformationen, die zum Auflösen von Importen in die Einstiegspunkte in diesem Image verwendet werden.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Exportieren von Flags |
Reserviert, muss 0 sein. |
| 4 |
4 |
Uhrzeit/Datumsstempel |
Die Uhrzeit und das Datum, an dem die Exportdaten erstellt wurden. |
| 8 |
2 |
Hauptversion |
Die Hauptversionsnummer. Die Haupt- und Nebenversionsnummern können vom Benutzer festgelegt werden. |
| 10 |
2 |
Nebenversion |
Die Nebenversionsnummer. |
| 12 |
4 |
Name RVA |
Die Adresse der ASCII-Zeichenfolge, die den Namen der DLL enthält. Diese Adresse ist relativ zur Imagebasis. |
| 16 |
4 |
Ordnungszahlbasis |
Die Anfangszahl der Ordnungszahl für Exporte in diesem Image. Dieses Feld gibt die Anfangszahl der Ordnungszahl für die Exportadresstabelle an. Sie ist in der Regel auf 1 festgelegt. |
| 20 |
4 |
Adresstabelleneinträge |
Die Anzahl der Einträge in der Exportadresstabelle. |
| 24 |
4 |
Anzahl von Namenszeigern |
Die Anzahl der Einträge in der Namenszeigertabelle. Dies ist auch die Anzahl der Einträge in der Ordnungstabelle. |
| 28 |
4 |
Export Address Table RVA |
Die Adresse der Exportadresstabelle relativ zur Imagebasis. |
| 32 |
4 |
Name Pointer RVA |
Die Adresse der Exportnamenzeigertabelle relativ zur Imagebasis. Die Tabellengröße wird durch das Feld Number of Name Pointers angegeben. |
| 36 |
4 |
Ordinaltabellen-RVA |
Die Adresse der Ordnungstabelle relativ zur Imagebasis. |
Adresstabelle exportieren
Die Tabelle mit den Exportadressen enthält die Adresse der exportierten Einstiegspunkte und exportierten Daten und Absoluten. Eine Ordnungszahl wird als Index in die Exportadresstabelle verwendet.
Jeder Eintrag in der Exportadresstabelle ist ein Feld, das eines von zwei Formaten in der folgenden Tabelle verwendet. Wenn sich die angegebene Adresse nicht innerhalb des Exportabschnitts befindet (wie durch die Adresse und Länge definiert, die im optionalen Header angegeben sind), ist das Feld ein Export-RVA, bei dem es sich um eine tatsächliche Adresse in Code oder Daten handelt. Andernfalls ist das Feld eine Weiterleitungs-RVA, die ein Symbol in einer anderen DLL benennt.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Exportieren von RVA |
Die Adresse des exportierten Symbols, wenn es in den Arbeitsspeicher geladen wird, relativ zur Imagebasis. Beispielsweise die Adresse einer exportierten Funktion. |
| 0 |
4 |
Forwarder RVA |
Der Zeiger auf eine auf NULL beendete ASCII-Zeichenfolge im Exportabschnitt. Diese Zeichenfolge muss innerhalb des Bereichs liegen, der durch den Exporttabellen-Datenverzeichniseintrag angegeben wird. Weitere Informationen finden Sie unter Optional Header Data Directories (Image Only) (Optionale Headerdatenverzeichnisse (nur Image)). Diese Zeichenfolge gibt den DLL-Namen und den Namen des Exports (z. B. "MYDLL.expfunc") oder den DLL-Namen und die Ordnungszahl des Exports (z. B. "MYDLL. # 27"). |
Eine RVA-Forwarder exportiert eine Definition aus einem anderen Image, wodurch sie so ausgesehen wird, als würde sie vom aktuellen Image exportiert. Daher wird das Symbol gleichzeitig importiert und exportiert.
Beispielsweise wird in Kernel32.dll in Windows XP der Export mit dem Namen "HeapAlloc" an die Zeichenfolge "NTDLL. RtlAllocateHeap." Dadurch können Anwendungen die Windows XP-spezifischen Ntdll.dll verwenden, ohne tatsächlich Importverweise darauf zu enthalten. Die Importtabelle der Anwendung bezieht sich nur auf Kernel32.dll. Daher ist die Anwendung nicht spezifisch für Windows XP und kann auf jedem Win32-System ausgeführt werden.
Exportieren der Namenszeigertabelle
Die Exportnamenzeigertabelle ist ein Array von Adressen (RVAs) in der Exportnamentabelle. Die Zeiger sind jeweils 32 Bits und relativ zur Imagebasis. Die Zeiger werden lexikalisch sortiert, um binäre Suchvorgänge zu ermöglichen.
Ein Exportname wird nur definiert, wenn die Exportnamenzeigertabelle einen Zeiger darauf enthält.
Exportieren der Ordinaltabelle
Die Export ordinal-Tabelle ist ein Array von 16-Bit-Indizes ohne Berücksichtigung der Exportadressentabelle. Ordnungszahlen werden durch das Ordinalbasisfeld der Exportverzeichnistabelle voreingenommen. Anders ausgedrückt: Die Ordnungsbasis muss von den Ordnungszahlen subtrahiert werden, um echte Indizes in die Exportadressentabelle zu erhalten.
Die Exportnamenzeigertabelle und die Export ordinaltabelle bilden zwei parallele Arrays, die getrennt sind, um eine natürliche Feldausrichtung zu ermöglichen. Diese beiden Tabellen werden als eine Tabelle verwendet, in der die Spalte Export Name Pointer auf einen öffentlichen (exportierten) Namen verweist und die Spalte Ordinal exportieren die entsprechende Ordnungszahl für diesen öffentlichen Namen angibt. Ein Member der Exportnamenzeigertabelle und ein Member der Export ordinaltabelle werden zugeordnet, indem in ihren jeweiligen Arrays die gleiche Position (Index) verwendet wird.
Wenn also die Exportnamenzeigertabelle durchsucht wird und eine übereinstimmende Zeichenfolge an Position i gefunden wird, ist der Algorithmus zum Suchen der RVA und der verzerrten Ordnungszahl des Symbols:
i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];
rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;
Bei der Suche nach einem Symbol nach (verzerrter) Ordnungszahl ist der Algorithmus zum Suchen der RVA und des Namens des Symbols:
ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);
rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];
Tabelle "Name exportieren"
Die Exportnamentabelle enthält die tatsächlichen Zeichenfolgendaten, auf die von der Exportnamenzeigertabelle verwiesen wurde. Die Zeichenfolgen in dieser Tabelle sind öffentliche Namen, die andere Bilder zum Importieren der Symbole verwenden können. Diese öffentlichen Exportnamen sind nicht unbedingt identisch mit den privaten Symbolnamen, die die Symbole in ihrer eigenen Bilddatei und im Quellcode haben, obwohl dies möglich ist.
Jedes exportierte Symbol verfügt über einen Ordinalwert, bei dem es sich nur um den Index in der Exportadressentabelle handelt. Die Verwendung von Exportnamen ist jedoch optional. Einige, alle oder keine der exportierten Symbole können Exportnamen haben. Bei exportierten Symbolen mit Exportnamen werden die entsprechenden Einträge in der Exportnamenzeigertabelle und der Export ordinaltabelle zusammen verwendet, um jeden Namen einer Ordnungszahl zu zuordnen.
Die Struktur der Exportnamentabelle besteht aus einer Reihe von ASCII-Zeichenfolgen mit NULL-Terminierung variabler Länge.
Der Abschnitt ".idata"
Alle Bilddateien, die Symbole importieren, einschließlich praktisch aller ausführbaren Dateien (EXE), verfügen über einen IDATA-Abschnitt. Es folgt ein typisches Dateilayout für die Importinformationen:
Verzeichnistabelle
NULL-Verzeichniseintrag
DLL1 Import Lookup Table
Null
DLL2 Import Lookup Table
Null
DLL3 Import Lookup Table
Null
Hint-Name Tabelle
Verzeichnistabelle importieren
Die Importinformationen beginnen mit der Importverzeichnistabelle, die den Rest der Importinformationen beschreibt. Die Importverzeichnistabelle enthält Adressinformationen, die verwendet werden, um Fixupverweise auf die Einstiegspunkte in einem DLL-Image aufzulösen. Die Importverzeichnistabelle besteht aus einem Array von Importverzeichniseinträgen, einem Eintrag für jede DLL, auf die das Image verweist. Der letzte Verzeichniseintrag ist leer (mit NULL-Werten gefüllt), was das Ende der Verzeichnistabelle angibt.
Jeder Importverzeichniseintrag hat das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Import Lookup Table RVA (Merkmale) |
Die RVA der Import-Lookuptabelle. Diese Tabelle enthält einen Namen oder eine Ordnungszahl für jeden Import. (Der Name "Characteristics" wird in Winnt.h verwendet, beschreibt dieses Feld jedoch nicht mehr.) |
| 4 |
4 |
Zeit-/Datumsstempel |
Der Stempel, der auf 0 (null) festgelegt ist, bis das Bild gebunden ist. Nachdem das Image gebunden wurde, wird dieses Feld auf den Zeit-/Datenstempel der DLL festgelegt. |
| 8 |
4 |
Forwarder Chain |
Der Index des ersten Forwarderverweises. |
| 12 |
4 |
Name RVA |
Die Adresse einer ASCII-Zeichenfolge, die den Namen der DLL enthält. Diese Adresse ist relativ zur Imagebasis. |
| 16 |
4 |
RVA für Die Adresstabelle importieren (Thunk-Tabelle) |
Das RVA der Importadrentabelle. Der Inhalt dieser Tabelle ist mit dem Inhalt der Importsuchetabelle identisch, bis das Bild gebunden ist. |
Importieren der Nachschlagetabelle
Eine Importsuchetabelle ist ein Array von 32-Bit-Zahlen für PE32 oder ein Array von 64-Bit-Zahlen für PE32+. Jeder Eintrag verwendet das in der folgenden Tabelle beschriebene Bitfeldformat. In diesem Format ist Bit 31 das wichtigste Bit für PE32, und Bit 63 ist das wichtigste Bit für PE32+. Die Auflistung dieser Einträge beschreibt alle Importe aus einer bestimmten DLL. Der letzte Eintrag wird auf null (NULL) festgelegt, um das Ende der Tabelle anzugeben.
| Bit(s) | Size | Bitfeld | BESCHREIBUNG |
|---|---|---|---|
| 31/63 |
1 |
Ordinal-/Namensflag |
Wenn dieses Bit festgelegt ist, importieren Sie nach Ordnungszahl. Andernfalls importieren Sie nach Namen. Bit wird als 0x80000000 für PE32 maskiert, 0x8000000000000000 für PE32+. |
| 15-0 |
16 |
Ordinalzahl |
Eine 16-Bit-Ordnungszahl. Dieses Feld wird nur verwendet, wenn das Bitfeld Ordinal-/Namensflag 1 ist (Import nach Ordnungszahl). Die Bits 30-15 oder 62-15 müssen 0 sein. |
| 30-0 |
31 |
Hinweis-/Namenstabellen-RVA |
Ein 31-Bit-RVA eines Hinweis-/Namenstabelleneintrags. Dieses Feld wird nur verwendet, wenn das Bitfeld Ordinal-/Namensflag 0 (nach Name importieren) ist. Für PE32+ Bits muss 62-31 0 (null) sein. |
Hinweis-/Namenstabelle
Eine Hinweis-/Namenstabelle reicht für den gesamten Importabschnitt aus. Jeder Eintrag in der Hinweis-/Namenstabelle hat das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
2 |
Hinweis |
Ein Index in der Exportnamenzeigertabelle. Zuerst wird versucht, eine Übereinstimmung mit diesem Wert zu erhalten. Wenn ein Fehler auftritt, wird eine binäre Suche für die Exportnamenzeigertabelle der DLL ausgeführt. |
| 2 |
-Variable |
Name |
Eine ASCII-Zeichenfolge, die den zu importierenden Namen enthält. Dies ist die Zeichenfolge, die mit dem öffentlichen Namen in der DLL übereinstimmen muss. Bei dieser Zeichenfolge wird die Kleinschreibung beachtet und mit einem NULL-Byte beendet. |
| * |
0 oder 1 |
Pad |
Ein nach dem folgenden NULL-Byte angezeigtes nach dem folgenden NULL-Byte, falls erforderlich, um den nächsten Eintrag an einer gleichmäßigen Grenze auszurichten. |
Adresstabelle importieren
Die Struktur und der Inhalt der Importadressentabelle sind mit denen der Importsuchetabelle identisch, bis die Datei gebunden ist. Während der Bindung werden die Einträge in der Importadressentabelle mit den 32-Bit-Adressen (für PE32) oder 64-Bit-Adressen (für PE32+) der zu importierenden Symbole überschrieben. Diese Adressen sind die tatsächlichen Speicheradressen der Symbole, obwohl sie technisch gesehen immer noch als "virtuelle Adressen" bezeichnet werden. Das Lader verarbeitet die Bindung in der Regel.
Der PDATA-Abschnitt
Der Abschnitt .pdata enthält ein Array von Funktionstabelleneinträgen, die für die Ausnahmebehandlung verwendet werden. Auf sie wird durch den Ausnahmetabelleneintrag im Imagedatenverzeichnis verwiesen. Die Einträge müssen nach den Funktionsadressen (dem ersten Feld in jeder Struktur) sortiert werden, bevor sie in das endgültige Bild ausgegeben werden. Die Zielplattform bestimmt, welche der drei unten beschriebenen Funktionstabellen-Eingabeformatvarianten verwendet wird.
Für 32-Bit-MIPS-Images haben Funktionstabelleneinträge das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Begin Address |
Die Va der entsprechenden Funktion. |
| 4 |
4 |
Endadresse |
Die Va am Ende der Funktion. |
| 8 |
4 |
Ausnahmehandler |
Der Zeiger auf den auszuführenden Ausnahmehandler. |
| 12 |
4 |
Handlerdaten |
Der Zeiger auf zusätzliche Informationen, die an den Handler übergeben werden sollen. |
| 16 |
4 |
Prolog-Endadresse |
Die Va am Ende des Prologs der Funktion. |
Für die PLATTFORMEN ARM, PowerPC, SH3 und SH4 Windows CE haben Funktionstabelleneinträge das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Begin Address |
Die Va der entsprechenden Funktion. |
| 4 |
8 Bit |
Prologlänge |
Die Anzahl der Anweisungen im Prolog der Funktion. |
| 4 |
22 Bits |
Funktionslänge |
Die Anzahl der Anweisungen in der Funktion. |
| 4 |
1 Bit |
32-Bit-Flag |
Wenn festgelegt, besteht die Funktion aus 32-Bit-Anweisungen. Wenn dies klar ist, besteht die Funktion aus 16-Bit-Anweisungen. |
| 4 |
1 Bit |
Ausnahmeflag |
Wenn festgelegt, ist ein Ausnahmehandler für die Funktion vorhanden. Andernfalls ist kein Ausnahmehandler vorhanden. |
Für x64- und Itanium-Plattformen haben Funktionstabelleneinträge das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Begin Address |
Das RVA der entsprechenden Funktion. |
| 4 |
4 |
Endadresse |
Das RVA am Ende der Funktion. |
| 8 |
4 |
Entladungsinformationen |
Das RVA der Entladungsinformationen. |
Abschnitt ".reloc" (nur Bild)
Die Basisverlagerungstabelle enthält Einträge für alle Basisverlagerungen im Image. Das Feld Basisverlagerungstabelle in den optionalen Headerdatenverzeichnissen gibt die Anzahl von Bytes in der Basisverlagerungstabelle an. Weitere Informationen finden Sie unter Optionale Headerdatenverzeichnisse (nur Image). Die Basisverlagerungstabelle ist in Blöcke unterteilt. Jeder Block stellt die Basisverlagerungen für eine 4K-Seite dar. Jeder Block muss an einer 32-Bit-Grenze beginnen.
Das Lader ist nicht erforderlich, um Basisverlagerungen zu verarbeiten, die vom Linker aufgelöst werden, es sei denn, das Ladeimage kann nicht auf der Imagebasis geladen werden, die im PE-Header angegeben ist.
Basisverlagerungsblock
Jeder Basisverlagerungsblock beginnt mit der folgenden Struktur:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Seiten-RVA |
Die Imagebasis plus die Seiten-RVA wird jedem Offset hinzugefügt, um die Va zu erstellen, auf die die Basisverlagerung angewendet werden muss. |
| 4 |
4 |
Blockgröße |
Die Gesamtzahl der Bytes im Basisverlagerungsblock, einschließlich der Felder Seiten-RVA und Blockgröße und der folgenden Felder vom Typ/Offset. |
Auf das Feld Blockgröße folgt dann eine beliebige Anzahl von Typ- oder Offsetfeldeinträgen. Jeder Eintrag ist ein WORD -Eintrag (2 Bytes) und hat die folgende Struktur:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 Bits |
type |
Wird in den hohen 4 Bits des WORD gespeichert, ein Wert, der den Typ der zu verwendenden Basisverlagerung angibt. Weitere Informationen finden Sie unter Basisverlagerungstypen. |
| 0 |
12 Bits |
Offset |
Wird in den verbleibenden 12 Bits von WORD gespeichert, ein Offset von der Startadresse, die im Feld Seiten-RVA für den Block angegeben wurde. Dieser Offset gibt an, wo die Basisverlagerung angewendet werden soll. |
Um eine Basisverlagerung anzuwenden, wird die Differenz zwischen der bevorzugten Basisadresse und der Basis berechnet, in der das Image tatsächlich geladen wird. Wenn das Image an seiner bevorzugten Basis geladen wird, beträgt die Differenz 0 (null), und daher müssen die Basisverlagerungen nicht angewendet werden.
Basisverlagerungstypen
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMAGE _ REL _ BASED _ ABSOLUTE |
0 |
Die Basisverlagerung wird übersprungen. Dieser Typ kann verwendet werden, um einen Block zu aufpaddnen. |
| IMAGE _ REL _ BASED _ HIGH |
1 |
Die Basisverlagerung fügt dem 16-Bit-Feld am Offset die hohen 16 Bits der Differenz hinzu. Das 16-Bit-Feld stellt den hohen Wert eines 32-Bit-Worts dar. |
| IMAGE _ REL _ BASED _ LOW |
2 |
Die Basisverlagerung fügt dem 16-Bit-Feld am Offset die unteren 16 Bits der Differenz hinzu. Das 16-Bit-Feld stellt die untere Hälfte eines 32-Bit-Worts dar. |
| IMAGE _ _ REL-BASIERTES _ HIGHLOW |
3 |
Die Basisverlagerung wendet alle 32 Bits der Differenz auf das 32-Bit-Feld am Offset an. |
| IMAGE _ _ REL-BASIERTES _ HIGHADJ |
4 |
Die Basisverlagerung fügt dem 16-Bit-Feld am Offset die hohen 16 Bits der Differenz hinzu. Das 16-Bit-Feld stellt den hohen Wert eines 32-Bit-Worts dar. Die unteren 16 Bits des 32-Bit-Werts werden im 16-Bit-Wort gespeichert, das dieser Basisverlagerung folgt. Dies bedeutet, dass diese Basisverlagerung zwei Slots belegt. |
| IMAGE _ _ REL-BASIERTE _ MIPS _ JMPADDR |
5 |
Die Interpretation der Verschiebung hängt vom Computertyp ab. Wenn der Computertyp MIPS ist, gilt die Basisverlagerung für eine MIPS-Sprunganweisung. |
| IMAGE _ _ REL-BASIERTES _ ARM _ MOV32 |
5 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp ARM oder Thumb ist. Die Basisverlagerung wendet die 32-Bit-Adresse eines Symbols auf ein aufeinander folgendes MOVW/MOVT-Anweisungspaar an. |
| IMAGE _ _ REL-BASIERTES _ RISCV _ HIGH20 |
5 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp RISC-V ist. Die Basisverlagerung gilt für die hohen 20 Bits einer absoluten 32-Bit-Adresse. |
| 6 |
Reserviert, muss 0 (null) sein. |
|
| IMAGE _ _ REL-BASIERTER _ THUMB _ MOV32 |
7 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp Thumb ist. Die Basisverlagerung wendet die 32-Bit-Adresse eines Symbols auf ein aufeinander folgendes MOVW/MOVT-Anweisungspaar an. |
| IMAGE _ _ REL-BASIERTER _ RISCV _ LOW12I |
7 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp RISC-V ist. Die Basisverlagerung gilt für die unteren 12 Bits einer absoluten 32-Bit-Adresse, die im RISC-V-I-Typanweisungsformat gebildet wird. |
| IMAGE _ _ REL-BASIERTES _ RISCV _ LOW12S |
8 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp RISC-V ist. Die Basisverlagerung gilt für die unteren 12 Bits einer absoluten 32-Bit-Adresse, die im RISC-V-S-Typanweisungsformat gebildet wird. |
| IMAGE _ REL _ BASED _ LOONGARCH32 _ MARK _ LA |
8 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp LoongArch 32-Bit ist. Die Basisverlagerung gilt für eine absolute 32-Bit-Adresse, die in zwei aufeinander folgenden Anweisungen gebildet wird. |
| IMAGE _ _ REL-BASIERT _ LOONGARCH64 _ MARK _ LA |
8 |
Diese Verschiebung ist nur sinnvoll, wenn der Computertyp LoongArch 64-Bit ist. Die Basisverlagerung gilt für eine absolute 64-Bit-Adresse, die in vier aufeinander folgenden Anweisungen gebildet wird. |
| IMAGE _ _ REL-BASIERTE _ MIPS _ JMPADDR16 |
9 |
Die Verschiebung ist nur sinnvoll, wenn der Computertyp MIPS ist. Die Basisverlagerung gilt für eine MIPS16-Sprunganweisung. |
| IMAGE _ _ REL-BASIERTES _ DIR64 |
10 |
Die Basisverlagerung wendet den Unterschied auf das 64-Bit-Feld am Offset an. |
Der TLS-Abschnitt
Der Abschnitt .tls bietet direkte PE- und COFF-Unterstützung für statischen lokalen Threadspeicher (STATIC Thread Local Storage, TLS). TLS ist eine spezielle Speicherklasse, die Windows unterstützt, bei der ein Datenobjekt keine automatische Variable (Stapelvariable) ist, aber lokal für jeden einzelnen Thread ist, der den Code ausgeführt. Daher kann jeder Thread einen anderen Wert für eine Variable verwalten, die mitHILFE von TLS deklariert wurde.
Beachten Sie, dass jede Menge von TLS-Daten mithilfe der API-Aufrufe TlsAlloc, TlsFree, TlsSetValue und TlsGetValue unterstützt werden kann. Die PE- oder COFF-Implementierung ist ein alternativer Ansatz zur Verwendung der API und hat den Vorteil, dass sie aus Sicht des Programmierers auf hoher Ebene einfacher ist. Mit dieser Implementierung können TLS-Daten ähnlich wie normale statische Variablen in einem Programm definiert und initialisiert werden. Beispielsweise kann in Visual C++ eine statische TLS-Variable wie folgt definiert werden, ohne die Windows-API zu verwenden:
__declspec (thread) int tlsFlag = 1;
Zur Unterstützung dieses Programmierkonstrukts gibt der Abschnitt PE und COFF .tls die folgenden Informationen an: Initialisierungsdaten, Rückrufroutinen für die Initialisierung und Beendigung pro Thread und den TLS-Index, die in der folgenden Diskussion erläutert werden.
Hinweis
Statisch deklarierte TLS-Datenobjekte können nur in statisch geladenen Bilddateien verwendet werden. Dadurch ist es unzuverlässig, statische TLS-Daten in einer DLL zu verwenden, es sei denn, Sie wissen, dass die DLL oder etwas, das statisch mit ihr verknüpft ist, nie dynamisch mit der LoadLibrary-API-Funktion geladen wird.
Ausführbarer Code greifen mit den folgenden Schritten auf ein statisches TLS-Datenobjekt zu:
Zur Linkzeit legt der Linker das Feld Adresse des Indexes des TLS-Verzeichnisses fest. Dieses Feld zeigt auf einen Speicherort, an dem das Programm den TLS-Index erwartet.
Die Microsoft-Laufzeitbibliothek erleichtert diesen Prozess, indem sie ein Speicherimage des TLS-Verzeichnisses definiert und ihm den speziellen Namen _ _ "tls _ used" (Intel x86-Plattformen) oder _ "tls used" (andere Plattformen) _ gibt. Der Linker sucht nach diesem Speicherimage und verwendet die Daten dort, um das TLS-Verzeichnis zu erstellen. Andere Compiler, die TLS unterstützen und mit dem Microsoft-Linker arbeiten, müssen dieselbe Technik verwenden.
Wenn ein Thread erstellt wird, kommuniziert das Lader die Adresse des TLS-Arrays des Threads, indem die Adresse des Threadumgebungsblocks (TEB) im FS-Register platziert wird. Ein Zeiger auf das TLS-Array befindet sich am Offset 0x2C anfang von TEB. Dieses Verhalten ist intel x86-spezifisch.
Das Lader weist den Wert des TLS-Indexes der Stelle zu, die durch das Feld Adresse des Indexes angegeben wurde.
Der ausführbare Code ruft den TLS-Index und auch den Speicherort des TLS-Arrays ab.
Der Code verwendet den TLS-Index und die TLS-Arrayposition (multipliziert den Index mit 4 und verwendet ihn als Offset zum Array), um die Adresse des TLS-Datenbereichs für das angegebene Programm und Modul zu erhalten. Jeder Thread verfügt über einen eigenen TLS-Datenbereich, aber dies ist für das Programm transparent, das nicht wissen muss, wie Daten einzelnen Threads zugeordnet werden.
Auf ein einzelnes TLS-Datenobjekt wird als fester Offset im TLS-Datenbereich zugegriffen.
Das TLS-Array ist ein Array von Adressen, die das System für jeden Thread verwaltet. Jede Adresse in diesem Array gibt den Speicherort der TLS-Daten für ein bestimmtes Modul (EXE oder DLL) innerhalb des Programms an. Der TLS-Index gibt an, welcher Member des Arrays verwendet werden soll. Der Index ist eine Zahl (nur für das System aussagekräftig), die das Modul identifiziert.
Das TLS-Verzeichnis
Das TLS-Verzeichnis hat das folgende Format:
| Offset (PE32/ PE32+) | Größe (PE32/ PE32+) | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4/8 |
Raw Data Start VA |
Die Startadresse der TLS-Vorlage. Die Vorlage ist ein Datenblock, der zum Initialisieren von TLS-Daten verwendet wird. Das System kopiert alle diese Daten jedes Mal, wenn ein Thread erstellt wird, sodass er nicht beschädigt werden darf. Beachten Sie, dass diese Adresse kein RVA ist. Es handelt sich um eine Adresse, für die es eine Basisverlagerung im Abschnitt .reloc geben sollte. |
| 4/8 |
4/8 |
Rohdaten-End-VA |
Die Adresse des letzten Byte des TLS, mit Ausnahme der Nullfüllung. Wie beim Feld Raw Data Start VA ist dies eine Va, keine RVA. |
| 8/16 |
4/8 |
Adresse des Indexes |
Der Speicherort, an dem der TLS-Index empfangen werden soll, der vom Lader zugewiesen wird. Dieser Speicherort befindet sich in einem normalen Datenabschnitt, sodass ihm ein symbolischer Name gegeben werden kann, auf den das Programm zugriff kann. |
| 12/24 |
4/8 |
Adresse von Rückrufen |
Der Zeiger auf ein Array von TLS-Rückruffunktionen. Das Array wird mit NULL beendet. Wenn also keine Rückruffunktion unterstützt wird, zeigt dieses Feld auf 4 Bytes, die auf 0 (null) festgelegt sind. Informationen zum Prototyp für diese Funktionen finden Sie unter TLS-Rückruffunktionen. |
| 16/32 |
4 |
Größe der Füllgröße 0 (null) |
Die Größe der Vorlage in Bytes, die über die initialisierten Daten hinaus geht, die durch die Felder Raw Data Start VA und Raw Data End VA getrennt sind. Die Gesamtgröße der Vorlage sollte mit der Gesamtgröße der TLS-Daten in der Bilddatei identisch sein. Die Füllmenge 0 (null) ist die Datenmenge, die nach den initialisierten Daten ungleich 0 (null) liegt. |
| 20/36 |
4 |
Merkmale |
Die vier Bits [ 23:20 ] beschreiben Ausrichtungsinformationen. Mögliche Werte sind diejenigen, die als IMAGE SCN ALIGN definiert sind, die auch verwendet werden, um die Ausrichtung _ _ des _ * Abschnitts in Objektdateien zu beschreiben. Die anderen 28 Bits sind für die zukünftige Verwendung reserviert. |
TLS-Rückruffunktionen
Das Programm kann eine oder mehrere TLS-Rückruffunktionen bereitstellen, um zusätzliche Initialisierung und Beendigung für TLS-Datenobjekte zu unterstützen. Eine typische Verwendung für eine solche Rückruffunktion wäre das Aufrufen von Konstruktoren und Destruktoren für Objekte.
Obwohl es in der Regel nicht mehr als eine Rückruffunktion gibt, wird ein Rückruf als Array implementiert, damit bei Wunsch zusätzliche Rückruffunktionen hinzugefügt werden können. Wenn es mehrere Rückruffunktionen gibt, wird jede Funktion in der Reihenfolge aufgerufen, in der ihre Adresse im Array angezeigt wird. Ein NULL-Zeiger beendet das Array. Es ist völlig gültig, eine leere Liste zu haben (kein Rückruf wird unterstützt). In diesem Fall verfügt das Rückrufarray über genau einen Member– einen NULL-Zeiger.
Der Prototyp für eine Rückruffunktion (auf den durch einen Zeiger vom Typ PIMAGE TLS CALLBACK verwiesen wird) verfügt über die gleichen Parameter wie eine _ _ DLL-Einstiegspunktfunktion:
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
Der Reserved-Parameter sollte auf 0 (null) festgelegt werden. Der Reason-Parameter kann die folgenden Werte verwenden:
| Einstellung | Wert | BESCHREIBUNG |
|---|---|---|
| ANFÜGEN _ DES _ DLL-PROZESSES |
1 |
Ein neuer Prozess wurde gestartet, einschließlich des ersten Threads. |
| DLL _ THREAD _ ATTACH |
2 |
Ein neuer Thread wurde erstellt. Diese Benachrichtigung wird nur für den ersten Thread gesendet. |
| _ _ DLL-THREADTRENNEN |
3 |
Ein Thread wird beendet. Diese Benachrichtigung wird nur für den ersten Thread gesendet. |
| _ _ DLL-PROZESSTRENNVORGANG |
0 |
Ein Prozess wird beendet, einschließlich des ursprünglichen Threads. |
Die Load-Konfigurationsstruktur (nur Image)
Die Auslastungskonfigurationsstruktur (IMAGE LOAD CONFIG DIRECTORY) wurde früher in sehr begrenzten Fällen im Windows NT-Betriebssystem selbst verwendet, um verschiedene Features zu beschreiben, die zu schwierig oder zu groß sind, um sie im Dateiheader oder optionalen Header des Images zu _ _ _ beschreiben. Aktuelle Versionen des Microsoft-Linkers und Windows XP und neuere Versionen von Windows verwenden eine neue Version dieser Struktur für x86-basierte 32-Bit-Systeme, die reservierte SEH-Technologie enthalten. Dies enthält eine Liste der sicheren strukturierten Ausnahmehandler, die das Betriebssystem während der Ausnahmeaussendung verwendet. Wenn sich die Handleradresse im VA-Bereich eines Bilds befindet und als reservierte SEH-orientierte Adresse gekennzeichnet ist (d.h. IMAGE _ DLLCHARACTERISTICS NO SEH ist im _ Feld DllCharacteristics des optionalen Headers eindeutig, wie weiter oben beschrieben), muss sich der Handler in der Liste der bekannten sicheren Handler für dieses Image _ befinden. Andernfalls beendet das Betriebssystem die Anwendung. Dies hilft, den Exploit "x86 exception handler hijacking" zu verhindern, der in der Vergangenheit verwendet wurde, um die Kontrolle über das Betriebssystem zu übernehmen.
Der Microsoft-Linker stellt automatisch eine Standardkonfigurationsstruktur für die Auslastung zur Verfügung, die die reservierten SEH-Daten enthält. Wenn der Benutzercode bereits eine Auslastungskonfigurationsstruktur enthält, muss er die neuen reservierten SEH-Felder enthalten. Andernfalls kann der Linker die reservierten SEH-Daten nicht enthalten, und das Bild ist nicht als mit reservierten SEH markiert.
Laden des Konfigurationsverzeichnisses
Der Datenverzeichniseintrag für eine vorab reservierte SEH-Ladekonfigurationsstruktur muss eine bestimmte Größe der Auslastungskonfigurationsstruktur angeben, da das Betriebssystemlader immer einen bestimmten Wert erwartet. In dieser Hinsicht ist die Größe eigentlich nur eine Versionsprüfung. Zur Kompatibilität mit Windows XP und früheren Versionen von Windows muss die Größe für x86-Images 64 sein.
Load Configuration Layout
Die Auslastungskonfigurationsstruktur verfügt über das folgende Layout für 32-Bit- und 64-Bit-PE-Dateien:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Merkmale |
Flags, die Attribute der Datei angeben, die derzeit nicht verwendet werden. |
| 4 |
4 |
TimeDateStamp |
Datums- und Zeitstempelwert. Der Wert wird gemäß der Systemuhr in der Anzahl der Sekunden dargestellt, die seit Mitternacht (00:00:00) am 1. Januar 1970 verstrichen sind. Der Zeitstempel kann mithilfe der CRT-Zeitfunktion (C Runtime) gedruckt werden. |
| 8 |
2 |
MajorVersion |
Hauptversionsnummer. |
| 10 |
2 |
MinorVersion |
Nebenversionsnummer. |
| 12 |
4 |
GlobalFlagsClear |
Das globale Laderflag, das für diesen Prozess zu löschen ist, wenn das Lader den Prozess startet. |
| 16 |
4 |
GlobalFlagsSet |
Das globale Laderflag, das für diesen Prozess festgelegt werden soll, wenn das Lader den Prozess startet. |
| 20 |
4 |
CriticalSectionDefaultTimeout |
Der Standardzeitüberschreitungswert, der für die kritischen Abschnitte dieses Prozesses verwendet werden soll, die abgebrochen werden. |
| 24 |
4/8 |
DeCommitFreeBlockThreshold |
Arbeitsspeicher, der frei werden muss, bevor er an das System zurückgegeben wird , in Bytes. |
| 28/32 |
4/8 |
DeCommitTotalFreeThreshold |
Gesamtmenge des freien Arbeitsspeichers in Bytes. |
| 32/40 |
4/8 |
LockPrefixTable |
[Nur x86 Die Va einer Liste von Adressen, bei denen das LOCK-Präfix verwendet wird, sodass sie auf Computern mit einem Prozessor durch ] NOP ersetzt werden können. |
| 36/48 |
4/8 |
MaximumAllocationSize |
Maximale Zuordnungsgröße in Bytes. |
| 40/56 |
4/8 |
VirtualMemoryThreshold |
Maximale Größe des virtuellen Arbeitsspeichers in Bytes. |
| 44/64 |
4/8 |
ProcessAffinityMask |
Das Festlegen dieses Felds auf einen Wert, der nicht 0 (null) ist, entspricht dem Aufrufen von SetProcessAffinityMask mit diesem Wert während des Prozessstarts (nur .exe). |
| 48/72 |
4 |
ProcessHeapFlags |
Verarbeiten Sie Heapflags, die dem ersten Argument der HeapCreate-Funktion entsprechen. Diese Flags gelten für den Prozessheap, der während des Prozessstarts erstellt wird. |
| 52/76 |
2 |
CSDVersion |
Der Service Pack-Versionsbezeichner. |
| 54/78 |
2 |
Reserviert |
Muss Null sein. |
| 56/80 |
4/8 |
EditList |
Für die Verwendung durch das System reserviert. |
| 60/88 |
4/8 |
SecurityCookie |
Ein Zeiger auf ein Cookie, das von Visual C++- oder GS-Implementierung verwendet wird. |
| 64/96 |
4/8 |
SEHandlerTable |
[x86 nur ] Die VA der sortierten Tabelle der RVAs jedes gültigen, eindeutigen SE Handlers im Bild. |
| 68/104 |
4/8 |
SEHandlerCount |
[Nur x86 ] Die Anzahl der eindeutigen Handler in der Tabelle. |
| 72/112 |
4/8 |
GuardCFCheckFunctionPointer |
Die VA, in der der Check-Function-Zeiger Control Flow Guard gespeichert wird. |
| 76/120 |
4/8 |
GuardCFDispatchFunctionPointer |
Die VA, in der der Steuerungs-Flow Guard-Dispatchfunktionszeiger gespeichert wird. |
| 80/128 |
4/8 |
GuardCFFunctionTable |
Die VA der sortierten Tabelle der RVAs jeder Control Flow Guard-Funktion im Bild. |
| 84/136 |
4/8 |
GuardCFFunctionCount |
Die Anzahl eindeutiger RVAs in der obigen Tabelle. |
| 88/144 |
4 |
GuardFlags |
Steuern sie Flow Guard-bezogene Flags. |
| 92/148 |
12 |
CodeIntegrity |
Codeintegritätsinformationen. |
| 104/160 |
4/8 |
GuardAddressTakenIatEntryTable |
Die VA, in der die IAT-Tabelle Control Flow Guard-Adresse gespeichert wird. |
| 108/168 |
4/8 |
GuardAddressTakenIatEntryCount |
Die Anzahl eindeutiger RVAs in der obigen Tabelle. |
| 112/176 |
4/8 |
GuardLongJumpTargetTable |
Die VA, in der die Long Jump-Zieltabelle Control Flow Guard gespeichert wird. |
| 116/184 |
4/8 |
GuardLongJumpTargetCount |
Die Anzahl eindeutiger RVAs in der obigen Tabelle. |
Das Feld GuardFlags enthält eine Kombination aus mindestens einem der folgenden Flags und Unterfelder:
Das Modul führt Ablaufsteuerungsintegritätsprüfungen mithilfe der vom System bereitgestellten Unterstützung durch.
#define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100Das Modul führt Ablaufsteuerungs- und Schreibintegritätsprüfungen durch.
#define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200Das Modul enthält gültige Ablaufsteuerungszielmetadaten.
#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400Das Modul verwendet nicht das /GS-Sicherheitscookie.
#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800Das Modul unterstützt IAT für schreibgeschütztes verzögertes Laden.
#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000Verzögertes Laden der Importtabelle im eigenen DIDAT-Abschnitt (ohne weitere Informationen), der frei erneut geschützt werden kann.
#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000Das Modul enthält unterdrückte Exportinformationen. Dies leitet auch ab, dass die IAT-Adresstabelle auch in der Ladekonfiguration vorhanden ist.
#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000Das Modul ermöglicht die Unterdrückung von Exporten.
#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000Das Modul enthält Longjmp-Zielinformationen.
#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000Maske für das Unterfeld, das den Schritt der Einträge in der Control Flow Guard-Funktionstabelle enthält (d. b. die zusätzliche Anzahl von Bytes pro Tabelleneintrag).
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000
Darüber hinaus definiert der Windows SDK-Header winnt.h dieses Makro für die Menge der Bits, um den GuardFlags-Wert nach rechts zu verschieben, um den Schritt der Control Flow Guard-Funktionstabelle zu rechtfertigen:
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28
Abschnitt ".rsrc"
Ressourcen werden durch eine binär sortierte Struktur mit mehreren Ebenen indiziert. Der allgemeine Entwurf kann 2 * * 31 Ebenen umfassen. Laut Konvention verwendet Windows jedoch drei Ebenen:
- type
Name
Sprache
Eine Reihe von Ressourcenverzeichnistabellen verknüpft alle Ebenen wie folgt: Auf jede Verzeichnistabelle folgt eine Reihe von Verzeichniseinträgen, die den Namen oder Bezeichner (ID) für diese Ebene (Typ, Name oder Sprachebene) und eine Adresse einer Datenbeschreibung oder einer anderen Verzeichnistabelle enthalten. Wenn die Adresse auf eine Datenbeschreibung verweist, handelt es sich bei den Daten um ein Blatt in der Struktur. Wenn die Adresse auf eine andere Verzeichnistabelle verweist, listet diese Tabelle Verzeichniseinträge auf der nächsten Ebene nach unten auf.
Typ-, Namens- und Sprach-IDs eines Blatts werden durch den Pfad bestimmt, der durch Verzeichnistabellen geleitet wird, um das Blatt zu erreichen. Die erste Tabelle bestimmt die Typ-ID, die zweite Tabelle (auf die durch den Verzeichniseintrag in der ersten Tabelle verwiesen wird) bestimmt die Namens-ID, und die dritte Tabelle bestimmt die Sprach-ID.
Die allgemeine Struktur des Abschnitts .rsrc lautet:
| Daten | BESCHREIBUNG |
|---|---|
| Ressourcenverzeichnistabellen (und Ressourcenverzeichniseinträge) |
Eine Reihe von Tabellen, eine für jede Gruppe von Knoten in der Struktur. Alle Knoten der obersten Ebene (Typ) sind in der ersten Tabelle aufgeführt. Einträge in dieser Tabelle zeigen auf Tabellen der zweiten Ebene. Jede Struktur der zweiten Ebene hat die gleiche Typ-ID, aber unterschiedliche Namens-IDs. Strukturen der dritten Ebene verfügen über die gleichen Typ- und Namens-IDs, aber unterschiedliche Sprach-IDs. Auf jede einzelne Tabelle folgen unmittelbar Verzeichniseinträge, in denen jeder Eintrag über einen Namen oder numerischen Bezeichner und einen Zeiger auf eine Datenbeschreibung oder eine Tabelle auf der nächstunteren Ebene verfügt. |
| Ressourcenverzeichniszeichenfolgen |
Zwei-Byte-ausgerichtete Unicode-Zeichenfolgen, die als Zeichenfolgendaten dienen, auf die verzeichniseinträge verweisen. |
| Beschreibung der Ressourcendaten |
Ein Array von Datensätzen, auf die von Tabellen verwiesen wird, die die tatsächliche Größe und den Tatsächlichen Speicherort der Ressourcendaten beschreiben. Diese Datensätze sind die Blätter in der Ressourcenbeschreibungsstruktur. |
| Ressourcendaten |
Rohdaten des Ressourcenabschnitts. Die Größen- und Standortinformationen im Feld Ressourcendatenbeschreibungen begrenzen die einzelnen Regionen der Ressourcendaten. |
Ressourcenverzeichnistabelle
Jede Ressourcenverzeichnistabelle hat das folgende Format. Diese Datenstruktur sollte als Überschrift einer Tabelle betrachtet werden, da die Tabelle tatsächlich aus Verzeichniseinträgen (beschrieben in Abschnitt 6.9.2, "Ressourcenverzeichniseinträge") und dieser Struktur besteht:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Merkmale |
Ressourcenflags. Dieses Feld ist für eine spätere Verwendung vorgesehen. Sie ist derzeit auf 0 (null) festgelegt. |
| 4 |
4 |
Uhrzeit/Datumsstempel |
Der Zeitpunkt, zu dem die Ressourcendaten vom Ressourcencompiler erstellt wurden. |
| 8 |
2 |
Hauptversion |
Die vom Benutzer festgelegte Hauptversionsnummer. |
| 10 |
2 |
Nebenversion |
Die vom Benutzer festgelegte Nebenversionsnummer. |
| 12 |
2 |
Anzahl von Namenseinträgen |
Die Anzahl von Verzeichniseinträgen unmittelbar nach der Tabelle, die Zeichenfolgen verwenden, um Einträge vom Typ, Namen oder der Sprache zu identifizieren (abhängig von der Ebene der Tabelle). |
| 14 |
2 |
Anzahl von ID-Einträgen |
Die Anzahl der Verzeichniseinträge unmittelbar nach den Namenseinträgen, die numerische IDs für Type-, Name- oder Language-Einträge verwenden. |
Ressourcenverzeichniseinträge
Die Verzeichniseinträge bilden die Zeilen einer Tabelle. Jeder Ressourcenverzeichniseintrag hat das folgende Format. Ob der Eintrag ein Name- oder ID-Eintrag ist, wird durch die Ressourcenverzeichnistabelle angegeben, die angibt, wie viele Name- und ID-Einträge darauf folgen (denken Sie daran, dass alle Namenseinträge allen ID-Einträgen für die Tabelle vorangestellt sind). Alle Einträge für die Tabelle werden in aufsteigender Reihenfolge sortiert: die Name-Einträge nach Zeichenfolge mit Empfindlichkeit der Groß-/Kleinschreibung und die ID-Einträge nach numerischem Wert. Offsets sind relativ zur Adresse im _ IMAGE DIRECTORY ENTRY RESOURCE _ _ DataDirectory. Weitere Informationen finden Sie unter Peering inside the PE: A Tour of the Win32 Portable Executable File Format (Peering innerhalb des PE: Überblick über das Win32 Portable Executable File Format).
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Namensoffset |
Der Offset einer Zeichenfolge, die abhängig von der Tabellenebene den Eintrag Typ, Name oder Sprach-ID angibt. |
| 0 |
4 |
Ganzzahlige ID |
Eine 32-Bit-Ganzzahl, die den Eintrag Typ, Name oder Sprach-ID identifiziert. |
| 4 |
4 |
Dateneintragsoffset |
High Bit 0. Adresse eines Ressourcendateneintrags (Blatt). |
| 4 |
4 |
Unterverzeichnisoffset |
High Bit 1. Die unteren 31 Bits sind die Adresse einer anderen Ressourcenverzeichnistabelle (die nächste Ebene nach unten). |
Ressourcenverzeichniszeichenfolge
Der Zeichenfolgenbereich des Ressourcenverzeichnisses besteht aus Unicode-Zeichenfolgen, die wortbündig ausgerichtet sind. Diese Zeichenfolgen werden nach dem letzten Ressourcenverzeichniseintrag und vor dem ersten Ressourcendateneintrag zusammen gespeichert. Dadurch werden die Auswirkungen dieser Zeichenfolgen variabler Länge auf die Ausrichtung der Verzeichniseinträge fester Größe minimiert. Jede Ressourcenverzeichniszeichenfolge hat das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
2 |
Länge |
Die Größe der Zeichenfolge ohne Längenfeld selbst. |
| 2 |
-Variable |
Unicode-Zeichenfolge |
Die Unicode-Zeichenfolgendaten variabler Länge, wortbündig ausgerichtet. |
Ressourcendateneintrag
Jeder Ressourcendateneintrag beschreibt eine tatsächliche Einheit von Rohdaten im Bereich Ressourcendaten. Ein Ressourcendateneintrag hat das folgende Format:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Data RVA |
Die Adresse einer Einheit von Ressourcendaten im Bereich Ressourcendaten. |
| 4 |
4 |
Size |
Die Größe der Ressourcendaten in Bytes, auf die das Daten-RVA-Feld verweist. |
| 8 |
4 |
codepage |
Die Codepage, die zum Decodieren von Codepunktwerten in den Ressourcendaten verwendet wird. In der Regel ist die Codepage die Unicode-Codepage. |
| 12 |
4 |
Reserviert, muss 0 sein. |
Cormeta-Abschnitt (nur Objekt)
CLR-Metadaten werden in diesem Abschnitt gespeichert. Es wird verwendet, um anzugeben, dass die Objektdatei verwalteten Code enthält. Das Format der Metadaten ist nicht dokumentiert, kann aber zur Verarbeitung von Metadaten an die CLR-Schnittstellen übergeben werden.
Der Abschnitt ".sxdata"
Die gültigen Ausnahmehandler eines Objekts werden im SXDATA-Abschnitt dieses Objekts aufgeführt. Der Abschnitt ist als IMAGE _ SCN _ LNK _ INFO gekennzeichnet. Sie enthält den COFF-Symbolindex jedes gültigen Handlers mit 4 Bytes pro Index.
Darüber hinaus markiert der Compiler ein COFF-Objekt als registrierten SEH, indem er das absolute Symbol " " mit dem LSB des Wertfelds aus gibt, das auf @feat.00 1 festgelegt ist. Ein COFF-Objekt ohne registrierte SEH-Handler hätte das Symbol @feat.00 " " , aber keinen SXDATA-Abschnitt.
Archivdateiformat (Bibliothek)
- Archivdateisignatur
- Archivieren von Memberheadern
- Erstes Linkermitglied
- Zweites Linkermitglied
- Longnames-Member
Das COFF-Archivformat stellt einen Standardmechanismus zum Speichern von Sammlungen von Objektdateien dar. Diese Sammlungen werden in der Programmierdokumentation häufig als Bibliotheken bezeichnet.
Die ersten 8 Bytes eines Archivs bestehen aus der Dateisignatur. Der Rest des Archivs besteht wie folgt aus einer Reihe von Archivmitgliedern:
Das erste und das zweite Member sind "Linker-Member". Jeder dieser Member hat ein eigenes Format, wie im Abschnitt Import Name Type (Importnamenstyp) beschrieben. In der Regel platziert ein Linker Informationen in diese Archivmitglieder. Die Linkermitglieder enthalten das Verzeichnis des Archivs.
Das dritte Mitglied ist das "longnames"-Mitglied. Dieser optionale Member besteht aus einer Reihe von ASCII-Zeichenfolgen mit NULL-Terminierung, bei denen jede Zeichenfolge der Name eines anderen Archivmitglieds ist.
Der Rest des Archivs besteht aus Standard-Membern (Objektdatei). Jeder dieser Member enthält den Inhalt einer Objektdatei in seiner Gesamtheit.
Jedem Member wird ein Archivmitgliedsheader vorangehende. Die folgende Liste zeigt die allgemeine Struktur eines Archivs:
Signatur :"! < arch > \ n"
Header
- 1. Linkermitglied
Header
- 2. Linkermitglied
Header
- Longnames-Member
Header
- Inhalt der OBJ-Datei 1
(COFF-Format)
Header
- Inhalt der OBJ-Datei 2
(COFF-Format)
Archivdateisignatur
Die Archivdateisignatur identifiziert den Dateityp. Jedes Hilfsprogramm (z. B. ein Linker), das eine Archivdatei als Eingabe verwendet, kann den Dateityp überprüfen, indem es diese Signatur liest. Die Signatur besteht aus den folgenden ASCII-Zeichen, in denen jedes zeichen unten wörtlich dargestellt wird, mit Ausnahme des Zeichens newline ( \ n):
!<arch>\n
Archivieren von Memberheadern
Jedem Member (Linker, Longnames oder Objektdatei-Member) wird ein Header vorangehende. Ein Archiv-Memberheader hat das folgende Format, in dem jedes Feld eine ASCII-Textzeichenfolge ist, die rechtsbiert und mit Leerzeichen bis zum Ende des Felds aufschlossen ist. In keinem dieser Felder ist ein beendendes NULL-Zeichen enthalten.
Jeder Memberheader beginnt bei der ersten gleichmäßigen Adresse nach dem Ende des vorherigen Archivmitglieds.
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
16 |
Name |
Der Name des Archivmitglieds, an den ein Schrägstrich (/) angefügt wird, um den Namen zu beenden. Wenn das erste Zeichen ein Schrägstrich ist, hat der Name eine besondere Interpretation, wie in der folgenden Tabelle beschrieben. |
| 16 |
12 |
Date |
Datum und Uhrzeit der Erstellung des Archivmitglieds: Dies ist die ASCII-Dezimaldarstellung der Anzahl von Sekunden seit dem 1.1.1970 UCT. |
| 28 |
6 |
Benutzer-ID |
Eine ASCII-Dezimaldarstellung der Benutzer-ID. Dieses Feld enthält keinen aussagekräftigen Wert auf Windows Plattformen, da Microsoft-Tools alle Leerstellen ausgeben. |
| 34 |
6 |
Gruppen-ID |
Eine ASCII-Dezimaldarstellung der Gruppen-ID. Dieses Feld enthält keinen aussagekräftigen Wert auf Windows Plattformen, da Microsoft-Tools alle Leerstellen ausgeben. |
| 40 |
8 |
Mode |
Eine ASCII-Oktaldarstellung des Dateimodus des Mitglieds. Dies ist der ST _ MODE-Wert aus der C-Laufzeitfunktion _ wstat. |
| 48 |
10 |
Size |
Eine ASCII-Dezimaldarstellung der Gesamtgröße des Archivmitglieds, ohne die Größe des Headers. |
| 58 |
2 |
Ende des Headers |
Die beiden Bytes in der C-Zeichenfolge " 2 \ n" (0x60 0x0A). |
Das Feld Name hat eines der in der folgenden Tabelle gezeigten Formate. Wie bereits erwähnt, wird jede dieser Zeichenfolgen gerechtfertigt und mit nachstellenden Leerzeichen innerhalb eines Felds von 16 Bytes aufschlossen:
| Inhalt des Felds Name | BESCHREIBUNG |
|---|---|
| name/ |
Der Name des Archivmembers. |
| / |
Der Archivmember ist einer der beiden Linkermember. Beide Linkermember haben diesen Namen. |
| // |
Das Archivmember ist der Longnames-Member, der aus einer Reihe von AUF NULL endende ASCII-Zeichenfolgen besteht. Der Longnames-Member ist der dritte Archivmember und optional. |
| /n |
Der Name des Archivmembers befindet sich bei Offset n innerhalb des Longnames-Members. Die Zahl n ist die Dezimaldarstellung des Offsets. Beispiel: "/26" gibt an, dass der Name des Archivmembers 26 Bytes hinter dem Anfang des Longnames-Elementinhalts liegt. |
Erster Linkermember
Der Name des ersten Linkermembers lautet "/". Der erste Linkermember ist aus Gründen der Abwärtskompatibilität enthalten. Sie wird nicht von aktuellen Linkern verwendet, aber ihr Format muss korrekt sein. Dieser Linkermember stellt ein Verzeichnis mit Symbolnamen bereit, ebenso wie das zweite Linkermember. Für jedes Symbol geben die Informationen an, wo das Archivmember zu finden ist, das das Symbol enthält.
Der erste Linkermember hat das folgende Format. Diese Informationen werden nach dem Header angezeigt:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Anzahl von Symbolen |
Unsigned long, die die Anzahl der indizierten Symbole enthält. Diese Zahl wird im Big-Endian-Format gespeichert. Jedes Objektdateimember definiert in der Regel ein oder mehrere externe Symbole. |
| 4 |
4 * n |
Offsets |
Ein Array von Dateioffsets zu Archivmemberheadern, in dem n gleich dem Feld Number of Symbols (Anzahl von Symbolen) ist. Jede Zahl im Array ist eine lange Zahl ohne Vorzeichen, die im Big-Endian-Format gespeichert ist. Für jedes Symbol, das in der Zeichenfolgentabelle benannt ist, gibt das entsprechende Element im Offsetarray die Position des Archivelements an, das das Symbol enthält. |
| * |
* |
Zeichenfolgentabelle |
Eine Reihe von auf NULL endenden Zeichenfolgen, die alle Symbole im Verzeichnis benennen. Jede Zeichenfolge beginnt unmittelbar nach dem NULL-Zeichen in der vorherigen Zeichenfolge. Die Anzahl der Zeichenfolgen muss gleich dem Wert des Felds Anzahl von Symbolen sein. |
Die Elemente im Offsetarray müssen in aufsteigender Reihenfolge angeordnet werden. Dies impliziert, dass die Symbole in der Zeichenfolgentabelle entsprechend der Reihenfolge der Archivmember angeordnet werden müssen. Beispielsweise müssten alle Symbole im ersten Objektdateimember vor den Symbolen in der zweiten Objektdatei aufgelistet werden.
Zweiter Linkermember
Der zweite Linkermember hat den Namen "/" wie der erste Linkermember. Obwohl beide Linkermember ein Verzeichnis von Symbolen und Archivmembern bereitstellen, die diese enthalten, wird das zweite Linkermember von allen aktuellen Linkern bevorzugt verwendet. Das zweite Linkermember enthält Symbolnamen in lexikalischer Reihenfolge, was eine schnellere Suche nach Namen ermöglicht.
Das zweite Element hat das folgende Format. Diese Informationen werden nach dem Header angezeigt:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
4 |
Anzahl von Membern |
Ein long-Wert ohne Vorzeichen, der die Anzahl der Archivmember enthält. |
| 4 |
4 * m |
Offsets |
Ein Array von Dateioffsets zu Archivmemberheadern, die in aufsteigender Reihenfolge angeordnet sind. Jeder Offset ist ein lang ohne Vorzeichen. Die Zahl m entspricht dem Wert des Felds Anzahl von Mitgliedern. |
| * |
4 |
Anzahl von Symbolen |
Ein long-Wert ohne Vorzeichen, der die Anzahl der indizierten Symbole enthält. Jedes Objektdateimember definiert in der Regel ein oder mehrere externe Symbole. |
| * |
2 * n |
Indizes |
Ein Array von 1-basierten Indizes (kurz ohne Vorzeichen), die Symbolnamen zu Archivmemberoffsets zuordnen. Die Zahl n entspricht dem Feld Anzahl von Symbolen. Für jedes Symbol, das in der Zeichenfolgentabelle benannt ist, gibt das entsprechende Element im Indexarray einen Index im Offsetarray an. Das Offsetarray gibt wiederum die Position des Archivmembers an, der das Symbol enthält. |
| * |
* |
Zeichenfolgentabelle |
Eine Reihe von auf NULL endenden Zeichenfolgen, die alle Symbole im Verzeichnis benennen. Jede Zeichenfolge beginnt unmittelbar nach dem NULL-Byte in der vorherigen Zeichenfolge. Die Anzahl der Zeichenfolgen muss gleich dem Wert des Felds Anzahl von Symbolen sein. In dieser Tabelle werden alle Symbolnamen in aufsteigender lexikalischer Reihenfolge aufgelistet. |
Longnames-Member
Der Name des Longnames-Members lautet "/". Der Longnames-Member ist eine Reihe von Zeichenfolgen mit Archivmembernamen. Ein Name wird hier nur angezeigt, wenn im Feld Name nicht genügend Platz vorhanden ist (16 Bytes). Der Longnames-Member ist optional. Es kann nur mit einem Header leer sein, oder es kann vollständig fehlen, ohne dass ein Header vorhanden ist.
Die Zeichenfolgen sind NULL-terminiert. Jede Zeichenfolge beginnt unmittelbar nach dem NULL-Byte in der vorherigen Zeichenfolge.
Importieren des Bibliotheksformats
Herkömmliche Importbibliotheken, d. h. Bibliotheken, die die Exporte aus einem Bild zur Verwendung durch ein anderes beschreiben, folgen in der Regel dem in Abschnitt 7, Archivdateiformat (Bibliothek)beschriebenen Layout. Der Hauptunterschied besteht darin, dass Importbibliotheksmember Pseudoobjektdateien anstelle realer Dateien enthalten, in denen jedes Element die Abschnittsbeiträge enthält, die erforderlich sind, um die Importtabellen zu erstellen, die in Abschnitt 6.4, The .idata Section, beschrieben sind. Der Linker generiert dieses Archiv beim Erstellen der exportierenden Anwendung.
Die Abschnittsbeiträge für einen Import können aus einem kleinen Satz von Informationen abgeleitet werden. Der Linker kann entweder die vollständigen, ausführlichen Informationen für jedes Mitglied zum Zeitpunkt der Erstellung der Bibliothek in die Importbibliothek generieren oder nur die kanonischen Informationen in die Bibliothek schreiben und die Anwendung, die sie später verwendet, die erforderlichen Daten im Ruhevorgang generieren lassen.
In einer Importbibliothek mit dem langen Format enthält ein einzelner Member die folgenden Informationen:
- Archivmemberheader
Dateiheader
Abschnittsheader
Daten, die den einzelnen Abschnittsheadern entsprechen
COFF-Symboltabelle
Zeichenfolgen
Im Gegensatz dazu wird eine kurze Importbibliothek wie folgt geschrieben:
- Archiv-Memberheader
Importheader
Auf NULL beendete Importnamenzeichenfolge
AUF NULL beendete DLL-Namenszeichenfolge
Dies sind ausreichende Informationen, um den gesamten Inhalt des Members zum Zeitpunkt seiner Verwendung genau zu rekonstruieren.
Importheader
Der Importheader enthält die folgenden Felder und Offsets:
| Offset | Size | Feld | BESCHREIBUNG |
|---|---|---|---|
| 0 |
2 |
Sig1 |
Muss IMAGE FILE _ _ MACHINE UNKNOWN _ sein. Weitere Informationen finden Sie unter Computertypen. |
| 2 |
2 |
Sig2 |
Muss 0xFFFF. |
| 4 |
2 |
Version |
Die Strukturversion. |
| 6 |
2 |
Machine |
Die Zahl, die den Typ des Zielcomputers identifiziert. Weitere Informationen finden Sie unter Computertypen. |
| 8 |
4 |
Time-Date Stempel |
Die Uhrzeit und das Datum, zu denen die Datei erstellt wurde. |
| 12 |
4 |
Größe der Daten |
Die Größe der Zeichenfolgen, die dem Header folgen. |
| 16 |
2 |
Ordnungszahl/Hinweis |
Entweder die Ordnungszahl oder der Hinweis für den Import, der durch den Wert im Feld Namenstyp bestimmt wird. |
| 18 |
2 Bits |
type |
Der Importtyp. Spezifische Werte und Beschreibungen finden Sie unter Importtyp. |
| 3 Bits |
Namenstyp |
Der Importnamenstyp. Weitere Informationen finden Sie unter Import Name Type. |
|
| 11 Bit |
Reserviert |
Reserviert, muss 0 sein. |
Auf diese Struktur folgen zwei auf NULL beendete Zeichenfolgen, die den Namen des importierten Symbols und die DLL beschreiben, aus der es stammt.
Importtyp
Die folgenden Werte werden für das Feld Typ im Importheader definiert:
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMPORTIEREN _ VON CODE |
0 |
Ausführbarer Code. |
| IMPORTIEREN VON _ DATEN |
1 |
Daten. |
| IMPORT _ CONST |
2 |
Wird in der DEF-Datei als CONST angegeben. |
Diese Werte werden verwendet, um zu bestimmen, welche Abschnittsbeiträge vom Tool generiert werden müssen, das die Bibliothek verwendet, wenn es auf diese Daten zugreifen muss.
Typ des Importnamens
Der auf NULL beendete Importsymbolname folgt unmittelbar auf den zugeordneten Importheader. Die folgenden Werte werden für das Feld Namenstyp im Importheader definiert. Sie geben an, wie der Name verwendet werden soll, um die richtigen Symbole zu generieren, die den Import darstellen:
| Konstante | Wert | BESCHREIBUNG |
|---|---|---|
| IMPORT _ ORDINAL | 0 | Der Import ist nach Ordnungszahl. Dies gibt an, dass der Wert im Feld Ordinal/Hinweis des Importheaders die Ordnungszahl des Imports ist. Wenn diese Konstante nicht angegeben wird, sollte das Feld Ordnungszahl/Hinweis immer als Importhinweis interpretiert werden. |
| _IMPORTNAME | 1 | Der Importname ist mit dem Namen des öffentlichen Symbols identisch. |
| IMPORTNAME _ _ NOPREFIX | 2 | Der Importname ist der name des öffentlichen Symbols, überspringt jedoch die führenden ?, @oder optional _ . |
| IMPORTNAME _ _ UNDECORATE | 3 | Der Importname ist der name des öffentlichen Symbols, überspringt jedoch die führenden ?, @oder optional , und schneide bei der _ ersten @ ab. |
Anhang A: Berechnen des Authenticode PE-Imagehashs
Es wird erwartet, dass mehrere Attributzertifikate verwendet werden, um die Integrität der Images zu überprüfen. Die häufigste ist jedoch die Authenticode-Signatur. Mit einer Authenticode-Signatur kann überprüft werden, ob die relevanten Abschnitte einer PE-Imagedatei in irgendeiner Weise aus dem ursprünglichen Formular der Datei geändert wurden. Um diese Aufgabe zu erfüllen, enthalten Authenticode-Signaturen einen sogenannten PE-Imagehash.
Was ist ein Authenticode PE-Imagehash?
Der Authenticode PE-Imagehash(kurz Dateihash) ähnelt einer Dateiüberprüfungssumme, da er einen kleinen Wert erzeugt, der sich auf die Integrität einer Datei bezieht. Eine Prüfsumme wird von einem einfachen Algorithmus erzeugt und hauptsächlich verwendet, um Speicherfehler zu erkennen. Das heißt, es wird verwendet, um zu erkennen, ob ein Speicherblock auf dem Datenträger fehlerhaft geworden ist und die dort gespeicherten Werte beschädigt wurden. Ein Dateihash ähnelt einer Prüfsumme, da er auch Dateibeschädigungen erkennt. Im Gegensatz zu den meisten Prüfsummenalgorithmen ist es jedoch sehr schwierig, eine Datei so zu ändern, dass sie den gleichen Dateihash wie ihr ursprüngliches (unverändertes) Format hat. Das heißt, eine Prüfsumme soll einfache Speicherfehler erkennen, die zu Beschädigungen führen, aber ein Dateihash kann verwendet werden, um absichtliche und sogar geringfügige Änderungen an einer Datei zu erkennen, z. B. solche, die von Viren, Hackern oder Trojanerprogrammen eingeführt wurden.
Bei einer Authenticode-Signatur wird der Dateihash digital signiert, indem ein privater Schlüssel verwendet wird, der nur dem Signaturgeber der Datei bekannt ist. Ein Softwareverbraucher kann die Integrität der Datei überprüfen, indem er den Hashwert der Datei berechnet und mit dem Wert des signierten Hashs vergleicht, der in der digitalen Authenticode-Signatur enthalten ist. Wenn die Dateihashes nicht übereinstimmen, wurde ein Teil der Vom PE-Imagehash abgedeckten Datei geändert.
Was wird in einem Authenticode PE-Imagehash abgedeckt?
Es ist nicht möglich oder wünschenswert, alle Bilddateidaten in die Berechnung des PE-Imagehashs einzuschließen. Manchmal stellt sie einfach unerwünschte Merkmale dar (z. B. können Debuginformationen nicht aus öffentlich veröffentlichten Dateien entfernt werden). manchmal ist es einfach unmöglich. Beispielsweise ist es nicht möglich, alle Informationen in einer Bilddatei in eine Authenticode-Signatur einzuschließen, dann die Authenticode-Signatur, die diesen PE-Imagehash enthält, in das PE-Image einzufügen und später einen identischen PE-Imagehash generieren zu können, indem alle Bilddateidaten erneut in die Berechnung eingeschlossen werden, da die Datei jetzt die Authenticode-Signatur enthält, die ursprünglich nicht vorhanden war.
Prozess zum Generieren des Authenticode PE-Imagehashs
In diesem Abschnitt wird beschrieben, wie ein PE-Imagehash berechnet wird und welche Teile des PE-Images geändert werden können, ohne dass die Authenticode-Signatur ungültig wird.
Hinweis
Der PE-Imagehash für eine bestimmte Datei kann in einer separaten Katalogdatei enthalten sein, ohne dass ein Attributzertifikat in die Hashdatei eingeschlossen wird. Dies ist relevant, da es möglich ist, den PE-Imagehash in einer Authenticode-signierten Katalogdatei ungültig zu machen, indem ein PE-Image geändert wird, das eigentlich keine Authenticode-Signatur enthält.
Alle Daten in Abschnitten des PE-Images, die in der Abschnittstabelle angegeben sind, werden vollständig mit Einem Hash versehen, mit Ausnahme der folgenden Ausschlussbereiche:
Das CheckSum-Feld der Datei der Windows spezifischen Felder des optionalen Headers. Diese Prüfsumme enthält die gesamte Datei (einschließlich aller Attributzertifikate in der Datei). Die Prüfsumme unterscheidet sich aller Wahrscheinlichkeit nach dem Einfügen der Authenticode-Signatur vom ursprünglichen Wert.
Informationen im Zusammenhang mit Attributzertifikaten. Die Bereiche des PE-Images, die sich auf die Authenticode-Signatur beziehen, sind nicht in der Berechnung des PE-Imagehashs enthalten, da Authenticode-Signaturen einem Image hinzugefügt oder daraus entfernt werden können, ohne die Allgemeine Integrität des Images zu beeinträchtigen. Dies ist kein Problem, da es Benutzerszenarien gibt, die davon abhängen, PE-Images erneut zu signieren oder einen Zeitstempel hinzuzufügen. Authenticode schließt die folgenden Informationen aus der Hashberechnung aus:
Das Feld Zertifikattabelle der optionalen Headerdatenverzeichnisse.
Die Zertifikattabelle und die entsprechenden Zertifikate, auf die das Feld Zertifikattabelle zeigt, das direkt oben aufgeführt ist.
Um den PE-Imagehash zu berechnen, sortiert Authenticode die in der Abschnittstabelle angegebenen Abschnitte nach Adressbereich und hasht dann die resultierende Bytesequenz und übergibt die Ausschlussbereiche.
Informationen nach dem Ende des letzten Abschnitts. Für den Bereich hinter dem letzten Abschnitt (definiert durch den höchsten Offset) wird kein Hashwert festgelegt. Dieser Bereich enthält häufig Debuginformationen. Debuginformationen können im Allgemeinen als Empfehlung für Debugger betrachtet werden. sie wirkt sich nicht auf die tatsächliche Integrität des ausführbaren Programms aus. Es ist durchaus möglich, Debuginformationen aus einem Image zu entfernen, nachdem ein Produkt geliefert wurde, ohne die Funktionalität des Programms zu beeinträchtigen. In der Tat wird dies manchmal als Datenträgersparmaßnahme durchgeführt. Beachten Sie, dass Debuginformationen, die in den angegebenen Abschnitten des PE-Images enthalten sind, nicht entfernt werden können, ohne dass die Authenticode-Signatur ungültig wird.
Sie können die im Windows Platform SDK bereitgestellten Tools makecert und signtool verwenden, um mit dem Erstellen und Überprüfen von Authenticode-Signaturen zu experimentieren. Weitere Informationen finden Sie weiter unten in der Referenz.
References
Downloads und Tools für Windows (einschließlich des Windows SDK)
Erstellen, Anzeigen und Verwalten von Zertifikaten
Exemplarische Vorgehensweise zur Codesignierung im Kernelmodus (.doc)
Windows Authenticode Portable Executable Signature Format (.docx)