Stand: 23. Mai 2020

Inhaltsverzeichnis

über dieses Dokument
was es hierin gibt
wo man die neuste Version bekommt
wie man den Verfasser kontaktiert
welche gesetzlichen Einschränkungen es gibt
Lizenzlosigkeit
Verfasserschutz
Vorbehalt für zusätzliche Einschränkungen für zukünftige Versionen

die Details vom Dateiformat "32 Bit portable executable" ("pe32")
Übersicht
Abschnitte
DOS-Abschnitt
Übersicht
Unterabschnitte
Kopfzeile
Übersicht
Bezeichnung
Unterabschnitte
Signatur
Zweck
Aufbau
Bezeichnung
von mir undokumentierter Bereich
Zweck
unbenutzter Bereich
Offset zum Windows-Abschnitt
Programm
Windows-Abschnitt
Kopfzeile
Übersicht
Bezeichnung
Unterabschnitte
Signatur
Zweck
Aufbau
Bezeichnung
Position
Datei-Kopfzeile
Zweck
Aufbau
Bezeichnung
Position
zusätzliche Kopfzeile
Zweck
Aufbau
Bezeichnung
Position
Tabellenverzeichnis für verschiedene Tabellen
Zweck
Aufbau
Bezeichnung
Hinweise bezüglich dem Betriebssystem "Windows 2000"
Hinweise bezüglich dem Betriebssystem "Windows experience"
Position
Programmabschnitte
Kopfzeilen-Tabelle
Zweck
Aufbau
Bezeichnung
Position
Inhalte
Bezeichnung im Allgemeinen
Gruppierung von den Rohdaten
Namensgebung von einem spezifischen Programmabschnitt
Position
Tabellen
Position
Export-Tabelle für Adressen von Dingen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Export-Tabelle für Adressen von Zeichenketten von Namen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Export-Tabelle für Positionen von Adressen von Dingen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Export-Tabelle für Zeichenketten von Namen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Import-Tabelle für Zeichenketten von Namen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Tabelle für Adressen-Reparaturen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Tabelle für Ressourcen
Tabellenverzeichnis für Export-Tabellen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position
Tabellenverzeichnis für Import-Tabellen
Zweck
Anforderungen an den Programmabschnitt-Inhalt
Aufbau
Bezeichnung
Position

ein "Hallo Welt!"-Programm
Beschreibung
notwendige Voraussetzungen
Vorbereitung
die Datei anlegen
die Datei öffnen
Anmerkungen zum Speichern
DOS-Abschnitt
die Kopfzeile schreiben
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Bereich schreiben
Allgemeines
Änderung
Ergebnis
Größe
den Offset zum Windows-Abschnitt schreiben
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
Windows-Abschnitt
Kopfzeile
die Signatur schreiben
Allgemeines
Änderung
Ergebnis
Größe
die Datei-Kopfzeile schreiben
Allgemeines
Änderung
Ergebnis
Größe
die zusätzliche Kopfzeile schreiben
Allgemeines
Änderung
Ergebnis
Größe
das Tabellenverzeichnis für verschiedene Tabellen schreiben
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
Programmabschnitte
die Kopfzeilen-Tabelle schreiben
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
0. Programmabschnitt-Inhalt
die Funktion "WriteConsoleA"
den Wert vom Parameter "unbenutzt" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion "GetStdHandle"
den Wert vom Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion aufrufen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion "WriteConsoleA"
den Wert vom Parameter "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion aufrufen
Allgemeines
Änderung
Ergebnis
Größe
das Programm beenden
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
die Übersicht
1. Programmabschnitt-Inhalt
die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode schreiben
Allgemeines
Änderung
Ergebnis
Größe
die "Hallo Welt!"-Zeichenkette schreiben
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
2. Programmabschnitt-Inhalt
die Import-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
Änderung
Ergebnis
Größe
das Tabellenverzeichnis für Import-Tabellen schreiben
Allgemeines
Änderung
Ergebnis
Größe
die "kernel32.dll\0"-Zeichenkette schreiben
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
das Programm starten
Allgemeines

eine Bibliothek mit einer "Hallo Welt!"-Funktion
Beschreibung
notwendige Voraussetzungen
Vorbereitung
die Datei anlegen
die Datei öffnen
Anmerkungen zum Speichern
DOS-Abschnitt
Windows-Abschnitt
Kopfzeile
die Signatur schreiben
die Datei-Kopfzeile schreiben
Allgemeines
Änderung
Ergebnis
Größe
die zusätzliche Kopfzeile schreiben
Allgemeines
Änderung
Ergebnis
Größe
das Tabellenverzeichnis für verschiedene Tabellen schreiben
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
Programmabschnitte
die Kopfzeilen-Tabelle schreiben
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
0. Programmabschnitt-Inhalt
die Funktion "WriteConsoleA"
den Wert vom Parameter "unbenutzt" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
den Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion "GetStdHandle"
den Wert vom Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion aufrufen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion "WriteConsoleA"
den Wert vom Parameter "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" auf den Stapel legen
Allgemeines
Änderung
Ergebnis
Größe
die Funktion aufrufen
Allgemeines
Änderung
Ergebnis
Größe
zurückkehren
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
1. Programmabschnitt-Inhalt
die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode schreiben
Allgemeines
Änderung
Ergebnis
Größe
die "Hallo Welt!"-Zeichenkette schreiben
Allgemeines
Änderung
Ergebnis
Größe
den unbenutzten Zwischenraum füllen
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
2. Programmabschnitt-Inhalt
die Import-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
Änderung
Ergebnis
Größe
das Tabellenverzeichnis für Import-Tabellen schreiben
Allgemeines
Änderung
Ergebnis
Größe
die "kernel32.dll\0"-Zeichenkette schreiben
Allgemeines
Änderung
Ergebnis
Größe
die Export-Tabelle für Adressen von Dingen schreiben
Allgemeines
Änderung
Ergebnis
Größe
die Export-Tabelle für Adressen von Zeichenketten von Namen schreiben
Allgemeines
Änderung
Ergebnis
Größe
die Export-Tabelle für Positionen von Adressen von Dingen schreiben
Allgemeines
Änderung
Ergebnis
Größe
die Export-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
Änderung
Ergebnis
Größe
das Tabellenverzeichnis für Export-Tabellen schreiben
Allgemeines
Änderung
Ergebnis
Größe
Übersicht
die Bibliothek benutzen
Allgemeines

weiteres Material zu diesem Thema
Bibliotheken
Dokumente
Programme
Aufnahme von weiteren Materialien


über dieses Dokument

was es hierin gibt

Dieses Dokument
Von diesem Dateiformat gibt es auch eine "64 Bit"-Variante. Diese Variante wird mit "pe32+" abgekürzt. Sie ist in diesem Dokument allerdings nicht beschrieben.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument aufgelistet, welches allgemeine Informationen über enthält.

wo man die neuste Version bekommt

Derzeit nutze ich OnTheServer.de/Downloads/ um neue Versionen zugänglich zu machen. Sie müsste irgendwo dort in den Unterverzeichnissen sein; das kann sich hin und wieder ein bischen ändern.

Dort gibt es vielleicht auch dieses Dokument in anderen Sprachen.

Die Versions-Angabe von diesem Dokument steht oben rechts ("Stand: ...").

wie man den Verfasser kontaktiert

Der Verfasser von diesem Dokument kann mit der Hilfe von einer elektronischen Nachricht kontaktiert werden. Das hierfür eingerichtete Postfach ist mit der Hilfe von der folgenden Adresse erreichbar:
Kontakt@On(entferne mich)TheServer.de

welche gesetzlichen Einschränkungen es gibt

Lizenzlosigkeit

Dieses Dokument
  • ist an keine Lizenz gebunden.
  • unterliegt nicht den Einschränkungen durch das Urhebergesetz.
  • soll allgemeinfrei (public domain) behandelt werden. Also so, als wenn es sich um ein Eigentum von der Allgemeinheit handelt.

Im Übrigen soll alles, was man auf OnTheServer.de und den Subdomains öffentlich zugänglich findet, entsprechend behandelt werden.

Es gibt auf OnTheServer.de allerdings eine Ausnahme:
Ich lege gelegentlich im Verzeichnis "OnTheServer.de/temp/" urheberrechtlich geschütztes Material ab.

Es ist nicht gestattet, auf irreführendeweise vorzutäuschen, dass das (ursprüngliche) Dokument an eine Lizenz gebunden wäre.

Verfasserschutz

Es ist nicht gestattet, auf irreführendeweise vorzutäuschen, dass man der (ursprüngliche) Verfasser vom Dokument wäre. Der (ursprüngliche) Verfasser muss jedoch nicht namentlich genannt werden.

Vorbehalt für zusätzliche Einschränkungen für zukünftige Versionen

Ich (der ursprüngliche Verfasser) behalte die Möglichkeit, Einschränkungen für
  • die Veränderung oder/und
  • die Verbreitung
aufzuerlegen. Von den Einschränkungen wären lediglich neue Versionen betroffen. Was bisher veröffentlicht wurde, erhält keine weiteren Einschränkungen.

Von diesem Recht werde ich hoffentlich nie gebrauch machen müssen.


die Details vom Dateiformat "32 Bit portable executable" ("pe32")

Übersicht

DOS-Abschnitt
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von der Datei:
Kopfzeile IMAGE_DOS_HEADER 32 Byte 0 Byte bis 31 Byte
unbenutzter Bereich 28 Byte 32 Byte bis 59 Byte
Offset zum Windows-Abschnitt 4 Byte 60 Byte bis 63 Byte
Programm variabel 64 Byte bis x Byte
Gesamtgröße: variabel
Windows-Abschnitt
Beschreibung: Bezeichnung: Offset vom Anfang von der Datei:
Kopfzeile IMAGE_NT_HEADERS y Byte bis
Programmabschnitte
Gesamtgröße: variabel

Der Unterabschnitt "Programm" vom DOS-Abschnitt kann in einer ausführbaren Datei von Nutzen sein. In einer Bibliothek ergibt er jedoch normalerweise keinen Sinn, da die "*.dll"-Datei um das DOS-Programm zu starten. Aus diesem Grund ergibt es Sinn, den Unterabschnitt in einer Bibliothek wegzulassen.

Wenn dann
Zwischen kann ein unbenutzter Bereich sein. Dieser Bereich wird ausgeführt. Windows benutzt den angegebenen Offset, um das erste Byte von der Kopfzeile vom Windows-Abschnitt zu finden.

Microsoft empfiehlt, alle unbenutzten Bits auf "0" zu setzen.

Abschnitte

DOS-Abschnitt

Übersicht

Der DOS-Abschnitt ist in die folgenden Unterabschnitte aufgeteilt:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von der Datei:
Kopfzeile IMAGE_DOS_HEADER 32 Byte 0 Byte bis 31 Byte
unbenutzter Bereich 28 Byte 32 Byte bis 59 Byte
Offset zum Windows-Abschnitt 4 Byte 60 Byte bis 63 Byte
Programm variabel 64 Byte bis x Byte
Gesamtgröße: variabel

Unterabschnitte

Kopfzeile
Übersicht
Die Kopfzeile ist in die folgenden Unterabschnitte aufgeteilt:
Beschreibung: Größe: Offset vom Anfang von der Datei:
Signatur 2 Byte 0 Byte bis 1 Byte
von mir undokumentierter Bereich 30 Byte 2 Byte bis 31 Byte
Gesamtgröße: 32 Byte

Bezeichnung
Die Kopfzeile wird von Microsoft
  • manchmal "DOS-Kopfzeile" (im Englischen: "DOS header") und
  • manchmal "old-style header"
genannt.

Microsoft benutzt die Bezeichnung "old-style header" noch nicht so lange, wie die Bezeichnung "DOS-Kopfzeile" (im Englischen: "DOS header").

Unterabschnitte
Signatur
Zweck
Die Kopfzeile beginnt mit der Zeichenkette "MZ". Anhand von diesen 2 Byte kann man erkennen, dass es sich um eine "Mark Zbikowski"-Datei handelt.

Mark Zbikowski war der Entwickler vom Dateiformat, welches sich in "*.exe"-Dateien für DOS findet.

Dieses Dateiformat ist heute im Dateiformat "portable executable" ("pe") enthalten und füllt den kompletten DOS-Abschnitt. In Dateien für Windows werden allerdings nicht immer alle Felder vom ursprünglichen Dateiformat für DOS definiert, sondern manchmal nur das allernötigste, damit das Lade-Programm von Windows die Datei akzeptiert und den Windows-Abschnitt findet.

Aufbau
Beschreibung: Bezeichnung: Größe: Hexadezimalwert: Offset vom Anfang von der Datei:
das ASCII-Zeichen "M" e_magic 1 Byte 4D 0 Byte
das ASCII-Zeichen "Z" 1 Byte 5A 1 Byte
Gesamtgröße: 2 Byte

Bezeichnung
Das "MZ" und damit dieser Unterabschnitt wird von Microsoft "DOS-Signatur" (im Englischen: "DOS signature") genannt.

von mir undokumentierter Bereich
Zweck
Die Bytes von diesem Bereich bilden den Rest von der Kopfzeile vom DOS-Abschnitt.

Wenn
  • es sich bei der Datei um eine ausführbare Datei handelt,
dann gilt:
  • Wenn
    • die "*.exe"-Datei auch in DOS laufen soll,
    dann
    • müssen die von mir undokumentierten Felder in diesem Bereich ausgefüllt werden, da DOS die komplette "32 Byte"-große Kopfzeile liest und auswertet.
    Ansonsten wenn
    • die Lauffähigkeit in Windows genügt,
    dann
Ansonsten wenn
  • es sich bei der Datei um eine Bibliothek handelt,
dann
  • müssen die von mir undokumentierten Felder in diesem Bereich nicht ausgefüllt werden, da "*.dll"-Dateien von DOS ohnehin nicht unterstützt werden.

Diese Dokumentation beschränkt sich auf Dateien für Windows. Daher sind die Felder von diesen Bereich in diesem Dokument nicht dokumentiert.

Bei der Suche im Internet helfen vielleicht die Namen für die Kopfzeile vom DOS-Abschnitt
  • "DOS header" und
  • "old-style header".
Allerdings gibt es, von dem was ich so gesehen habe, nicht sonderlich viele Informationen über diesen Abschnitt.

unbenutzter Bereich
Microsoft empfiehlt, alle unbenutzten Bits auf "0" zu setzen.

Beschreibung: Größe: Hexadezimalwert: Offset vom Anfang von der Datei:
unbenutzt 28 Byte 00 32 Byte bis 59 Byte
Gesamtgröße: 28 Byte

Offset zum Windows-Abschnitt
Beschreibung: Bezeichnung: Größe: Hexadezimalwert: Offset vom Anfang von der Datei:
Offset vom Anfang von der Datei bis zum Anfang vom Windows-Abschnitt e_lfanew 4 Byte 60 Byte bis 63 Byte
Gesamtgröße: 4 Byte

In den ursprünglichen "Mark Zbikowski"-Dateien existiert diese Offset-Angabe nicht, da Windows in dem Zeitraum, als das ursprüngliche Dateiformat "Mark Zbikowski" entwickelt wurde, noch nicht existiert hatte. Stattdessen ist in den ursprünglichen "Mark Zbikowski"-Dateien der unbenutzte Bereich "32 Byte"-groß.

Wenn
  • sodass die Datei in Windows laufen kann,
dann
Der Wert, welcher hier angegeben wird, muss restlos durch 8 teilbar sein.

Programm
Beschreibung: Größe: Hexadezimalwert: Offset vom Anfang von der Datei:
die Daten und der Maschinencode vom DOS-Programm variabel 64 Byte bis x Byte
Gesamtgröße: variabel

Windows-Abschnitt

Kopfzeile

Übersicht
Die Kopfzeile ist in die folgenden Unterabschnitte aufgeteilt:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Windows-Abschnitt:
Signatur Signature 4 Byte 0 Byte bis 3 Byte
Datei-Kopfzeile FileHeader 20 Byte 4 Byte bis 23 Byte
zusätzliche Kopfzeile OptionalHeader 96 Byte 24 Byte bis 119 Byte
Tabellenverzeichnis für verschiedene Tabellen DataDirectory 8 Byte * x 120 Byte bis (120 Byte + (8 Byte * x) - 1 Byte)
Gesamtgröße: 120 Byte + (8 Byte * x)

Bezeichnung
Die Kopfzeile wird von Microsoft "NT-Kopfzeilen" (im Englischen: "NT headers") genannt.

Unterabschnitte
Signatur
Zweck
Die Kopfzeile beginnt mit der Zeichenkette "PE". Nach diesen 2 Byte kommen 2 weitere Byte von welchen alle Bits auf "0|b" gesetzt sind.

Anhand von diesen 4 Byte kann erkannt werden, dass für die Datei
  • nicht nur das Dateiformat "Mark Zbikowski" ("MZ"),
  • sondern auch das Dateiformat "portable executable" ("pe")
verwendet wird.

Aufbau
Beschreibung: Bezeichnung: Größe: Hexadezimalwert: Offset vom Anfang von
der Signatur: dem Windows-Abschnitt:
das ASCII-Zeichen "P" Signature 1 Byte 50 0 Byte 0 Byte
das ASCII-Zeichen "E" 1 Byte 45 1 Byte 1 Byte
Alle 16 Bits sind auf "0" gesetzt. 2 Byte 00 2 Byte
bis
3 Byte
2 Byte
bis
3 Byte
Gesamtgröße: 4 Byte

Bezeichnung
Das "PE" wird von Microsoft "NT-Signatur" (im Englischen: "NT signature") genannt.

Position
Die Position vom 0. Byte vom Windows-Abschnitt wurde im Feld "e_lfanew" vom Abschnitt "Offset zum Windows-Abschnitt" vom DOS-Abschnitt angegeben. Das ist der Offset zum Windows-Abschnitt.

Die Signatur von der Kopfzeile vom Windows-Abschnitt beginnt dort, wo das 0. Byte vom Windows-Abschnitt ist.

Datei-Kopfzeile
Zweck
Die Datei-Kopfzeile besteht aus Einträgen, welche Auskünfte über den Windows-Abschnitt machen.

Aufbau
Beschreibung: Bezeichnung: Größe: Hexadezimalwert Offset vom Anfang von
2560: 2561: 2562: 2563: der Datei-Kopfzeile: dem Windows-Abschnitt:
Mit der Hilfe von diesem Feld wird eine Auskunft über die Hardware-Architektur vom CPU gemacht, für welche die Datei geschrieben wurde.

In allen Dateien, welche ich mir angeschaut hatte, war hier der Wert "14C|h" gespeichert.

Die Bedeutungen von den Werten sind wie folgt:
Architektur: Bezeichnung: Datengröße vom Befehlssatz: Hersteller: Hexadezimalwert
2560: 2561:
Das Lade-Programm von Windows soll nicht prüfen, ob die Datei auf der richtigen Architektur ausgeführt wird.

Wenn
  • in der Datei kein Maschinencode enthalten ist, welcher ausgeführt wird und
  • die Datei zur Laufzeit mit der Hilfe von
    • der Funktion "LoadLibraryEx(A/W)" von der Bibliothek "kernel32.dll" und
    • der Anweisung "LOAD_LIBRARY_AS_DATAFILE"
    geladen wird,
dann
  • kann dieser Wert gewählt werden.
IMAGE_FILE_MACHINE_UNKNOWN 00 00

Power PC ohne Fließkomma-Unterstützung IMAGE_FILE_MACHINE_POWERPC Konsortium aus
  • Apple,
  • International Business Machines Corporation (IBM) und
  • Motorola
F0 01
Power PC mit Fließkomma-Unterstützung IMAGE_FILE_MACHINE_POWERPCFP Konsortium aus
  • Apple,
  • International Business Machines Corporation (IBM) und
  • Motorola
F1 01

x86 IMAGE_FILE_MACHINE_AMD64 8 Byte
(d. h. "64 Bit"-Befehle)
Advanced Micro Devices Incorporated (AMD) 64 86

x86 IMAGE_FILE_MACHINE_I386 4 Byte
(d. h. "32 Bit"-Befehle), also die Architektur vom Prozessor "80386" (alias "Intel386"), oder eine spätere, darauf basierende Architektur
Intel Corporation 4C 01
x86 IMAGE_FILE_MACHINE_IA64 8 Byte
(d. h. "64 Bit"-Befehle)
Intel Corporation 00 02

R4000 mit "little endian"-Kodierung MIPS Technologies Incorporated 66 01

Scheinbar gab es früher noch andere Werte, wie zum Beispiel jeweils einen zur Kennzeichnung von
  • einem "Intel486er"-Prozessor und
  • einem "Pentium"-Prozessor.
Diese scheinen allerdings vom Betriebssystem "Windows xp" nicht mehr unterstützt zu werden.
Machine 2 Byte 4C 01 - - 0 Byte
bis
1 Byte
4 Byte
bis
5 Byte
Mit der Hilfe von diesem Feld wird die Anzahl der Programmabschnitte von dieser Datei angegeben.

Die Programmabschnitte sind die letzten Abschnitte in der Datei.

Die maximale Anzahl, welche hier stehen darf, wird durch das Lade-Programm von Betriebssystem "Windows" in der Version "experience" ("xp") auf 96|d begrenzt. In der Version "Vista" und den späteren Versionen gibt es keine solche Begrenzung mehr. Das bedeutet, dass die maximale Anzahl, welche hier stehen darf, der Wert "FF FF|h = 65.535|d" ist.
NumberOfSections 2 Byte - - 2 Byte
bis
3 Byte
6 Byte
bis
7 Byte
Mit der Hilfe von diesem Feld wird, in der Form von einem Unix-Zeitstempel (im Englischen: Unix timestamp), eine Auskunft über
  • das Datum und
  • die Uhrzeit
gemacht, wann diese Datei erzeugt wurde. Diese Angabe ist eine Art von Versionsangabe von der Datei.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument über Zeitsysteme aufgelistet. In diesem Dokument sind auch die Spezifikationen vom Zeitsystem "Unix-Zeitstempel" enthalten.

Wenn
  • andere Programme Dinge, also Datensätze oder Funktionen, aus dieser Datei importieren wollen,
dann
  • können sie eine schnellere Methode verwenden, als die Universalmethode.

Beim Import mit der Hilfe von
  • der Universalmethode schaut das Lade-Programm, an welche Stelle vom Segment die Bibliothek geladen wurde und versucht dann herauszufinden, wo das Ding in dieser Bibliothek ist, um anschließend die Adresse zu diesem Ding zu berechnen und der Anwendung, welche dieses Ding benutzen möchte, den Zugriff zu geben.
  • der schnelleren Methode schaut das Lade-Programm ebenfalls, an welche Stelle vom Segment die Bibliothek geladen wurde, versucht dann aber nicht herauszufinden, wo das Ding in dieser Bibliothek ist. Stattdessen hat bei dieser Methode der Programmierer den relativen Offset bereits in der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode angegeben, sodass jetzt bereits die absolute Adresse berechnet werden kann.

    Dazu wird allerdings verglichen, ob übereinstimmt, um sicher zu stellen, dass der Programmierer die Offsets von der selben Version von der Bibliothek angegeben hat, wie von der Version, welche auf dem Computer vorhanden ist, auf welchem das Programm ausgeführt wird.

Wenn
  • ich die schnellere Methode richtig verstanden habe,
dann
  • reicht es aus, wenn
    • die Angabe aus dieser Datei mit der Angabe übereinstimmt, welche in der Datei gespeichert ist, welche etwas importieren möchte. Es muss sich also nicht um eine korrekte Zeitangabe handeln.

      Und
    • die Angabe sich von den Angaben von den anderen Versionen von dieser Datei eindeutig unterscheidet, sodass die Überprüfung vom Zeitstempel zur zuverlässigen Erkennung von inkompatiblen Versionen führt.

Der Windows Explorer scheint die Zeitangabe nicht dem Benutzer anzuzeigen. Er zeigt vielmehr eine andere Zeitangabe an, welche sich Windows im Dateisystem zu speichern scheint.

Manche Link-Programme scheinen hier einen falschen Wert oder einen Wert in einem anderen Format, als in der vorgesehenen "little endian"-Kodierung, zu speichern.
TimeDateStamp 4 Byte 4 Byte
bis
7 Byte
8 Byte
bis
11 Byte
Diese 4 Byte geben einen Offset in Byte an, vom Anfang der Datei, bis dorhin, wo der Abschnitt "Symbol-Tabelle" beginnt. Die Symbol-Tabelle scheint zur Fehlersuche (debugging) vorgesehen zu sein.

Microsoft empfiehlt, von diesem Feld alle Bits auf "0|b" zu setzen, da dieses Hilfsmittel zur Fehlersuche veraltet sei.
PointerToSymbolTable 4 Byte 00 00 00 00 8 Byte
bis
11 Byte
12 Byte
bis
15 Byte
Diese 4 Byte geben die Anzahl der Symbole in der Symbol-Tabelle an.

Microsoft empfiehlt, von diesem Feld alle Bits auf "0|b" zu setzen, da dieses Hilfsmittel zur Fehlersuche veraltet sei.
NumberOfSymbols 4 Byte 00 00 00 00 12 Byte
bis
15 Byte
16 Byte
bis
19 Byte
Diese 2 Byte geben die Größe von der zusätzlichen Kopfzeile und vom Tabellenverzeichnis für verschiedene Tabellen zusammengerechnet in Byte an.

In den Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "E0|h = 224|d" gespeichert. Also
   96 Byte für die zusätzliche Kopfzeile
+ 128 Byte für das Tabellenverzeichnis für verschiedene Tabellen
= 224 Byte

Wenn dann
  • ist ein anderer Wert notwendig.

Die zusätzliche Kopfzeile kommt in der Datei direkt nach dieser Datei-Kopfzeile. Das Tabellenverzeichnis für verschiedene Tabellen kommt direkt nach der zusätzlichen Kopfzeile.

Laut einer anderen Quelle wird mit der Hilfe von dieser Angabe der Abstand in Byte angegeben, Dies müsste jedoch der selbe Wert sein.
SizeOfOptionalHeader 2 Byte E0 00 - - 16 Byte
bis
17 Byte
20 Byte
bis
21 Byte
Die einzelnen Bits von diesem Feld machen Auskünfte, wie zum Beispiel, ob diese Datei eine Bibliothek ist.

In ausführbaren Dateien, welche ich mir angeschaut hatte, war meistens die Bitfolge
"0000 0001 0000 1111|b"
gespeichert. Das ist der Wert "1 0F|h".

In einer ausführbaren Datei war diese Bitfolge eingetragen:
"1000 0001 1000 1110|b"
Das ist der Wert "81 8E|h".

In Bibliotheken, welche ich mir angeschaut hatte, war meistens die Bitfolge
"0010 0001 0000 1110|b"
gespeichert. Das ist der Wert "21 0E|h".

In wenigen Bibliotheken war diese Bitfolge eingetragen:
"0010 0001 0000 0010"
Das ist der Wert "21 02|h".

Die Bedeutungen von den einzelnen Bits sind wie folgt:
allgemeine Beschreibung: Bedeutung wenn Bezeichnung: Wertigkeit:
Wert=="0": Wert=="1":
Gibt an, was das Lade-Programm tun soll, wenn die Datei nicht an die gewünschte Stelle im Segment geladen werden kann.

Welche Adresse die gewünschte Stelle im Segment ist, kann mit der Hilfe vom Feld "ImageBase" von der zusätzlichen Kopfzeile angegeben werden.
Wenn
  • die Datei nicht an die gewünschte Stelle im Segment geladen werden kann,
dann
  • soll der Lade-Vorgang deshalb nicht abgebrochen werden.
Wenn
  • die Datei nicht an die gewünschte Stelle im Segment geladen werden kann,
dann
  • soll der Lade-Vorgang abgebrochen werden.

    In diesem Fall wird die Fehlermeldung
    'Die Anwendung konnte nicht richtig initialisiert werden (0xc0000018). Klicken Sie auf "OK", um die Anwendung zu beenden.'
    angezeigt.
IMAGE_FILE_RELOCS_STRIPPED 20
Gibt an, ob die Datei verwendet werden kann.

Dieses Bit sollte eigentlich immer auf "1" gesetzt sein.
Diese Datei kann nicht verwendet werden, da es beispielsweise einen Fehler im Link-Programm gab. Diese Datei kann verwendet werden. IMAGE_FILE_EXECUTABLE_IMAGE 21
Gibt an, ob Informationen über die Zeilennummer vorhanden sind.

Microsoft sieht die Information von diesem Bit als veraltet an und empfiehlt, dieses Bit auf "0" zu setzen. Warum Microsoft "0" anstatt "1" empfiehlt, kann ich mir nicht erklären.

Dieses Bit wird in ausführbaren Dateien nicht ausgewertet.
Es sind Informationen über die Zeilennummer vorhanden. Es sind keine Informationen über die Zeilennummer vorhanden. IMAGE_FILE_LINE_NUMS_STRIPPED 22
Gibt an, ob Informationen über lokale Symbole vorhanden sind.

Microsoft sieht die Information von diesem Bit als veraltet an und empfiehlt, dieses Bit auf "0" zu setzen. Warum Microsoft "0" anstatt "1" empfiehlt, kann ich mir nicht erklären.

Dieses Bit wird in ausführbaren Dateien nicht ausgewertet.
Es sind Informationen über lokale Symbole vorhanden. Es sind keine Informationen über lokale Symbole vorhanden. IMAGE_FILE_LOCAL_SYMS_STRIPPED 23
Gibt an, ob alle Byte, welche das Programm im Arbeitsspeicher belegt, auf die Festplatte ausgelagert werden sollen.

Bei Hintergrundanwendungen, welche nur selten irgendeine Aktivität ausführen, kann dies sinnvoll sein.

Microsoft sieht die Information von diesem Bit für "Windows 2000" und spätere Versionen als veraltet an und empfiehlt, dieses Bit auf "0" zu setzen.

In der Kopfzeilen-Tabelle der Programmabschnitte gibt es ein Bit, welches eine Auskunft darüber macht, ob ein bestimmter Programmabschnitt auf die Festplatte ausgelagert werden darf.
Der belegte Arbeitsspeicher soll nicht auf die Festplatte ausgelagert werden. Der belegte Arbeitsspeicher soll auf die Festplatte ausgelagert werden. IMAGE_FILE_AGGRESSIVE_WS_TRIM 24
Laut Microsoft gibt dieses Bit an, ob das Programm Adressen handhaben kann, welche über 2 Gigabyte hinausgehen (also zum Beispiel die Adresse 2.952.790.016).

Das Lade-Programm teilt den Arbeitsspeicher vom Segment im Wesentlichen in 2 Bereiche auf:
  • Der eine Bereich belegt die niedrigen Adressen. Prinzipiell kann Maschinencode mit allen "privilege levels" auf diesen Bereich zugreifen.
  • Der andere Bereich belegt die hohen Adressen. Prinzipiell kann nur Maschinencode mit dem 'privilege level "0"' auf diesen Bereich zugreifen.

Mit der Hilfe von diesem Bit wird angegeben, wie groß diese beiden Bereiche sein sollen. Damit dieses Bit jedoch eine Auswirkung hat, muss beim letzten Hochfahren die relevante Hochfahreinstellung verwendet worden sein:
  • In der Version "Windows experience" ("Windows xp") muss hierfür in der Datei "boot.ini" der Parameter "/3GB" vorhanden sein, sodass der Inhalt von der Datei beispielsweise wie folgt aussieht:
    [Operating Systems]
    multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows XP Professional" /fastdetect /3GB

    In manchen anderen Versionen vom Betriebssystem bewirkt diese Option,
    • dass lediglich der Bereich, welcher die hohen Adressen belegt, auf die höchstwertigsten 1 GB reduziert wird, ohne
    • dass dabei der andere Bereich, welcher die niedrigen Adressen belegt, vergrößert wird.
    Somit entsteht ein ungenutzter "1 GB"-großer Zwischenbereich.
  • In der Version "Windows Vista" müssen hierfür die Bootkonfigurationsdaten geändert werden:
    1. auf den "Start"-Knopf klicken
    2. auf "ausführen ..." klicken
    3. "bcdedit /set increaseuserva 3072" eingeben und mit "[enter]" bestätigen

    Die Einstellung kann mit der Eingabe "bcdedit /deletevalue increaseuserva" wieder entfernt werden.

Damit diese Einstellung übernommen wird, muss das Betriebssystem "Windows" neugestartet werden.

Die Einstellung kann dazu führen, dass gewisse Treiber nicht mehr funktionieren. Das Betriebssystem "Windows" verweigert möglicherweise anschließend vollständig das Hochfahren.

Wenn
  • noch mehr Arbeitsspeicher verwendet werden soll,
dann
  • kann eine Anwendung mehrere Segmente verwenden oder
  • zur Laufzeit den Inhalt von einem Teil von seinem Adressraum austauschen (Stichwort: address windowing extension (AWE)).
Beide Bereiche sollen "2 Gigabyte"-groß sein:
  • Der eine Bereich belegt die Speicherzellen mit den Adressen
    • von 00 00 00 00|h
    • bis 7F FF FF FF|h
    und
  • der andere Bereich belegt die Speicherzellen mit den Adressen
    • von 80 00 00 00|h
    • bis FF FF FF FF|h.
  • Der eine Bereich soll "3 Gigabyte"-groß sein und die Speicherzellen mit den Adressen
    • von 00 00 00 00|h
    • bis BF FF FF FF|h
    belegen.
  • Der andere Bereich soll "1 Gigabyte"-groß sein und die Speicherzellen mit den Adressen
    • von C0 00 00 00|h
    • bis FF FF FF FF|h
    belegen.
IMAGE_FILE_LARGE_ADDRESS_AWARE 25
Dieses Bit wird nicht benutzt.

Microsoft empfiehlt, dieses Bit auf "0" zu setzen.
26
Hier konnte ich nicht zufriedenstellend klären, welche Bedeutung dieses Bit hat.

Microsoft sieht die Information von diesem Bit als veraltet an und empfiehlt, dieses Bit auf "0" zu setzen.
IMAGE_FILE_BYTES_REVERSED_LO 27
Gibt an, ob die CPU-Architektur eine "32 Bit"-Architektur, oder eine darauf basierende Architektur, sein muss.

Im "32 Bit portable executable"-Format müsste dieses Bit eigentlich immer auf "1" gesetzt sein.

Das Lade-Programm scheint diesen Wert nicht auszuwerten. Auch nicht bei einer Datei im "64 Bit portable executable"-Format.
Die Architektur muss keine "32 Bit"-Architektur, oder eine darauf basierende Architektur, sein. Die Architektur muss eine "32 Bit"-Architektur, oder eine darauf basierende Architektur, sein. IMAGE_FILE_32BIT_MACHINE 28
Gibt an, ob Hilfs-Informationen für eine Fehlersuche (debugging) vorhanden sind. Es sind Hilfs-Informationen für eine Fehlersuche vorhanden. Es sind keine Hilfs-Informationen für eine Fehersuche vorhanden. IMAGE_FILE_DEBUG_STRIPPED 29
Gibt an, ob das Programm von einem Wechselmedium (zum Beispiel CD oder USB-Stick) ausgeführt werden darf. Wenn nicht, dann wird das Programm zunächst in die Auslagerungsdatei kopiert.

(das sollte ich prüfen: wird das Programm nicht eh in den Arbeitsspeicher kopiert bevor es ausgeführt wird!?)
Das Programm darf auch von einem Wechselmedium ausgeführt werden. Das Programm darf nicht von einem Wechselmedium ausgeführt werden. Wenn
  • es dennoch auf einem Wechselmedium ist, während es gestartet wird,
dann
  • muss es zunächst in die Auslagerungsdatei kopiert werden.
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 210
Gibt an, ob das Programm auch über ein Netzwerk ausgeführt werden darf. Wenn nicht, dann wird das Programm zunächst in die Auslagerungsdatei kopiert.

(das sollte ich prüfen: wird das Programm nicht eh in den Arbeitsspeicher kopiert bevor es ausgeführt wird!?)
Das Programm darf auch über ein Netzwerk ausgeführt werden. Das Programm darf nicht über ein Netzwerk ausgeführt werden.

Wenn
  • es dennoch auf einem anderen Computer ist, während es gestartet wird,
dann
  • muss es zunächst in die Auslagerungsdatei kopiert werden.
IMAGE_FILE_NET_RUN_FROM_SWAP 211
Gibt an, ob es sich um eine Systemdatei vom Betriebssystem oder um einen Treiber handelt.

Scheinbar setzt kaum ein Treiberhersteller dieses Bit. Nichteinmal Microsoft scheint hier konsequent zu sein. Ich betrachte dieses Bit daher als unzuverlässige Information.

Dieses Bit wird in ausführbaren Dateien nicht ausgewertet.
Diese Datei ist
  • weder eine Systemdatei vom Betriebssystem
  • noch ein Treiber.
Diese Datei ist
  • eine Systemdatei vom Betriebssystem oder
  • ein Treiber.
IMAGE_FILE_SYSTEM 212
Gibt an, ob die Datei eine Bibliothek ist. Die Datei ist keine Bibliothek. Die Datei ist eine Bibliothek. IMAGE_FILE_DLL 213
Gibt an, ob die Datei auch auf einem Rechner ausgeführt werden darf, welcher über mehrere Prozessoren verfügt. Prozessorkerne gelten nicht als einzelne Prozessoren.

Nach einer anderen Quelle reicht bereits die Auswahl "Multiprocessor-PC", um das Kriterium zu erfüllen. Bei der Installation von
  • dem Betriebssystem "Windows 2000" und
  • dem Betriebssystem "Windows experience"
kann über die [F5]-Taste die Wahl getroffen werden. Standardmäßig ist "ACPI Multiprocessor-PC" gewählt.
Die Datei darf auch auf einem "Multiprocessor-PC" ausgeführt werden. Die Datei darf nicht auf einem "Multiprocessor-PC" ausgeführt werden. Ein "Uniprocessor-PC" ist stattdessen notwendig. IMAGE_FILE_UP_SYSTEM_ONLY 214
Hier konnte ich nicht zufriedenstellend klären, welche Bedeutung dieses Bit hat.

Microsoft sieht die Information von diesem Bit als veraltet an und empfiehlt, dieses Bit auf "0" zu setzen.
IMAGE_FILE_BYTES_REVERSED_HI 215
Characteristics 2 Byte - - 18 Byte
bis
19 Byte
22 Byte
bis
23 Byte
Gesamtgröße: 20 Byte

Bezeichnung
Dieser Unterabschnitt wird von Microsoft ebenfalls "Datei-Kopfzeile" (im Englischen: "file header") genannt.

Position
Die Position vom 0. Byte vom Windows-Abschnitt wurde im Feld "e_lfanew" vom Abschnitt "Offset zum Windows-Abschnitt" vom DOS-Abschnitt angegeben. Das ist der Offset zum Windows-Abschnitt.

Die Datei-Kopfzeile von der Kopfzeile vom Windows-Abschnitt beginnt dort, wo das 4. Byte vom Windows-Abschnitt ist.

Somit kommt die Datei-Kopfzeile direkt nach der Signatur, also ohne unbenutzte Bytes zwischen

zusätzliche Kopfzeile
Zweck
Die zusätzliche Kopfzeile besteht aus Einträgen, welche ebenfalls Auskünfte über den Windows-Abschnitt machen.

Diese Kopfzeile muss in
  • jeder ausführbaren Datei und
  • jeder Bibliothek
vorkommen. In "*.obj"-Dateien hingegen macht sie keinen Sinn und kann dort weggelassen werden.

Aufbau
Beschreibung: Bezeichnung: Größe: Hexadezimalwert Offset vom Anfang von
2560: 2561: 2562: 2563: diesem Abschnitt: dem Windows-Abschnitt:
Mit der Hilfe von diesem Feld wird angegeben, gemäß welchem Dateiformat diese Datei aufgebaut ist:
Dateiformat: Hexadezimalwert
2560: 2561:
32 Bit portable executable (pe32) 0B 01
64 Bit portable executable (pe32+) 0B 02

In dieser Dokumentation ist lediglich die "32 Bit"-Variante beschrieben.
Magic 2 Byte 0B 01 - - 0 Byte
bis
1 Byte
24 Byte
bis
25 Byte
Gibt die Hauptversion vom Link-Programm an.

Wenn
  • das Link-Programm beispielsweise die Version "1.4" hat,
dann
  • ist "1" die Hauptversion.

Wenn
  • die Hauptversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version inkompatibel zur Vorgängerversion ist.

Manche Link-Programme setzen hier einen inkorrekten Wert und manche Link-Programme setzen hier alle 8 Bits auf "0". Welches Link-Programm verwendet wurde, wird nach meinem Kenntnisstand nirgends angegeben.
MajorLinkerVersion 1 Byte 00 - - - 2 Byte 26 Byte
Gibt die Unterversion vom Link-Programm an.

Wenn
  • das Link-Programm beispielsweise die Version "1.4" hat,
dann
  • ist "4" die Unterversion.

Wenn
  • die Unterversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version kompatibel zur Vorgängerversion ist.

Manche Link-Programme setzen hier einen inkorrekten Wert und manche Link-Programme setzen hier alle 8 Bits auf "0". Welches Link-Programm verwendet wurde, wird nach meinem Kenntnisstand nirgends angegeben.
MinorLinkerVersion 1 Byte 00 - - - 3 Byte 27 Byte
Mit der Hilfe von diesem Feld wird die Größe von den ausführbaren Codes von allen Programmabschnitt-Inhalten zusammengerechnet in Byte angegeben.

Manche Link-Programme setzen hier einen inkorrekten Wert.

Das Lade-Programm von Windows wertet diesen Wert nicht aus, sondern hält sich an die Werte von den einzelnen Programmabschnitten in der Kopfzeilen-Tabelle der Programmabschnitte.
SizeOfCode 4 Byte 00 00 00 00 4 Byte
bis
7 Byte
28 Byte
bis
31 Byte
Mit der Hilfe von diesem Feld wird die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet in Byte angegeben. Hier sind nur die Daten gemeint, welche bereits beim Programmstart mit Werten definiert sind.

Manche Link-Programme setzen hier einen inkorrekten Wert.

Das Lade-Programm von Windows wertet diesen Wert nicht aus, sondern hält sich an die Werte von den einzelnen Programmabschnitten in der Kopfzeilen-Tabelle der Programmabschnitte.
SizeOfInitializedData 4 Byte 00 00 00 00 8 Byte
bis
11 Byte
32 Byte
bis
35 Byte
Mit der Hilfe von diesem Feld wird die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet in Byte angegeben. Hier sind nur die Daten gemeint, deren Größe zwar beim Programmstart bekannt ist, welche aber noch nicht mit Werten definiert sind.

Die Kompiler von manchen Programmiersprachen benutzen keine solchen Daten. In diesen Sprachen sind dann die Daten
  • entweder nicht vorhanden
  • oder vorhanden und mit Werten definiert.

Manche Link-Programme setzen hier einen inkorrekten Wert.

Das Lade-Programm von Windows wertet diesen Wert nicht aus, sondern hält sich an die Werte von den einzelnen Programmabschnitten in der Kopfzeilen-Tabelle der Programmabschnitte.
SizeOfUninitializedData 4 Byte 00 00 00 00 12 Byte
bis
15 Byte
36 Byte
bis
39 Byte
Mit der Hilfe von diesem Feld wird ein Offset in Byte angegeben,
  • vom ersten Byte, welches die Datei im Segment belegt,
  • bis zu dem Byte im Segment, wo Maschinecode ist, welcher ausgeführt werden soll, sobald ein Ereignis eingetreten ist.
Dieser Offset ist nicht zwangsweise der selbe Offset
  • vom Anfang von der Datei
  • bis zum Maschinencode in der Datei.
Es ist auch nicht zwangsweise das erste Byte vom gesamten Maschinencode.

Welches Ereignis eingetreten sein muss, hängt davon ab, um welche Art von Datei es sich handelt. Bei
  • einer ausführbaren Datei gibt es das folgende Ereignis:
    • Die Anwendung wurde vollständig geladen.
  • einer Bibliothek gibt es folgende Ereignisse:
    • Die Bibliothek wurde ins Segment von einer Anwendung geladen.
    • Die Bibliothek wird gleich aus dem Segment von einer Anwendung gelöscht. Dies passiert zum Beispiel, wenn die Anwendung beendet wird.
    • Ein weiterer "thread" wird gestartet.
    • Ein bestehender "thread" wird beendet.

      Hier ist nicht der "Hauptthread" gemeint. Wenn
      • also die Anwendung beendet wird und
      • es nur 1 "Hauptthread" gibt,
      dann
      • zählt dies nicht als das Eintreten von 2 Ereignissen, sondern lediglich als das Eintreten von 1 Ereignis.

    Wenn
    • dieser Maschinencode zum ersten Mal ausgeführt wird,
    dann
    • zwangsweise deshalb, weil das oberste Ereignis eingetroffen ist.
    Ansonsten

In der Beschreibung vom Feld "DllCharacteristics" sind weitere Informationen darüber enthalten, wie das Reagieren auf einzelne Ereignisse aktiviert/deaktiviert werden kann/konnte.

Wenn
  • das Ende vom auszuführenden Maschinencode erreicht wurde,
dann Das Beenden von der Ausführung vom Maschinencode entspricht also dem Zurückkehren von einer Funktion, welche keine Parameter hat. Die Initialisierungsrountine von einer Bibliothek hat jedoch Parameter. Diese können, müssen aber nicht, vom Stapel geworfen werden.

Wenn
  • kein Maschinencode ausgeführt werden soll, nur weil eines von diesen Ereignissen eingetroffen ist und
  • es sich um eine Bibliothek handelt,
dann
  • können alle Bits von diesem Feld auf "0" gesetzt werden.
Bei einer ausführbaren Datei würde die Maschinencodeausführung dennoch beginnen. Das "MZ" würde vom Prozessor als der folgende Maschinencode interpretiert werden:
# M ≙ 4D|h
dec(extended base pointer (ebp))

# Z ≙ 5A|h
extended data (edx) = pop()

Wenn
  • ein anderer Wert als der Wert "0" angegeben wurde und
  • vom Betriebssystem die Version "Windows 8" verwendet wird,
dann
  • darf kein Wert angegeben sein, welcher kleiner als jener Wert ist, welcher im Feld "SizeOfHeaders" angegeben wurde.
AddressOfEntryPoint 4 Byte 16 Byte
bis
19 Byte
40 Byte
bis
43 Byte
Mit der Hilfe von diesem Feld wird ein Offset in Byte angegeben,
  • vom ersten Byte, welches die Datei im Segment belegt,
  • bis zu dem Byte im Segment, wo der Maschinencode beginnt.

Dieser Offset gibt nicht zwangsweise an, welches Byte vom Maschinencode ausgeführt werden soll, wenn die Anwendung geladen wurde.

In den meisten Dateien, welche ich mir angeschaut hatte, waren
  • im Feld "AddressOfEntryPoint" und
  • im Feld "BaseOfCode"
der selbe Wert, also der selbe Offset, eingetragen.

In allen ausführbaren Dateien, welche ich mir angeschaut hatte, war im Feld "BaseOfCode" der Wert "10 00|h" eingetragen.

Dieser Wert scheint vom Lade-Programm von Windows nicht ausgewertet zu werden. Wenn
  • man mehrere Programmabschnitte mit Maschinencode hat,
dann
  • würde ohnehin die Frage aufkommen, zum Maschinencode von welchem Programmabschnitt der Offset angegeben werden soll.
BaseOfCode 4 Byte 00 00 00 00 20 Byte
bis
23 Byte
44 Byte
bis
47 Byte
Mit der Hilfe von diesem Feld wird ein Offset in Byte angegeben,
  • vom ersten Byte, welches die Datei im Segment belegt,
  • bis zu dem Byte im Segment, wo die Daten gespeichert sind, welche bereits beim Programmstart mit Werten definiert seien sollen.

In allen ausführbaren Dateien, welche ich mir angeschaut hatte, war hier der Wert "20 00|h" gespeichert.

Dieser Wert scheint vom Lade-Programm von Windows nicht ausgewertet zu werden. Wenn
  • man mehrere Programmabschnitte mit solchen Daten hat,
dann
  • würde ohnehin die Frage aufkommen, zu den Daten von welchem Programmabschnitt der Offset angegeben werden soll.
BaseOfData 4 Byte 00 00 00 00 24 Byte
bis
27 Byte
48 Byte
bis
51 Byte
Mit der Hilfe von diesem Feld wird die Adresse angegeben, wo die Datei im Segment beginnen soll. Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment vom Programm.

Wenn
  • ein Link-Programm mit absoluten Adressen im Segment arbeitet,
dann
  • kann es vorteilhaft sein, wenn das Programm an der korrekten Stelle im Segment ist. So stimmen
    • die Anfangsadressen von Daten und
    • die Einsprungadressen von Funktionen
    mit den tatsächlichen Adressen im Segment überein.

Wenn
  • es nicht möglich sein sollte, die Datei an diese Stelle ins Segment zu laden, und
  • absolute Adressangaben verwendet wurden,
dann
  • ändert das Lade-Programm die zu reparierenden Adressen, welche durch das Link-Programm vorgegeben wurden.

Dafür ist allerdings zusätzliche Ladezeit für das Programm notwendig. Außerdem muss dann mindestens 1 Tabelle für Adressen-Reparaturen existieren.

Einige Offset-Angaben von diesem Dateiformat beziehen sich auf diesen Wert, sodass die Position von einer Speicherzelle relativ zu jener Speicherzelle angegeben wird, welche mit der Hilfe von diesem Wert angegeben wird. Der Wert muss jedoch im Maschinencode bei den Parametern von den Maschinenbefehlen berücksichtigt werden. Also zum Beispiel
  • bei Anfangsadressen von Daten und
  • bei Einsprungadressen von Funktionen.

Die Adresse, welche hier angegeben wird, muss restlos durch 64 Kilobyte teilbar sein.

Als Standardwert gibt Microsoft
  • für ausführbare Dateien den Wert
    "40 00 00|h", also 4 Megabyte,
  • für Bibliotheken den Wert
    "10 00 00 00|h", also 256 Megabyte,
  • für Treiber den Wert
    "1 00 00|h", also 64 Kilobyte,
für diese Feld vor.

Wenn
  • hier der Wert
    "0|h"
    angegeben wird,
dann
  • muss die Datei verschoben werden, da die ersten 64 Kilobyte vom Segment vom Betriebssystem verwendet werden.

Ich empfehle daher,
  • für ausführbare Dateien den von Microsoft vorgeschlagenen Standardwert zu benutzen, damit keine Adressen-Reparaturen notwendig sind.
  • für Bibliotheken den Wert "0|h" zu benutzen, da ohnehin die Angabe von den Adressen-Reparaturen in der Datei notwendig sind.

Ange Albertini erwähnt, dass der Wert "0|h" bei ausführbaren Dateien vom Lade-Programm vom Betriebssystem "Windows" in der Version "experience" ("xp") akzeptiert wird. Es ist zwar eine Verschiebung notwendig, aber die Erwähnung hinterlässt den Eindruck, dass das Lade-Programm von anderen Versionen vom Betriebssystem diesen Wert bei ausführbaren Dateien nicht akzeptiert.

Eine ausführbare Datei darf nicht mit den Bibliotheken
  • "kernel32.dll" und
  • "ntdll.dll"
überlagert werden. Ansonsten kann die ausführbare Datei nicht gestartet werden, sondern es wird eine Fehlermeldung ausgegeben:
Fehlerbeschreibung: Version vom Betriebssystem:
Testprogramm.exe - Illegales Verschieben einer System-DLL

Die System-DLL "kernel32.dll" wurde im Speicher verschoben. Die Anwendung wird nicht einwandfrei ausgeführt. Die Datei wurde verschoben, da die DLL "C:\Testprogramm.exe" einen Adressbereich belegt, der für Windows-System-DLLs reserviert ist. Besorgen Sie sich vom DLL-Lieferanten eine neue DLL.
experience (xp)
the subsystem needed to support the image type is not present

Diese Fehlermeldung wurde von Ange Albertini gemeldet.
7

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument über das Lade-Programm aufgelistet. In diesem ist enthalten,
  • mit welchen Inhalten das Segment von der Anwendung beim Starten gefüllt ist und
  • wo diese Inhalte im Segment platziert sind.
ImageBase 4 Byte 00 00 28 Byte
bis
31 Byte
52 Byte
bis
55 Byte
Eine konstante Größe für jede Seite von den Programmabschnitt-Inhalten in Byte, wenn sie ins Segment geladen wurden.

Wenn dann
  • wird er in Teile aufteilt. Ein solcher Teil wird "Seite" genannt.

  • Desto kleiner eine Seite ist,
  • desto mehr Seiten benötigt das Lade-Programm um den selben Inhalt im Arbeitsspeicher zu speichern.
Aber
  • desto weniger wird vom Segment belegt, da in der letzten Seite weniger Byte ungenutzt sind. Allerdings sind pro Seite Zusatzdaten irgendwo an einer anderen Stelle im Arbeitsspeicher notwendig, um die Zugriffsberechtigungen zu speichern.

Laut Microsoft ist der Standardwert hier die Größe von einer RAM-Seite, welche die CPU-Architektur für den Arbeitsspeicher vorgesehen hat. Also bei "32 Bit"-x86er-CPUs 4 Kilobyte (der Wert "10 00|h").

Wenn
  • ein Wert gewählt wird, welcher kleiner ist, als die Größe von einer RAM-Seite,
dann
  • muss es der selbe Wert sein, wie im nächsten Feld "FileAlignment" angegeben ist.

    Bei dieser Regelung scheint es sich um eine Hilfe für das Lade-Programm von Windows zu handeln.

Laut einem Mitarbeiter von Microsoft muss sich dieser Wert aus 2x ergeben. Allerdings muss er ≥ 512 Byte sein und ≤ 256 Megabyte sein, um den Vorgaben vom Dateiformat zu entsprechen.

Das Lade-Programm von "Windows xp" akzeptiert allerdings auch kleinere Werte. Laut Bernd Luevelsmeyer, welcher sich auf einen Testdurchlauf von David Binette beruft, akzeptiert das Lade-Programm von "Windows 95" lediglich den Wert "4 Kilobyte".

Meine Erfahrung ist, dass wenn
  • der Wert kleiner als 4 Kilobyte ist,
dann
  • sind nach der Durchführung von einer Adressen-Reparatur nicht immer die korrekten Zugriffsberechtigungen auf die Programmabschnitt-Inhalte gegeben.

Wenn dann
  • füllt dieser - bei 4.096 Byte pro Seite - im Arbeitsspeicher 2 Seiten. Der Inhalt benötigt daher 8.196 Byte im Arbeitsspeicher.

Die Bits von den restlichen Bytes von der 2. Seite werden vom Lade-Programm alle auf "0" gesetzt.

Ich empfehle, für den Wert von diesem Feld wenigstens den Standardwert von 4 Kilobyte zu verwenden, da ich selbst schon viel Zeit verloren habe, um den Fehler mit den fehlenden Zugriffsberechtigungen zu finden und zu beheben.
SectionAlignment 4 Byte 00 10 00 00 32 Byte
bis
35 Byte
56 Byte
bis
59 Byte
Eine konstante Größe für jede Seite von den Programmabschnitt-Inhalten in Byte, solange sie noch in der Datei auf der Festplatte/Diskette/CD/was auch immer sind.

Da die einzelnen Seiten von jedem Programmabschnitt-Inhalt direkt hintereinander kommen, glaube ich, dass dieses "aufteilen" in Seiten ein Hilfskonstrukt für das Lade-Programm von Windows ist.

  • Desto kleiner eine Seite ist,
  • desto mehr Seiten sind notwendig, um den selben Inhalt zu speichern.
Aber
  • desto kleiner ist die Dateigröße von der Datei, da in der letzten Seite weniger Byte ungenutzt sind.

Wenn
  • sich die Anfangsadresse/Offset von den Daten von einem Programmabschnitt-Inhalt nicht restlos durch 16 Byte bzw. 32 Byte teilen lässt,
dann
  • benötigt das Lade-Programm vermutlich mehr Zeit, da es eine Optimierung vom Prozessor nicht nutzen kann. (Notiz: diese Information gilt als ungesichert)

Der Standardwert ist hier 512 Byte (also der Wert "200|h").

Laut Microsoft:
Wenn
  • ein Wert gewählt wird, welcher kleiner ist, als die Größe von einer RAM-Seite, welche die CPU-Architektur für den Arbeitsspeicher vorgesehen hat,
dann
  • muss es der selbe Wert sein, wie im vorherigen Feld "SectionAlignment" angegeben ist.

Nach meiner eigenen Erfahrung müssen die Werte nicht übereinstimmen, solange ein Wert für dieses Feld gewählt wird, welcher 512 Byte oder größer ist.

Leider akzeptiert es das Lade-Programm in einem solchen Fall nicht, dass man den Wert "512 Byte" angibt, und sich dann bei den Längen von den Programmabschnitt-Inhalten nicht daran hält, sondern die Längen beispielsweise lediglich restlos durch 256 Byte teilbar macht.

Dieser Wert muss sich aus 2x ergeben. Allerdings muss er ≥ 512 Byte sein und ≤ 64 Kilobyte sein, um den Vorgaben vom Dateiformat zu entsprechen.

Wenn
  • die Werte von den beiden Feldern übereinstimmen,
dann
  • ist der kleinste Wert, welchen das Lade-Programm von "Windows xp" akzeptiert, der Wert "1".

Laut Bernd Luevelsmeyer, welcher sich auf einen Testdurchlauf von David Binette beruft, akzeptiert das Lade-Programm von "Windows 95" lediglich den Wert "512 Byte".

Wenn dann
  • füllt dieser - bei 512 Byte pro Seite - in der Datei 11 Seiten. Der Inhalt benötigt daher 5.632 Byte in der Datei.

Die Bits von den restlichen Bytes von der letzten Seite sollen alle auf "0" gesetzt werden.

Ich empfehle, für den Wert von diesem Feld den Standardwert von 512 Byte zu verwenden, da ich selbst schon viel Zeit verloren habe, um den Fehler mit den fehlenden Zugriffsberechtigungen zu finden und zu beheben.
FileAlignment 4 Byte 00 02 00 00 36 Byte
bis
39 Byte
60 Byte
bis
63 Byte
Wenn
  • ein bestimmtes Betriebssystem notwendig ist, damit die Datei ausgeführt werden kann,
dann
  • kann hier die Hauptversion vom Betriebssystem eingetragen werden.

Wenn
  • hier beispielsweise der Wert "4|h" eingetragen ist,
dann
  • bedeutet dies, dass "Windows NT 4.x" oder neuer notwendig ist.

Wenn
  • die Hauptversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version inkompatibel zur Vorgängerversion ist.

Das Lade-Programm von Windows scheint diesen Wert allerdings nicht auszuwerten.
MajorOperatingSystemVersion 2 Byte 00 00 - - 40 Byte
bis
41 Byte
64 Byte
bis
65 Byte
Wenn
  • ein bestimmtes Betriebssystem notwendig ist, damit die Datei ausgeführt werden kann,
dann
  • kann hier die Unterversion vom Betriebssystem eingetragen werden.

Wenn
  • hier beispielsweise der Wert "1|h" eingetragen wird,
dann
  • bedeutet dies, dass "Windows NT x.1" oder neuer notwendig ist.

Wenn
  • die Unterversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version kompatibel zur Vorgängerversion ist.

Das Lade-Programm von Windows scheint diesen Wert allerdings nicht auszuwerten.
MinorOperatingSystemVersion 2 Byte 00 00 - - 42 Byte
bis
43 Byte
66 Byte
bis
67 Byte
Mit der Hilfe von diesem Feld wird die Hauptversion von der Datei angegeben.

Wenn
  • die Hauptversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version inkompatibel zur Vorgängerversion ist.

Diese 2 Byte scheinen nicht ausgewertet zu werden. Wenn
  • man sich im Windows Explorer die Eigenschaften der Datei anschaut,
dann
  • sieht man in den Reitern
    • "Dateiinfo" und
    • "Version"
    Werte, welche sonst irgendwoher kommen, nur nicht aus diesen 2 Byte.
MajorImageVersion 2 Byte 00 00 - - 44 Byte
bis
45 Byte
68 Byte
bis
69 Byte
Mit der Hilfe von diesem Feld wird die Unterversion von der Datei angegeben.

Wenn
  • die Unterversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version kompatibel zur Vorgängerversion ist.

Diese 2 Byte scheinen nicht ausgewertet zu werden. Wenn
  • man sich im Windows Explorer die Eigenschaften der Datei anschaut,
dann
  • sieht man in den Reitern
    • "Dateiinfo" und
    • "Version"
    Werte, welche sonst irgendwoher kommen, nur nicht aus diesen 2 Byte.
MinorImageVersion 2 Byte 00 00 - - 46 Byte
bis
47 Byte
70 Byte
bis
71 Byte
Mit der Hilfe von diesem Feld wird die Hauptversion vom Betriebssystem angegeben, welche mindestens notwendig ist, damit die Datei ausgeführt werden kann.

Dieser Wert, wird im Vergleich zum Feld "MajorOperatingSystemVersion" tatsächlich ausgewertet. Wenn
  • hier der Wert "0|h" angegeben wird,
dann
  • versucht Windows die Version "new technology 3.51|d" ("NT 3.51|d") zu emulieren und erzeugt dadurch eventuell Fehler.

Es muss mindestens um die Version "3.10|d" gebeten werden.

In den Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "4|h" angegeben. Also "Windows NT 4.x".

Im Taschenrechner von Windows ist im Feld "MajorOperatingSystemVersion" angegeben, dass mindestens "Windows NT 5.1" notwendig ist, im Feld "MajorSubsystemVersion" ist allerdings angegeben, dass mindestens "Windows NT 4.0" notwendig ist. Hier scheint es also einen Bedeutungsunterschied zu geben, welchen ich noch nicht herausgefunden habe.

Wenn
  • die Hauptversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version inkompatibel zur Vorgängerversion ist.

Wenn
  • es sich um eine Bibliothek handelt und
  • vom Betriebssystem eine ältere Version als die Version "Windows 8" verwendet wird,
dann
  • wird der Wert von diesem Feld ignoriert.
Ansonsten
  • wertet das Lade-Programm diesen Wert aus.

Betriebssystem Wert für das Feld ...:
Bezeichnung: Markteinführung: Version: MajorSubsystemVersion MinorSubsystemVersion
Windows new technology (NT) Juli 1993 3.1 3|h 1|h
Windows new technology (NT) September 1994 3.5 3|h 5|h (?)
Windows new technology (NT) Mai 1995 3.5.1 3|h 33|h (?)
Windows new technology (NT) Juli 1996 4.0 4|h 0|h
Windows 2000 Dezember 1999 5.00 5|h 0|h
Windows experience (XP) 32 Bit August 2001 5.01 5|h 1|h
Windows experience (XP) 64 Bit ? 5.02 5|h 2|h
Windows Server 2003 März 2003 5.02 5|h 2|h
Windows Server 2003 R2 ? 5.02 5|h 2|h
Windows Vista Januar 2007 6.00
(build 6000)
6|h 0|h
Windows Server 2008 März 2008 6.00
(build 6001)
6|h 0|h
Windows 7 Oktober 2009 6.01
(build 7600)
6|h 1|h
Windows Server 2008 R2 Oktober 2009 6.01
(build 7600)
6|h 1|h
Windows 8 ? 6.02
(build ?)
6|h 2|h
Windows Server 2012 ? 6.02
(build ?)
6|h 2|h
Windows 8.1 ? 6.03
(build ?)
6|h 3|h
Windows Server 2012 R2 ? 6.03
(build ?)
6|h 3|h
Windows 10 ? 10.00
(build ?)
10|h 0|h
Windows Server 2016 ? 10.00
(build ?)
10|h 0|h
Windows Server 2019 ? 10.00
(build ?)
10|h 0|h

Für die Betriebssysteme
  • "Windows 7" und
  • "Windows Server 2008 R2"
wurde die selbe Versionsnummer vergeben, da sie auf dem selben Quellcode basieren.

Manche neuere Link-Programme setzen hier fälschlicherweise einen zu hohen Wert. Beim Versuch, das Programm auf einem älteren Betriebssystem zu starten, erscheint daher eine Fehlermeldung.
MajorSubsystemVersion 2 Byte 04 00 - - 48 Byte
bis
49 Byte
72 Byte
bis
73 Byte
Mit der Hilfe von diesem Feld wird die Unterversion vom Betriebssystem angegeben, welche mindestens notwendig ist, damit die Datei ausgeführt werden kann.

Wenn
  • die Unterversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version kompatibel zur Vorgängerversion ist.

In den Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "0|h" angegeben.

Wenn
  • es sich um eine Bibliothek handelt und
  • vom Betriebssystem eine ältere Version als die Version "8" verwendet wird,
dann
  • wird der Wert von diesem Feld ignoriert.
Ansonsten
  • wertet das Lade-Programm diesen Wert aus.
MinorSubsystemVersion 2 Byte 00 00 - - 50 Byte
bis
51 Byte
74 Byte
bis
75 Byte
Laut Microsoft Corporation sind diese 4 Byte sind unbenutzt. Microsoft empfiehlt, alle Bits auf "0" zu setzen.

Laut Ange Albertini werden diese 4 Byte benutzt. Leider habe ich nicht verstanden, wofür der Wert dient. Ich gebe daher im Folgenden ein wörtliches Zitat wieder:
If non null, it overrides MajorVersion/MinorVersion/BuildNumber/PlatformId OperatingSystem Versions values located in the PEB, after loading.
Win32VersionValue 4 Byte 00 00 00 00 52 Byte
bis
55 Byte
76 Byte
bis
79 Byte
Mit der Hilfe von diesem Feld wird die Gesamtgröße von der Datei in Byte angegeben, wenn sie ins Segment geladen wurde. Dieser Wert muss so aufgerundet werden, dass er ein Vielfaches vom Wert im Feld "SectionAlignment" ist. Also in der Regel ein Vielfaches von 4 Kilobyte.

Dieser Wert ist in der Regel größer als einfach nur die Größe von der Datei auf der Festplatte/Diskette/CD/was auch immer, da jeder Programmabschnitt-Inhalt im Segment in Seiten aufgeteilt wird, welche in der Regel größer sind, als die Seiten, wenn sie noch auf der Festplatte/Diskette/CD/was auch immer ist.

Außerdem gibt es im Segment Bereiche, welche für Daten vorgesehen sind, deren Größe zwar beim Programmstart bekannt ist, welche aber erst zur Laufzeit das erste Mal mit Werten definiert werden. Alle Bits von diesen Bereichen werden vom Lade-Programm auf "0" gesetzt. Da hier also keine Informationen gespeichert sind, müssen diese auch nicht in der Datei auf der Festplatte/Diskette/CD/was auch immer vorkommen. Lediglich wo diese Bereiche im Segment sein sollen und wieviele Bytes für sie reserviert werden sollen, kann in der Datei angegeben werden.
SizeOfImage 4 Byte 56 Byte
bis
59 Byte
80 Byte
bis
83 Byte
Mit der Hilfe von diesem Feld wird die Größe von
  dem DOS-Abschnitt
+ der Kopfzeile vom Windows-Abschnitt
+ der Kopfzeilen-Tabelle von den Programmabschitten
zusammengerechnet in Byte angegeben.

Diese Größe ist oft auch ein Offset,
Dieser Wert muss auf ein Vielfaches von dem Wert im Feld "FileAlignment" aufgerundet werden. Also in der Regel auf ein Vielfaches von 512 Byte.

In allen Dateien, welche ich mir angeschaut hatte, war hier die Wert "4 00|h" gespeichert, also 1.024 Byte.
SizeOfHeaders 4 Byte 00 04 00 00 60 Byte
bis
63 Byte
84 Byte
bis
87 Byte
Mit der Hilfe von diesem Feld wird eine Prüfsumme für die komplette Datei angegeben.

Während der Berechnung von der Prüfsumme müssen alle Bits von diesen 4 Byte auf "0" gesetzt sein. Anschließend kann hier der berechnete Wert gespeichert werden.

Wie die Berechnung stattfindet, scheint nicht sonderlich gut dokumentiert zu sein.

Vielleicht hilft dem Einen oder Anderen dieses Zitat von dem Autor von DumpPE:
The checksum is basically a sum of 16-bit words across the file, plus the file length.

This pseudo code goes something like this:
DWORD CheckSum = 0;

while(WordLength--){
// 16-bit
CheckSum += (DWORD)*WordPointer++;

// fold in the carry
CheckSum = (CheckSum >> 16) + (CheckSum & 0xFFFF);
}

// fold final carry
CheckSum = (CheckSum >> 16) + (CheckSum & 0xFFFF);

// add on file length
CheckSum = (CheckSum & 0xFFFF) + FileLength;

Ich konnte nicht überprüfen, ob damit eine korrekte Berechnung möglich ist.

Dieser Wert wird bei
    • ausführbaren Dateien und
    • normalen Bibliotheken
    nicht ausgewertet.
    • Bibliotheken oder
    • Treibern,
    welche während dem Bootvorgang geladen werden, sehrwohl ausgewertet.

Zur Berechnung kann
  • die Bibliothek "imagehlp.dll" oder
  • das kostenlose Programm "DumpPE"
benutzt werden.

In
  • allen ausführbaren Dateien und
  • einigen Bibliotheken,
welche ich mir angeschaut hatte, waren hier alle Bits auf "0" gesetzt. Allerdings war beispielsweise in der Bibliothek "kernel32.dll" ein anderer Wert eingetragen.
CheckSum 4 Byte 00 00 00 00 64 Byte
bis
67 Byte
88 Byte
bis
91 Byte
Diese Feld gibt an, welches Untersystem benötigt wird.

Die einzelnen Werte haben die folgenden Bedeutungen:
Bedeutung: Hexadezimalwert
2560: 2561:
Es wird kein Untersystem benötigt, weil es sich beispielsweise um
  • eine Bibliothek,
  • einen Treiber oder
  • einen Windows-eigenen-Prozess
handelt.
01 00
Es wird das System zur Darstellung von grafischen Benutzeroberflächen von Windows für Desktop-Rechner benötigt. 02 00
Es wird eine Konsole (Eingabeaufforderung) benötigt.

Dieser Wert führt dazu, dass dem Programm eine Konsole zugewiesen wird, welche nach dem Programmstart automatisch angezeigt wird.

In der Konsole wird der Ausgabe-Datenkanal angezeigt. Die Konsole hat außerdem
  • einen Eingabe-Datenkanal und
  • einen Fehler-Datenkanal.
03 00
Es wird das System zur Darstellung von grafischen Benutzeroberflächen von "Windows CE" benötigt. 09 00
Es wird das System von der XBOX benötigt. 0E 00

Laut Ange Albertini wertet das Lade-Programm den Wert von diesem Feld bei einer Bibliothek nicht aus.
Subsystem 2 Byte - - 68 Byte
bis
69 Byte
92 Byte
bis
93 Byte
Mit der Hilfe von den einzelnen Bits von diesem Feld werden Auskünfte in Bibliotheken gemacht.

In allen ausführbaren Dateien, welche ich mir angeschaut hatte, waren alle 16 Bits auf "0" gesetzt. In den meisten Bibliotheken, welche ich mir angeschaut hatte, waren ebenfalls alle 16 Bits auf "0" gesetzt.

In einer Bibiliothek war allerdings diese Bitfolge gespeichert:
0000 0100 0000 0000|b

Die Bedeutungen von den einzelnen Bits sind wie folgt:
allgemeine Beschreibung: Bedeutung wenn Wert=="0": Bedeutung wenn Wert=="1": Wertigkeiten:
In einer alten Dokumentation von Intel Corporation ist eine Beschreibung enthalten, wie mit der Hilfe von diesen Bits bei einer Bibliothek das Reagieren auf einzelne Ereignisse aktiviert/deaktiviert werden kann. Vielleicht
  • war die Beschreibung früher einmal gültig.
  • hat sie Microsoft Corporation nie umgesetzt.

Gemäß der Beschreibung wird durch die Aktivierung/Deaktivierung entschieden, ob der Maschinencode ausgeführt werden soll, welcher an der Adresse beginnt, welche mit der Hilfe vom Feld "AddressOfEntryPoint" angegeben wird.

Im Betriebssystem "Windows experience" ("Windows xp") werden diese Bits nicht (mehr) benutzt. Das bedeutet, dass wenn
  • es sich um eine ausführbare Datei handelt,
dass dann
  • der Maschinencode ohne einer weitere Bedingung ausgeführt wird.
Ansonsten wenn
  • es sich um eine Bibliothek handelt,
  • im Feld "AddressOfEntryPoint" ein anderer Wert als der Wert "0" angegeben wurde und
  • ein beliebiges von den genannten Ereignissen eintritt,
dass dann
  • der Maschinencode ebenfalls ohne eine weitere Bedingung ausgeführt wird.

    Das Eintreten von mehreren solchen Ereignissen führt zur mehrmaligen Ausführung vom Maschinencode.

Microsoft empfiehlt, diese Bits auf "0" zu setzen.

In einem Dokument von Herr Matt Pietrek wird zwar prinzipiell der Zweck von den Bits gemäß der Beschreibung von Intel Corporation bestätigt, jedoch erkennt Herr Pietrek ebenfalls an, dass die Reaktionen auf die Ereignisse nicht deaktiviert werden können.
Laut wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • die Bibliothek ins Segment von einer Anwendung geladen wurde.
Der Maschinencode soll bei diesem Ereignis nicht ausgeführt werden. Der Maschinencode soll bei diesem Ereignis ausgeführt werden. 20
Laut Intel Corporation wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • die Bibliothek gleich aus dem Segment von einer Anwendung gelöscht wird.

    Dies passiert zum Beispiel, wenn die Anwendung beendet wird.

Laut Matt Pietrek wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • ein bestehender "thread" beendet wird.

    Hier ist nicht der "Hauptthread" gemeint. Wenn
    • also die Anwendung beendet wird und
    • es nur 1 "Hauptthread" gibt,
    dann
    • zählt dies nicht als das Eintreten von 2 Ereignissen, sondern lediglich als das Eintreten von 1 Ereignis.
Der Maschinencode soll bei diesem Ereignis nicht ausgeführt werden. Der Maschinencode soll bei diesem Ereignis ausgeführt werden. 21
Laut wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • ein weiterer "thread" gestartet wird.
Der Maschinencode soll bei diesem Ereignis nicht ausgeführt werden. Der Maschinencode soll bei diesem Ereignis ausgeführt werden. 22
Laut Intel Corporation wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • ein bestehender "thread" beendet wird.

    Hier ist nicht der "Hauptthread" gemeint. Wenn
    • also die Anwendung beendet wird und
    • es nur 1 "Hauptthread" gibt,
    dann
    • zählt dies nicht als das Eintreten von 2 Ereignissen, sondern lediglich als das Eintreten von 1 Ereignis.

Laut Matt Pietrek wird dieses Bit benutzt, um bei einer Bibliothek anzugeben, ob der Maschinencode ausgeführt werden soll, wenn
  • die Bibliothek gleich aus dem Segment von einer Anwendung gelöscht wird.

    Dies passiert zum Beispiel, wenn die Anwendung beendet wird.
Der Maschinencode soll bei diesem Ereignis nicht ausgeführt werden. Der Maschinencode soll bei diesem Ereignis ausgeführt werden. 23
Diese Bits werden nicht benutzt.

Microsoft empfiehlt, diese Bits auf "0" zu setzen.
24 bis 25
Gibt an, ob die Bibliothek zwangsweise an der gewünschten Stelle im Segment platziert werden muss.

Die gewünschte Stelle, wo die Bibliothek im Segment platziert werden soll, kann mit der Hilfe vom Feld "ImageBase" angegeben werden.

(Notiz: entweder stimmt diese Beschreibung nicht, oder dieses Bit wird nicht ausgewertet)
Die Bibliothek muss an der gewünschten Stelle im Segment platziert werden, andernfalls kann ihr Maschinencode nicht ausgeführt werden. Die Bibliothek muss nicht an der gewünschten Stelle im Segment platziert werden. Der Maschinencode kann trotzdem ausgeführt werden. 26
Gibt an, ob die angegebene Prüfsumme auch dann überprüft werden soll, wenn dies das Lade-Programm normalerweise nicht tun würde.

Die Prüfsumme kann mit der Hilfe vom Feld "CheckSum" angegeben werden.

(Notiz: ich sollte prüfen, ob diese Angabe stimmt)
Das Lade-Programm soll selbst entscheiden, ob es die Prüfsumme überprüfen will. Das Lade-Programm soll überprüfen, ob die angegebene Prüfsumme für diese Datei stimmt. 27
Leider konnte ich nicht zufriedenstellend klären, wofür diese Bits verwendet werden. 28 bis 211
Dieses Bit wird nicht benutzt.

Microsoft empfiehlt, diese Bits auf "0" zu setzen.
212
Gibt an, ob es sich bei dieser Datei um einen Treiber handelt, welcher gemäß dem "Windows Driver Model" ("WDM") geschrieben wurden. Bei der Datei handelt es sich
  • um keinen Treiber oder
  • der Treiber wurde nicht gemäß dem "Windows Driver Model" ("WDM") geschrieben.
Bei der Datei handelt es sich
  • um einen Treiber und
  • der Treiber wurde gemäß dem "Windows Driver Model" ("WDM") geschrieben.
213
Dieses Bit wird nicht benutzt.

Microsoft empfiehlt, diese Bits auf "0" zu setzen.
214
Leider konnte ich nicht zufriedenstellend klären, wofür dieses Bit verwendet wird. 215
DllCharacteristics 2 Byte 00 00 - - 70 Byte
bis
71 Byte
94 Byte
bis
95 Byte
Mit der Hilfe von diesem Feld wird die Größe vom Stapel angegeben, welche er während der Laufzeit maximal haben soll. Dies ist nicht die Größe, welche er beim Programmstart im physikalischen Arbeitsspeicher belegt, sondern vielmehr eine Begrenzung von der Größe.

Wenn
  • der Stapel während der Laufzeit gefüllt wird,
dann
  • wächst die Größe in "4 Kilobyte"-Schritten. Oder genauer gesagt: in der Größe, welche eine RAM-Seite von der CPU-Architektur hat.

Die Größe von einer RAM-Seite beträgt bei einer Kombination von
  • dem Betriebssystem "Windows" und
  • einem Prozessor mit der x86-Architektur
4 Kilobyte. Dies gilt unabhängig davon,
  • in welcher Betriebsart der Prozessor läuft (zum Beispiel einer "32 Bit"-Betriebsart oder einer "64 Bit"-Betriebsart) und
  • von welchem Hersteller der Prozessor ist.

In einem Stapel werden beispielsweise
  • Parameter von Funktionen,
  • Inhalte von Prozessor-Registern oder/und
  • Rücksprungadressen
zwischengespeichert. Mit der Hilfe von den Befehlen
  • "pop" und
  • "push"
kann ein Stapel
  • gefüllt und
  • geleert
werden. Hierdurch werden jedoch keine bestehenden RAM-Seiten gelöscht, sodass der belegte Speicher freigegeben werden würde.

Im Dokument "Betriebssystem-spezifische - Windows - Funktionen vom Betriebssystem" sind im Kapitel "allgemeine Informationen zum Windows application programming interface - verschiedene Konzepte - Stapel" weitere Informationen hierzu enthalten.

Bei der Bedeutung von diesem Feld ist der Stapel vom ersten "thread" gemeint. Wenn
  • ein Programm weitere "threads" startet,
dann
  • haben diese eigene Stapel.

In den Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "10 00 00|h" gespeichert. Also 1 Megabyte.

Bei einer Bibliothek wird dieses Feld vermutlich nicht ausgewertet, da Bibliotheken den Stapel von der Anwendung mitbenutzen.
SizeOfStackReserve 4 Byte 00 00 10 00 72 Byte
bis
75 Byte
96 Byte
bis
99 Byte
Mit der Hilfe von diesem Feld wird die Größe vom Stapel angegeben, welche er beim Programmstart im physikalischen Arbeitsspeicher belegen soll.

In den Dateien, welche ich mir angeschaut hatte, war hier immer
  • der Wert "10 00|h" (also 4 Kilobyte) oder
  • der Wert "20 00|h" (also 8 Kilobyte)
gespeichert.

Bei einer Bibliothek wird dieses Feld vermutlich nicht ausgewertet, da Bibliotheken den Stapel von der Anwendung mitbenutzen.

Der Wert von diesem Feld muss nicht restlos durch die Größe von einer RAM-Seite (= 4 Kilobyte) teilbar sein, aber das Lade-Programm rundet ihn auf eine solche Größe auf.
SizeOfStackCommit 4 Byte 00 10 00 00 76 Byte
bis
79 Byte
100 Byte
bis
103 Byte
Mit der Hilfe von diesem Feld wird die Größe vom Haufen angegeben, welche er während der Laufzeit maximal haben soll. Dies ist nicht die Größe, welche er beim Programmstart im physikalischen Arbeitsspeicher belegt, sondern vielmehr eine Begrenzung von der Größe.

In einem Haufen werden die Daten vom Programm gespeichert, deren Größe möglicherweise beim Programmstart noch nicht bekannt ist. Der Haufen kann nach selbst geschriebenen Prozeduren verwaltet werden.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument aufgelistet, in welchem allgemeine Informationen über die Funktionen von einem Betriebssystem enthalten sind. In diesem Dokument sind auch allgemeine Informationen über das Speicherverwaltungskonzept "Haufen" enthalten.

Im selben Kapitel ist auch ein Dokument über die Funktionen vom Betriebssystem "Windows" aufgelistet. In diesem Dokument ist beschrieben, wie die Haufengröße zur Laufzeit geändert werden kann.

Bei der Bedeutung von diesem Feld ist der Haufen gemeint, welcher
  • automatisch mit der Hilfe vom Lade-Programm erzeugt wird und
  • der Anwendung zugewiesen wird.
Ein Programm kann allerdings zusätzliche Haufen erzeugen, wenn es dies wünscht. Weitere Informationen hierzu sind im Dokument über die Funktionen vom Betriebssystem "Windows" enthalten.

In allen Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "10 00 00|h" gespeichert. Also 1 Megabyte.

Wenn
  • ich das soweit richtig gesehen habe,
dann
  • wertet das Lade-Programm diesen Wert nicht aus. Es erzeugt stattdessen einen Haufen, dessen Wachstum nicht begrenzt wird.

Wenn
  • hier der Wert "0|h" angegeben wird,
dann
  • funktioniert die Anwendung trotzdem und der Haufen kann auch benutzt werden.

Bei einer Bibliothek wird dieses Feld vermutlich auch deshalb nicht ausgewertet, weil Bibliotheken den Haufen von der Anwendung mitbenutzen.
SizeOfHeapReserve 4 Byte 00 00 00 00 80 Byte
bis
83 Byte
104 Byte
bis
107 Byte
Gemäß der Dokumentation von Microsoft entsteht etwas der Eindruck, dass mit der Hilfe von diesem Feld die Größe vom Haufen angeben würde, welche er beim Programmstart im physikalischen Arbeitsspeicher belegen soll. Tatsächlich ist es vielmehr so, dass der Speicherbereich nur vorgemerkt ist und die entsprechenden RAM-Seiten erst beim ersten Zugriff darauf physikalischen Arbeitsspeicher belegen.

In den ausführbaren Dateien, welche ich mir angeschaut hatte, war hier immer der Wert "10 00|h" (also 4 Kilobyte) gespeichert.

Wenn
  • hier der Wert "0|h" angegeben wird,
dann
  • funktioniert die Anwendung trotzdem und der Haufen kann auch benutzt werden.

Wo der vorgemerkte Speicherbereich im Segment beginnt, kann nach meiner Kenntnis mit der Hilfe von
  • der Funktion "HeapWalk" aus der Bibliothek "kernel32.dll" und
  • entsprechend unverhältnismäßig viel Aufwand herausgefunden werden.

Wegen dem hohen Aufwand, welcher notwendig ist, um herauszufinden, wo der Speicherbereich beginnt, empfehle ich für dieses Feld den Wert "0|h" zu verwenden und während der Laufzeit von der Anwendung bei Bedarf den Haufen um eine angemessene Größe wachsen zu lassen.
SizeOfHeapCommit 4 Byte 00 00 00 00 84 Byte
bis
87 Byte
108 Byte
bis
111 Byte
Diese Byte sind unbenutzt.

Microsoft empfiehlt, alle Bits auf "0" zu setzen.
LoaderFlags 4 Byte 00 00 00 00 88 Byte
bis
91 Byte
112 Byte
bis
115 Byte
Diese Byte geben die Anzahl der Einträge im Tabellenverzeichnis für verschiedene Tabellen an.

In allen Dateien, welche ich mir angeschaut hatte, ist hier der Wert "10|h = 16|d" gespeichert.

Microsoft hat für diesen Wert, also den Wert "16|d", die Konstante "IMAGE_NUMBEROF_DIRECTORY_ENTRIES" in der Kopfdatei "windows.inc" im "Microsoft Windows software development kit" definiert.
NumberOfRvaAndSizes 4 Byte 10 00 00 00 92 Byte
bis
95 Byte
116 Byte
bis
119 Byte
Gesamtgröße: 96 Byte

Bezeichnung
Die zusätzliche Kopfzeile wird von Microsoft "optionale Kopfzeile 32" (im Englischen: "optional header 32") genannt.

Position
Die Position vom 0. Byte vom Windows-Abschnitt wurde im Feld "e_lfanew" vom Abschnitt "Offset zum Windows-Abschnitt" vom DOS-Abschnitt angegeben. Das ist der Offset zum Windows-Abschnitt.

Die zusätzliche Kopfzeile vom der Kopfzeile vom Windows-Abschnitt beginnt dort, wo das 24. Byte vom Windows-Abschnitt ist.

Somit kommt die zusätzliche Kopfzeile direkt nach der Datei-Kopfzeile, also ohne unbenutzte Bytes zwischen

Tabellenverzeichnis für verschiedene Tabellen
Zweck
In den Programmabschnitt-Inhalten können Tabellen vorkommen, auf welche das Lade-Programm zugreifen muss. Das Tabellenverzeichnis für verschiedene Tabellen listet einige von diesen Tabellen auf und macht über die einzelnen Tabellen jeweils eine Auskunft über
  • die Position und manchmal auch
  • die Größe
von der jeweiligen Tabelle.

Manche Tabellen, wie zum Beispiel kommen allerdings nicht im Tabellenverzeichnis für verschiedene Tabellen vor.

Die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode kann mehrmals in einer Datei vorkommen, denn für jede Bibliothek, aus welcher die Datei etwas importieren möchte, ist eine Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode notwendig. Es gibt allerdings nur 1 Eintrag für alle Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode im Tabellenverzeichnis für verschiedene Tabellen.

Wo diese Tabellen sind, wird im Tabellenverzeichnis für Import-Tabellen angegeben und wie groß die jeweilige Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode ist kann man daran erkennen, dass man das Ende von der Tabelle erkennen kann. Der Eintrag für "die" Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode im Tabellenverzeichnis für verschiedene Tabellen ist also hinfällig. Er existiert aber trotzdem.

In manchen Dateien, welche ich mir angeschaut hatte, waren bei diesem Eintrag alle Bits auf "0" gesetzt. Wenn
  • man diesen Eintrag mit echten Werten füllen wollte,
dann

Aufbau
Das Tabellenverzeichnis für verschiedene Tabellen ist eine Folge von Einträgen. Die Einträge kommen direkt hintereinander und jeder Eintrag bezieht sich jeweils auf 1 spezifische Tabelle.

Im Tabellenverzeichnis für verschiedene Tabellen ist Der Programmierer kann nicht einfach etwas anderes als das Tabellenverzeichnis für Export-Tabellen an der 0. Stelle im Verzeichnis platzieren. Das Lade-Programm erwartet dort das Tabellenverzeichnis für Export-Tabellen. Somit ist für jeden Eintrag im Verzeichnis angegeben, welche spezifische Tabelle dieser Eintrag definiert, ohne dass die Tabelle genannt werden muss.

Jede spezifische Tabelle, außer der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode, kann nur 1 mal in der Datei vorkommen und kommt daher auch nur 1 mal in diesem Verzeichnis vor.

Jeder Eintrag besteht aus 2 Feldern:
  1. Das 0. Feld ist gibt den Offset zu dieser Tabelle an und
  2. das 1. Feld ist gibt die Größe von dieser Tabelle an.

Wenn dann
  • werden alle Bits von diesem Eintrag auf "0" gesetzt. Somit hat man auch die Größe von diesem Tabellenverzeichnis als "0 Byte" angegeben.

Wenn dann
  • kann der nachfolgende Eintrag, also der 2. Eintrag, die Tabelle für Ressourcen, ganz normal nach dem 1. definiert werden, indem dieses Mal die tatsächlichen Werte für den Offset und die Größe angegeben werden.

Wenn
  • beispielsweise die 3. Tabelle, und alle nachfolgenden bis zur letzten Tabelle, nicht benutzt werden sollen,
dann
  • kann die Größe vom Tabellenverzeichnis für verschiedene Tabellen auf 3 Einträge begrenzt werden.

    Die Größe vom Tabellenverzeichnis für verschiedene Tabellen wird mit der Hilfe vom letzten Feld "NumberOfRvaAndSizes" von der zusätzlichen Kopfzeile definiert.

Es scheint üblich zu sein, dieses Tabellenverzeichnis für verschiedene Tabellen 16 Einträge groß zu machen, und dann alle Bits vom letzten Eintrag auf "0" zu setzten, da nicht definiert ist, welche Tabelle an dieser Position steht. Somit ergibt sich
Wenn
  • man sein Tabellenverzeichnis für verschiedene Tabellen "16 Einträge"-groß macht,
dann
  • haben die einzelnen Einträge die im nachfolgenden aufgelisteten Bedeutungen.
Ansonsten
  • fallen entsprechend die letzten Einträge weg.

Aufbau vom Eintrag: betroffene Tabelle:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Mit der Hilfe von diesem Feld wird der Offset zur Tabelle im Segment in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches die Tabelle im Segment belegen soll.
VirtualAddress 4 Byte 0 Byte
bis
3 Byte
120 Byte
bis
123 Byte
Mit der Hilfe von diesem Feld wird die Größe von der Tabelle in Byte angegeben.

Das Lade-Programm von Windows wertet dieses Feld nicht aus. Ich empfehle daher, um sich unnötigen Aufwand zu sparen, alle Bits auf "0" zusetzen.
Size 4 Byte 4 Byte
bis
7 Byte
124 Byte
bis
127 Byte
Gesamtgröße: 8 Byte
Tabellenverzeichnis für Export-Tabellen
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 8 Byte
bis
11 Byte
128 Byte
bis
131 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 12 Byte
bis
15 Byte
133 Byte
bis
135 Byte
Gesamtgröße: 8 Byte
Tabellenverzeichnis für Import-Tabellen
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 16 Byte
bis
19 Byte
136 Byte
bis
139 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 20 Byte
bis
23 Byte
140 Byte
bis
143 Byte
Gesamtgröße: 8 Byte
Tabelle für Ressourcen
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 24 Byte
bis
27 Byte
144 Byte
bis
147 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 28 Byte
bis
31 Byte
148 Byte
bis
151 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Mit der Hilfe von diesem Feld wird der Offset zur Tabelle in der Datei in Byte angegeben,
  • vom Anfang der Datei aus gerechnet,
  • bis zum ersten Byte, welches die Tabelle in der Datei belegt.
VirtualAddress (?) 4 Byte 32 Byte
bis
35 Byte
152 Byte
bis
155 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 36 Byte
bis
39 Byte
156 Byte
bis
159 Byte
Gesamtgröße: 8 Byte
Zertifikate-Tabelle
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Mit der Hilfe von diesem Feld wird der Offset zur ersten Tabelle im Segment in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches die erste Tabelle im Segment belegen soll.
VirtualAddress 4 Byte 40 Byte
bis
43 Byte
160 Byte
bis
163 Byte
Mit der Hilfe von diesem Feld wird die Größe von allen Tabellen für Adressen-Reparaturen zusammengerechnet in Byte angegeben.

Das Lade-Programm von Windows wertet dieses Feld aus.
Size 4 Byte 44 Byte
bis
47 Byte
164 Byte
bis
167 Byte
Gesamtgröße: 8 Byte
Tabelle für Adressen-Reparaturen
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 48 Byte
bis
51 Byte
168 Byte
bis
171 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 52 Byte
bis
55 Byte
172 Byte
bis
175 Byte
Gesamtgröße: 8 Byte
Tabelle für eine Fehlersuche
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Dieses Feld ist unbenutzt.

Microsoft empfiehlt, alle Bits auf "0" zu setzen.
VirtualAddress und Size 8 Byte 56 Byte
bis
63 Byte
176 Byte
bis
183 Byte
Gesamtgröße: 8 Byte
- unbenutzt -
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 64 Byte
bis
67 Byte
184 Byte
bis
187 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 68 Byte
bis
71 Byte
188 Byte
bis
191 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 72 Byte
bis
75 Byte
192 Byte
bis
195 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 76 Byte
bis
79 Byte
196 Byte
bis
199 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 80 Byte
bis
83 Byte
200 Byte
bis
203 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 84 Byte
bis
87 Byte
204 Byte
bis
207 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 88 Byte
bis
91 Byte
208 Byte
bis
211 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 92 Byte
bis
95 Byte
212 Byte
bis
215 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Dieser Eintrag ist eigentlich unbenutzt, da es mehrere Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode geben kann. Deren
Ich empfehle daher alle Bits auf "0" zu setzen.

Ich habe allerdings schon in einer Datei gesehen, dass
Das Lade-Programm von Windows wertet diese Werte jedenfalls nicht aus.
VirtualAddress und Size 8 Byte 96 Byte
bis
103 Byte
216 Byte
bis
223 Byte
Gesamtgröße: 8 Byte
Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 104 Byte
bis
107 Byte
224 Byte
bis
227 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 108 Byte
bis
111 Byte
228 Byte
bis
231 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
siehe: die Beschreibung vom Feld "VirtualAddress" vom 0. Eintrag VirtualAddress 4 Byte 112 Byte
bis
115 Byte
232 Byte
bis
235 Byte
siehe: die Beschreibung vom Feld "Size" vom 0. Eintrag Size 4 Byte 116 Byte
bis
119 Byte
236 Byte
bis
239 Byte
Gesamtgröße: 8 Byte
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von
dem Tabellenverzeichnis: dem Windows-Abschnitt:
Dieses Feld ist unbenutzt.

Microsoft empfiehlt, alle Bits auf "0" zu setzen.
VirtualAddress und Size 8 Byte 120 Byte
bis
127 Byte
240 Byte
bis
247 Byte
Gesamtgröße: 8 Byte
- unbenutzt -

Die Beschreibungen von den Inhalten von den einzelnen Tabellen, kommen in dieser Dokumentation in den Programmabschnitt-Inhalten im Unterkapitel "Tabellen".

Bezeichnung
Das Tabellenverzeichnis für verschiedene Tabellen wird von Microsoft "Datenverzeichnisse" (im Englischen: "data directories") genannt.

Microsoft sieht das Tabellenverzeichnis für verschiedene Tabellen als einen Teil von der zusätzlichen Kopfzeile an. Hierdurch erhält die zusätzlichen Kopfzeile, wegen der variablen Eintragsanzahl in diesem Verzeichnis, eine variable Größe.

Ich sehe das Tabellenverzeichnis für verschiedene Tabellen als einen eigenständigen Teil von der Kopfzeile vom Windows-Abschnitt an. Somit hat für mich die zusätzliche Kopfzeile eine feste Größe von 96 Byte und lediglich die Größe vom Tabellenverzeichnis für verschiedene Tabellen ist variabel.

Hinweise bezüglich dem Betriebssystem "Windows 2000"
In älteren Versionen vom Betriebssystem "Windows 2000" muss ein Eintrag für das Tabellenverzeichnis für Import-Tabellen existieren. Mit der Hilfe vom Tabellenverzeichnis für Import-Tabellen muss die Bibliothek "kernel32.dll" geladen werden und es muss mindestens 1 Funktion importiert werden.

Wenn
  • die Bibliothek "kernel32.dll" nicht geladen wird,
dann
  • wird das Lade-Programm von Windows abstürzen, da es versuchen wird, eine Funktion von dieser Bibliothek zu benutzen.

In allen anderen Versionen von Windows läd das Lade-Programm diese Bibliothek selbstständig.

Der Fehler wurde zwischenzeitlich behoben und betrifft daher nur ältere Versionen vom Betriebssystem "Windows 2000". Leider weis ich nicht, mit
  • welcher Reparatur (im Englischen: "update") oder
  • welchem Reparatur-Bündel (im Englischen: "service pack")
dieser Fehler behoben wurde.

Hinweise bezüglich dem Betriebssystem "Windows experience"
Im Betriebssystem "Windows experience" muss ein Eintrag für die Tabelle für eine Fehlersuche existieren. Im Eintrag kann auch angeben sein, dass keine Tabelle für eine Fehlersuche existiert, indem von diesem Eintrag alle Bits auf "0" gesetzt werden. Auch wenn dann
  • muss dennoch der Eintrag für die Tabelle für eine Fehlersuche existieren.

Soweit ich weis, gibt es bisher noch keine Reparatur (im Englischen: "update"), um diesen Fehler zu beheben.

Ich habe soweit bei folgenden Versionen von Windows getestet, ob eine ausführbare Datei ohne "Tabelle für eine Fehlersuche"-Eintrag funktioniert:
läuft ohne "Tabelle für eine Fehlersuche"-Eintrag?: Version:
ja Windows 2000 Professional
nein Windows experience Professional
ja Windows 7 Professional

Wie es bei anderen Versionen von Windows ist, weis ich nicht. (Notiz: Das sollte ich prüfen. Über einen Hinweis bin ich aber sehr dankbar.)

Wenn
  • Sie ein anderes Betriebssystem haben,
dann
Die Datei
Ein solcher Eintrag ist bei einer Bibliothek nicht notwendig.

Position
Die Position vom 0. Byte vom Windows-Abschnitt wurde im Feld "e_lfanew" vom Abschnitt "Offset zum Windows-Abschnitt" vom DOS-Abschnitt angegeben. Das ist der Offset zum Windows-Abschnitt.

Das Tabellenverzeichnis für verschiedene Tabellen von der Kopfzeile vom Windows-Abschnitt beginnt dort, wo das 120. Byte vom Windows-Abschnitt ist.

Somit kommt das Tabellenverzeichnis für verschiedene Tabellen direkt nach der zusätzlichen Kopfzeile, also ohne unbenutzte Bytes zwischen
Soweit wurden zwar die Positionen von den Tabellen jeweils mit der Hilfe von einem Eintrag angegeben; die Inhalte von den Tabellen kommen allerdings erst in den Inhalten von den Programmabschnitten und somit nach der Kopfzeilen-Tabelle von den Programmabschnitten.

Programmabschnitte

Kopfzeilen-Tabelle
Zweck
Diese Tabelle dient, um Angaben über die einzelnen Programmabschnitt-Inhalte zu machen, wie zum Beispiel
  • wo sie in der Datei beginnen, wenn sie noch auf der Festplatte/Diskette/CD/was auch immer sind,
  • wo sie beginnen sollen, wenn sie ins Segment geladen wurden,
  • wie groß sie sind und
  • welche Attribute (zum Beispiel "ausführbar" oder "beschreibbar") der Bereich vom Arbeitsspeicher erhalten soll, welcher durch den Programmabschnitt-Inhalt belegt ist.

Was der Inhalt von einem Programmabschnitt ist, wird also in dieser Tabelle nicht angegeben.

Aufbau
In der Kopfzeilen-Tabelle ist für jeden Programmabschnitt-Inhalt von der Datei eine Kopfzeile.

Jede Kopfzeile ist "40 Byte"-groß. Zwischen den einzelnen Kopfzeilen dürfen keine unbenutzten Byte sein.

Die Anzahl der Kopfzeilen in dieser Tabelle wurde im Feld "NumberOfSections" von der Datei-Kopfzeile vom Kopfzeilen-Abschnitt vom Windows-Abschnitt definiert. Hierdurch ist das Ende von dieser Tabelle bekannt.

Die einzelnen Kopfzeilen in dieser Tabelle müssen anhand von der Anfangsadresse vom Programmabschnitt-Inhalt im Segment sortiert sein. Das heißt, dass der Programmabschnitt-Inhalt mit der niedrigsten Anfangsadresse als erstes in der Kopfzeilen-Tabelle kommen muss.

Die Kopfzeilen bestehen jeweils aus mehreren Einträgen, die Auskünfte über den jeweiligen Inhalt vom Programmabschnitt machen. Der Aufbau von einer solchen Kopfzeile sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang von der Kopfzeile:
Mit der Hilfe von diesem Feld wird eine Zeichenkette angegeben, welche den Namen vom Programmabschnitt festlegt.

Laut
  • einem Mitarbeiter von Microsoft handelt es sich um eine "ASCII"-kodierte Zeichenkette.
  • der offiziellen Spezifikationsbeschreibung vom Dateiformat von Microsoft handelt es sich um eine "UTF-8"-kodierte Zeichenkette.
Dem Anschein nach wurde die Kodierung mit der Zeit auf "UTF-8" geändert.

"ASCII" ist aufwärtskompatibel zu "UTF-8". Das heißt, solange man "ASCII"-Zeichen verwendet, haben diese
  • sowohl gemäß der "ASCII"-Kodierung,
  • als auch gemäß der "UTF-8"-Kodierung
die selben Werte.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument über diese Zeichenkodierungen aufgelistet.

Das Lade-Programm von Windows orientiert sich nicht an diesem Namen um festzustellen, welcher Inhalt in diesem Programmabschnitt ist. In einem Programmabschnitt können ohnehin mehrere unterschiedliche Inhalte sein, welche lediglich gemeinsame Attribute im Arbeitsspeicher haben, also zum Beispiel
  • "ausführbar" oder
  • "beschreibbar".

Das Namens-Feld sollte nicht komplett frei gelassen werden und jeder Name sollte nur 1 mal vorkommen. Das fordert weder das Lade-Programm von Windows noch das Dateiformat "portable executable" ("pe"). In der Praxis ist es allerdings so, dass es Programme gibt, welche diese Namen verwenden. Beispielsweise kann das Entpackungsprogramm "7-Zip" aus
  • ausführbaren Dateien und
  • Bibliotheken
für Windows die einzelnen Programmabschnitt-Inhalte auslesen jeweils als eine Datei abspeichern. Als Dateiname wird der Name vom Programmabschnitt verwendet.

Der Name kann maximal 8 Byte lang sein. Wenn
  • er beispielsweise nur 5 Byte lang sein soll,
dann
  • sind die Byte "0 bis 4" mit Zeichen zu füllen und alle Bits von den Byte "5 bis 7" auf "0" zu setzen.

Um einen nützlichen Namen zu wählen, können berücksichtigt werden.
Name 8 Byte 0 Byte
bis
7 Byte
Mit der Hilfe von diesem Feld wird die Anzahl der genutzten Byte vom Inhalt vom Programmabschnitt angegeben, wenn er ins Segment geladen wurde.

Wenn dann
  • werden die Bits von den restlichen Bytes vom Lade-Programm auf "0" gesetzt.

In Dateien, welche ich mir angeschaut hatte, war hier oft der Wert "10 00|h" eingetragen. Also der selbe Wert, wie die konstante Größe für 1 Seite von einem Programmabschnitt-Inhalt im Segment. Hier waren
  • manchmal niedrigere Werte und
  • manchmal höhere Werte, wie zum Beispiel der Wert "1B A8|h = 7.080|d", wodurch 2 Seiten für einen Programmabschnitt-Inhalt im Segment notwendig sind,
eingetragen.

Laut Bernd Luevelsmeyer würden manche Link-Programme hier
  • falsche Werte eintragen oder
  • die 32 Bits alle auf "0" setzen.
Dennoch würden die entsprechenden ausführbaren Dateien, welche er sich angeschaut hat, in Windows laufen. Auch nach meinen eigenen Tests scheint dieses Feld vom Lade-Programm nicht ausgewertet zu werden.
VirtualSize 4 Byte 8 Byte
bis
11 Byte
Mit der Hilfe von diesem Feld wird der Offset zum Inhalt vom Programmabschnitt im Segment in Byte angegeben,
Dieser Wert muss ein Vielfaches vom Wert im Feld "SectionAlignment" von der zusätzlichen Kopfzeile sein, welcher eine konstante Größe für jede Seite von den Programmabschnitt-Inhalten angegeben wird, wenn sie ins Segment geladen wurden. Also in der Regel ein Vielfaches von 4 Kilobyte ("10 00|h").

Die einzelnen Programmabschnitt-Inhalte müssen direkt hintereinander kommen. Also nach dem Ende von einem Programmabschnitt-Inhalt und vor dem Anfang vom nächsten Programmabschnitt-Inhalt dürfen keine weiteren unbenutzte Byte sein. In einem Programmabschnitt-Inhalt können allerdings durchaus unbenutzte Byte sein. Es geht lediglich darum, dass zu dem Wert im Feld "SectionAlignment" von der zusätzlichen Kopfzeile kein zusätzlicher Offset entsteht.
VirtualAddress 4 Byte 12 Byte
bis
15 Byte
Mit der Hilfe von diesem Feld wird die Größe in Byte angegeben, von allen einzelnen Seiten vom Programmabschnitt-Inhalt zusammengerechnet, wenn sie noch in der Datei auf der Festplatte/Diskette/CD/was auch immer sind.

Dieser Wert muss ein Vielfaches vom Wert im Feld "FileAlignment" von der zusätzlichen Kopfzeile sein, welcher eine konstante Größe für jede Seite von den Programmabschnitt-Inhalten angibt, solange sie noch in der Datei sind. Also in der Regel ein Vielfaches von 512 Byte ("2 00|h").

In ausführbaren Dateien, welche ich mir angeschaut hatte, war hier
  • manchmal der Wert "2 00|h = 512|d" und
  • manchmal der Wert "4 00|h = 1.024|d"
eingetragen. In der ausführbaren Datei, welche bei einem Programmabschnitt-Inhalt angegeben hatte, dass er 7.080 Byte im Segment belegt, war hier angegeben, dass er 2.048 Byte auf der Festplatte belegt.

Auch in ausführbaren Dateien, welche sich andere Leute angeschaut haben, waren hier
  • manchmal größere Werte und
  • manchmal kleinere Werte
angegeben, als im Feld "VirtualSize" angegeben war, wo die Anzahl der genutzten Byte vom Inhalt vom Programmabschnitt angegeben wird, wenn er ins Segment geladen wurde.

Wenn
  • der Wert aus diesem Feld, also die Anzahl der genutzten Byte auf der Festplatte, größer ist, als die Anzahl der genutzten Byte im Segment,
dann
  • liegt das daran, dass dieser Wert aufgerundet wird, während die Anzahl der genutzten Byte im Segment nicht aufgerundet werden.

Ansonsten wenn
  • der Wert aus diesem Feld kleiner ist, als die Anzahl der genutzten Byte im Segment,
dann
  • kann das daran liegen, dass
    • der Inhalt vom Programmabschnitt im Segment auch Daten enthalten kann, deren Größe zwar beim Programmstart bekannt ist, welche aber erst zur Laufzeit zum ersten Mal mit Werten definiert werden. Da alle Bits von diesen Daten vom Lade-Programm auf "0" gesetzt werden, muss lediglich die Anzahl dieser Byte in der Datei angegeben werden. Die Nullen kommen aber nicht in der Datei auf der Festplatte/Diskette/CD/was auch immer vor.
    • eine Seite von einem Inhalt im Segment oft größer ist, als eine Seite von einem Inhalt auf der Festplatte/Diskette/CD/was auch immer. Somit sind in der letzten Seite im Segment meistens mehr Byte unbenutzt.

Dieser Wert wird vom Lade-Programm ausgewertet. Wenn
  • es sich um
    • eine ausführbare Datei ("*.exe"-Datei) oder
    • eine Bibliothek ("*.dll"-Datei)
    handelt,
dann
  • akzeptiert es das Lade-Programm allerdings auch, wenn anstatt dem aufgerundeten Wert, nur die tatsächlich genutzten Bytes angegeben werden. In diesem Fall kann
    • allerdings das Entpackungsprogramm "7-Zip" die einzelnen Programmabschnitt-Inhalte nicht mehr aus der Datei extrahieren.
    • auf unbenutzte Bytes vom letzten Programmabschnitt-Inhalte verzichtet werden, sodass die Dateigröße ein bischen geringer ist.
Ansonsten wenn
  • es sich um einen Treiber ("*.sys"-Datei) handelt
dann
  • akzeptiert das Lade-Programm nur den aufgerundeten Wert.
  • müssen alle unbenutzten Bytes vom letzten Programmabschnitt-Inhalte in der Datei vorhanden sein.
SizeOfRawData 4 Byte 16 Byte
bis
19 Byte
Mit der Hilfe von diesem Feld wird der Offset zum Programmabschnitt-Inhalt in Byte angegeben, wenn er noch in der Datei auf der Festplatte/Diskette/CD/was auch immer ist,
  • vom Anfang von der Datei aus gerechnet,
  • bis zum ersten Byte, welches der Programmabschnitt-Inhalt in der Datei belegt.

Dieser Wert muss ein Vielfaches vom Wert im Feld "FileAlignment" von der zusätzlichen Kopfzeile sein, welcher eine konstante Größe für jede Seite von den Programmabschnitt-Inhalten angibt, solange sie noch in der Datei sind. Also in der Regel ein Vielfaches von 512 Byte ("2 00|h").

Wenn
  • der komplette Inhalt vom Programmabschnitt dafür vorgesehen ist, Platz für Daten zu reservieren, deren Größe zwar beim Programmstart bekannt ist, welche aber erst zur Laufzeit zum ersten Mal mit Werten definiert werden,
dann
  • sind alle Bits von diesem Wert auf "0|b" zu setzen.

Somit müssen die Null-Bytes, welche das Lade-Programm im Segment erzeugen wird, nicht in der Datei vorkommen, da der Inhalt vom Programmabschnitt lediglich
  • im Segment und nicht
  • in der Datei
vorkommt.

In ausführbaren Dateien, welche ich mir angeschaut hatte, war hier für den ersten Programmabschnitt-Inhalt
  • manchmal der Wert "4 00|h" und
  • manchmal der Wert "6 00|h"
eingetragen.

In Bibliotheken, welche ich mir angeschaut hatte, war hier für den ersten Programmabschnitt-Inhalt
  • manchmal der Wert "4 00|h" und
  • manchmal der Wert "10 00|h"
eingetragen.
PointerToRawData 4 Byte 20 Byte
bis
23 Byte
Wenn dann
  • kann dieses Feld benutzt werden, um den Offset zur Auflistung von den Einträgen/Adressen-Reparatur-Anweisungen von einer Tabelle für Adressen-Reparaturen in Byte anzugeben, wenn sie noch in der Datei auf der Festplatte/Diskette/CD/was auch immer ist,
    • vom Anfang von der Datei aus gerechnet,
    • bis zum ersten Byte, welches die Auflistung von den Einträgen in der Datei belegt.

Mit der Hilfe von diesem Feld kann nur 1 Auflistung von Einträgen angegeben werden. Für manche Programmabschnitt-Inhalte werden allerdings mehrere Tabellen für Adressen-Reparaturen benötigt.

Da das Feld "NumberOfRelocations" nicht mehr benutzt wird, kann es sein, dass dieses Feld "PointerToRelocations" ebenfalls nicht mehr benutzt wird.

Ich empfehle daher alle Bits auf "0" zu setzen, um anzugeben, dass keine solche Auflistung von Einträgen in diesem Programmabschnitt-Inhalt ist und stattdessen den Eintrag im Tabellenverzeichnis für verschiedene Tabellen zu benutzen.
PointerToRelocations 4 Byte 24 Byte
bis
27 Byte
Diese Felder sind unbenutzt.

Microsoft empfiehlt, alle Bits auf "0" zu setzen.
PointerToLinenumbers 4 Byte 28 Byte
bis
31 Byte
NumberOfRelocations 2 Byte 32 Byte
bis
33 Byte
NumberOfLinenumbers 2 Byte 34 Byte
bis
35 Byte
Die einzelnen Bits von diesem Feld machen Auskünfte, wie zum Beispiel darüber, mit welcher Art von Inhalten der Programmabschnitt-Inhalt gefüllt ist.

In allen Dateien, welche ich mir angeschaut hatte, war hier für den ersten Programmabschnitt-Inhalt diese Bitfolge gespeichert:
Wert: 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
Wertigkeit: 231 230 229 228 227 226 225 224 223 222 221 220 219 218 217 216 215 214 213 212 211 210 29 28 27 26 25 24 23 22 21 20

Die Bedeutungen von den einzelnen Bits sind wie folgt:
allgemeine Beschreibung: Bedeutung wenn Wert=="0": Bedeutung wenn Wert=="1": Bezeichnung: Wertigkeiten:
Diese Bits werden nicht benutzt.

Ein Mitarbeiter von Microsoft empfiehlt, diese Bits auf "0" zu setzen.
20
bis
22
IMAGE_SCN_TYPE_NO_PAD 23
24
Mit der Hilfe von diesem Bit wird angegeben, ob im Programmabschnitt-Inhalt ausführbarer Code enthalten ist.

Siehe auch: das Bit mit der Wertigkeit "229"
Im Programmabschnitt-Inhalt ist kein ausführbarer Code enthalten. Im Programmabschnitt-Inhalt ist ausführbarer Code enthalten. IMAGE_SCN_CNT_CODE 25
Mit der Hilfe von diesem Bit wird angegeben, ob im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind. Im Programmabschnitt-Inhalt sind keine solche Daten enthalten. Im Programmabschnitt-Inhalt sind solche Daten enthalten. IMAGE_SCN_CNT_INITIALIZED_DATA 26
Mit der Hilfe von diesem Bit wird angegeben, ob im Programmabschnitt-Inhalt Daten enthalten sind, von welchen zwar beim Programmstart bereits die Größe bekannt ist, welche aber erst zur Laufzeit zum ersten Mal mit Werten definiert werden. Im Programmabschnitt-Inhalt sind keine solche Daten enthalten. Im Programmabschnitt-Inhalt sind solche Daten enthalten.

Wenn dann
  • werden in diesem Fall automatisch alle Bits von diesem gesamten Programmabschnitt-Inhalt auf "0" gesetzt. Anschließend müssten dann alle andere Inhalte in diesen Programmabschnitt-Inhalt geladen werden, so dass der Rest-Bereich für die nicht definierten Daten noch immer mit Null-Bytes gefüllt ist.
IMAGE_SCN_CNT_UNINITIALIZED_DATA 27
Diese Bits werden nicht benutzt.

Ein Mitarbeiter von Microsoft empfiehlt, diese Bits auf "0" zu setzen.
IMAGE_SCN_LNK_OTHER 28
IMAGE_SCN_LNK_INFO 29
210
IMAGE_SCN_LNK_REMOVE 211
IMAGE_SCN_LNK_COMDAT 212
213
bis
214
Leider konnte ich hier noch nicht zufriedenstellend klären, wofür dieses Bit verwendet wird. (Notiz: das sollte ich prüfen) IMAGE_SCN_GPREL 215
Dieses Bit wird nicht benutzt.

Ein Mitarbeiter von Microsoft empfiehlt, dieses Bit auf "0" zu setzen.
IMAGE_SCN_MEM_PURGEABLE (?) 216
Mit der Hilfe von diesem Bit wird angegeben, ob in diesem Programmabschnitt-Inhalt Maschinencode aus dem thumb-Befehlssatz enthalten ist.

Der thumb-Befehlssatz kann in CPUs mit ARM-Architektur verwendet werden. Also nicht in den x86er-CPUs.

Er ermöglicht,
  • anstatt der standardmäßigen Verwendung von "4 Byte"-großen Adressangaben, wie dies beim regulären ARM-Befehlssatz der Fall ist,
  • stattdessen die standardmäßige Verwendung von "2 Byte"-großen Adressangaben.
Somit können Programme mit kürzerem Maschinencode auskommen.
Im Programmabschnitt-Inhalt ist kein Maschinencode aus dem thumb-Befehlssatz enthalten. Im Programmabschnitt-Inhalt ist Maschinencode aus dem thumb-Befehlssatz enthalten. IMAGE_SCN_MEM_16BIT 217
Diese Bits werden nicht benutzt.

Ein Mitarbeiter von Microsoft empfiehlt, diese Bits auf "0" zu setzen.
IMAGE_SCN_MEM_LOCKED 218
IMAGE_SCN_MEM_PRELOAD 219
Wenn
  • Wert==1|d,
dann
  • IMAGE_SCN_ALIGN_1BYTES.
Ansonsten wenn
  • Wert==2|d,
dann
  • IMAGE_SCN_ALIGN_2BYTES.
Ansonsten wenn
  • Wert==3|d,
dann
  • IMAGE_SCN_ALIGN_4BYTES.
Ansonsten wenn
  • Wert==4|d,
dann
  • IMAGE_SCN_ALIGN_8BYTES.
Ansonsten wenn
  • Wert==5|d,
dann
  • IMAGE_SCN_ALIGN_16BYTES.
Ansonsten wenn
  • Wert==6|d,
dann
  • IMAGE_SCN_ALIGN_32BYTES.
Ansonsten wenn
  • Wert==7|d,
dann
  • IMAGE_SCN_ALIGN_64BYTES.
Ansonsten wenn
  • Wert==8|d,
dann
  • IMAGE_SCN_ALIGN_128BYTES.
Ansonsten wenn
  • Wert==9|d,
dann
  • IMAGE_SCN_ALIGN_256BYTES.
Ansonsten wenn
  • Wert==10|d,
dann
  • IMAGE_SCN_ALIGN_512BYTES.
Ansonsten wenn
  • Wert==11|d,
dann
  • IMAGE_SCN_ALIGN_1024BYTES.
Ansonsten wenn
  • Wert==12|d,
dann
  • IMAGE_SCN_ALIGN_2048BYTES.
Ansonsten wenn
  • Wert==13|d,
dann
  • IMAGE_SCN_ALIGN_4096BYTES.
Ansonsten wenn
  • Wert==14|d,
dann
  • IMAGE_SCN_ALIGN_8192BYTES.
220
bis
223
Die Bedeutung von diesem Bit ist in dieser Dokumentation nicht beschreiben. IMAGE_SCN_LNK_NRELOC_OVFL 224
Mit der Hilfe von diesem Bit wird angegeben, ob der Bereich vom physikalischen Arbeitsspeicher, welcher von diesem Programmabschnitt-Inhalt belegt wird, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

Diese Freigabe kann beispielsweise für einen Programmabschnitt-Inhalt gegeben werden, welcher lediglich Tabellen für Adressen-Reparaturen enthält. Diese Tabellen enthalten Informationen, welche das Lade-Programm von Windows einmalig benötigt. Während der Laufzeit vom Programm wird diese Tabelle allerdings nicht benötigt. Sie hätte also nie in den Arbeitsspeicher geladen werden müssen.

Bernd Luevelsmeyer nennt hier außerdem das Tabellenverzeichnis für Import-Tabellen und Startroutinen, welche nur ein einziges Mal ausgeführt werden müssen.

Meine Vermutungen und derzeitiges Verständnis von den Auswirkungen enthalten Folgendes:
Wenn
  • das Betriebssystem den Bedarf hat, Inhalte aus dem physikalischen Arbeitsspeicher zu löschen,
dann
  • werden diese Programmabschnitt-Inhalte mit relativ hoher Wahrscheinlichkeit gewählt. Vermutlich wahrscheinlicher, als die Programmabschnitt-Inhalte, von welchen lediglich angegeben ist, dass sie in die Auslagerungsdatei ausgelagert werden dürfen.

Dieser Bedarf entsteht,
  • wenn der physikalische Arbeitsspeicher soweit gefüllt ist, dass ein weiterer Inhalt nicht mehr aufgenommen werden kann oder
  • wenn der Computer in den "Ruhezustand" (im Englischen: "hibernation") gefahren wird.

    In diesem Fall scheint das Betriebssystem diese Programmabschnitt-Inhalte ebenfalls zu löschen, anstatt sie auf die Festplatte zu speichern.

Wenn dann
  • kopiert das Lade-Programm die Daten, so wie sie in der Datei gespeichert sind, in den physikalischen Arbeitsspeicher und macht diesen Teil vom physikalischen Arbeitsspeicher wieder zum Teil vom Segment.
(Notiz: diese Information gilt als ungesichert)

Wenn dann
  • gehen auf diese Weise die Änderungen verloren.
(Notiz: das Obige gilt nur, wenn die Annahme für den vorherigen Absatz korrekt ist)
Der Bereich vom physikalischen Arbeitsspeicher darf nicht für andere Zwecke benutzt werden. Der Bereich vom physikalischen Arbeitsspeicher darf für andere Zwecke benutzt werden. IMAGE_SCN_MEM_DISCARDABLE 225
Leider konnte ich hier noch nicht zufriedenstellend klären, wofür dieses Bit verwendet wird. (Notiz: das sollte ich prüfen)

Bernd Luevelsmeyer:
If bit 26 (IMAGE_SCN_MEM_NOT_CACHED) is set [to "1"], the section's data should not be cached. Don't ask my why not. Does this mean to switch off the 2nd-level-cache?

Microsoft Corporation:
[If the bit is set to "1", then] the section cannot be cached.

Von dem was ich verstanden habe, sollte das Bit eher auf "0" als auf "1" gesetzt werden.
IMAGE_SCN_MEM_NOT_CACHED 226
Mit der Hilfe von diesem Bit wird angegeben, ob der Bereich vom physikalischen Speicher in die Auslagerungsdatei ausgelagert werden darf. Der Bereich darf in die Auslagerungsdatei ausgelagert werden. Der Bereich darf nicht in die Auslagerungsdatei ausgelagert werden. IMAGE_SCN_MEM_NOT_PAGED 227
Mit der Hilfe von diesem Bit wird angegeben, ob dieser Bereich vom Speicher von allen Instanzen von dieser Anwendung gemeinsam benutzt werden soll.

Wenn
  • man eine Anwendung mehrmals startet,
dann
  • nennt man jede laufende Anwendung eine Instanz.

Wenn
  • diese Freigabe beispielsweise für einen Programmabschnitt-Inhalt erteilt wird, welcher die Daten enthält, welche beim Programmstart bereits mit einem Wert definiert sein sollen,
dann
  • haben alle Instanzen einen Zugriff auf exakt die selben Werte. Das heißt, wenn
    • eine Instanz einen Wert ändert,
    dann
    • ist dieser für alle Instanzen geändert.

Diese Freigabe kann also auch physikalischen Speicher sparen.

Wenn
  • alle Instanzen auf den selben Bereich vom physikalischen Speicher zugreifen, um ihren Maschinencode auszuführen,
dann
  • müssen für diese Anwendung weniger Byte in den 2nd-level-cache vom CPU geladen werden. Dies kann das Ausführen von
    • den einzelnen Instanzen und
    • auch anderen Programme, welche nicht wegen Platzmangel aus dem Zwischenspeicher "2nd-level-cache" geschmissen werden,
    beschleunigen.
Jede Instanz soll seinen eigenen Bereich vom physikalischen Arbeitsspeicher für diesen Programmabschnitt-Inhalt bekommen. Alle Instanzen sollen den selben Bereich vom physikalischen Arbeitsspeicher für diesen Programmabschnitt-Inhalt verwenden. IMAGE_SCN_MEM_SHARED 228
Mit der Hilfe von diesem Bit wird angegeben, ob der Bereich vom Speicher von diesem Programmabschnitt-Inhalt vom Prozess ausgeführt werden darf.

Wenn
  • ich das richtig verstanden habe,
dann
  • müsste diese Freigabe immer dann erteilt werden, wenn ausführbarer Code in diesem Programmabschnitt-Inhalt vorhanden ist, welcher irgendwann während der Laufzeit ausgeführt werden soll.

Siehe auch: das Bit mit der Wertigkeit "25"
Dieser Bereich vom Speicher darf nicht vom Prozess ausgeführt werden. Dieser Bereich vom Speicher darf vom Prozess ausgeführt werden. IMAGE_SCN_MEM_EXECUTE 229
Mit der Hilfe von diesem Bit wird angegeben, ob der Bereich vom Speicher von diesem Programmabschnitt-Inhalt vom Prozess gelesen werden darf.

Wenn
  • Maschinencode ausgeführt werden soll,
dann
  • muss der Maschinencode gelesen werden. Diese Art von Lesezugriff zählt bei der x86-Architektur jedoch als ein Zugriff für eine Maschinencodeausführung und nicht als Lesezugriff.

    Bei manchen Maschinenbefehlen ist der Wert von einem von den Parametern als direkte Daten im Maschinencode gespeichert. Das Lesen von den direkten Daten für die Maschinencodeausführung zählt ebenfalls als ein Zugriff für eine Maschinencodeausführung und nicht als ein Lesezugriff.

    Alleine für die Ausführung von Maschinencode ist also noch kein Lesezugriff notwendig.

Wenn
  • im Maschinencode Adressen repariert werden sollen,
dann
  • ist es deshalb noch kein Lesezugriff notwendig.

    Das Lade-Programm weist in diesem Fall die notwendigen Zugriffsberechtigungen den RAM-Seiten zu, um die Adressen zu reparieren. Anschließend - also bevor die Anwendung die Kontrolle über den Prozessor erhält - werden die gewünschten Zugriffsberechtigungen gesetzt.
Dieser Bereich vom Speicher darf nicht vom Prozess gelesen werden. Dieser Bereich vom Speicher darf vom Prozess gelesen werden. IMAGE_SCN_MEM_READ 230
Mit der Hilfe von diesem Bit wird angegeben, ob der Bereich vom Speicher von diesem Programmabschnitt-Inhalt vom Prozess beschrieben werden darf.

Wenn
  • im Maschinencode Adressen repariert werden sollen,
dann
  • ist es deshalb noch kein Schreibzugriff notwendig.

    Das Lade-Programm weist in diesem Fall die notwendigen Zugriffsberechtigungen den RAM-Seiten zu, um die Adressen zu reparieren. Anschließend - also bevor die Anwendung die Kontrolle über den Prozessor erhält - werden die gewünschten Zugriffsberechtigungen gesetzt.
Dieser Bereich vom Speicher darf nicht vom Prozess beschrieben werden. Dieser Bereich vom Speicher darf vom Prozess beschrieben werden. IMAGE_SCN_MEM_WRITE 231
Characteristics 4 Byte 36 Byte
bis
39 Byte
Gesamtgröße: 40 Byte

Bezeichnung
Die Kopfzeilen-Tabelle wird von Microsoft "Abschnittstabelle" (im Englischen: "section table") genannt. Eine einzelne Kopfzeile nennt Microsoft "Abschnitts-Kopfzeile" (im Englischen: "section header").

Position
Die Position vom 0. Byte vom Windows-Abschnitt wurde im Feld "e_lfanew" vom Abschnitt "Offset zum Windows-Abschnitt" vom DOS-Abschnitt angegeben. Das ist der Offset zum Windows-Abschnitt.

Um die Position vom 0. Byte von der Kopfzeilen-Tabelle von den Programmabschnitten vom Windows-Abschnitt zu berechnen, muss zunächst das 120. Byte vom Windows-Abschnitt verwendet werden.

Zum 120. Byte muss ("Anzahl der Einträge im Tabellenverzeichnis für verschiedene Tabellen" * "8 Byte") hinzuaddiert werden.

Somit kommt die Kopfzeilen-Tabelle direkt nach dem Tabellenverzeichnis für verschiedene Tabellen, also ohne unbenutzte Bytes zwischen

Inhalte
Bezeichnung im Allgemeinen
Der Inhalt von einem Programmabschnitt wird von Microsoft "Abschnitt" (im Englischen: "section") genannt. Wenn
  • sich Microsoft beim Inhalt nicht auf den Block als solchen bezieht, sondern auf
    • den Maschinencode oder
    • die Werte von den Daten,
dann
  • verwendet Microsoft manchmal auch den Begriff "Rohdaten" (im Englischen: "raw data").

Gruppierung von den Rohdaten
Einige Linkprogramme platzieren verschiedene Rohdaten, welche eine thematische Zusammengehörigkeit haben, im selben Programmabschnitt-Inhalt. Beispielsweise wird oft im selben Programmabschnitt-Inhalt gespeichert.

In der Kopfzeilen-Tabelle wird allerdings anhand vom Bitfeld klar, dass sich ein Programmabschnitt-Inhalt darin von einem Anderen unterscheidet, dass der Bereich vom Speicher andere Attribute hat. Also zum Beispiel
  • "ausführbar",
  • "beschreibbar" oder/und
  • "lesbar".

können beispielsweise aus dem Arbeitsspeicher gelöscht werden, sodass der Bereich für andere Zwecke verwendet werden kann. Dies gilt aber nicht für die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode. Sie muss bestehen bleiben, damit das Programm auch weiterhin importierte Dinge aus externen Bibliotheken verwenden kann.

Ich empfehle daher, wenn
  • mehrere Programmabschnitt-Inhalte verwendet werden,
dann
  • hier
    • nicht nach thematischer Zusammengehörigkeit zu gruppieren,
    • sondern anhand von gemeinsamen Attributen.

Namensgebung von einem spezifischen Programmabschnitt
Mit der Hilfe von der Gruppierung von den Rohdaten anhand von gemeinsamen Attributen wird die weit verbreitete Namensgebung für die Programmabschnitt-Inhalte hinfällig. Es ist bereispielsweise relativ üblich,
  • den Programmabschnitt-Inhalt, welcher alle Export-bezüglichen Rohdaten enthält, ".edata" zu nennen und
  • den Programmabschnitt-Inhalt, welcher alle Import-bezüglichen Rohdaten enthält, ".idata" zu nennen.

Der Name vom Programmabschnitt-Inhalt kann im Feld "Name" von der Kopfzeilen-Tabelle angegeben werden und ist auf maximal 8 Zeichen begrenzt.

Dateiattribute werden in Linux oft in der Form "rwx" angegeben. Wobei hier für eine Datei auch "r-x" angegeben sein kann.
  • Das "r" steht für "eine Leseberechtigung ist gegeben" (im Englischen: "readable"),
  • das "w" steht für "eine Schreibeberechtigung ist gegeben" (im Englischen: "writeable") und
  • das "x" steht für "eine Ausführungsberechtigung ist gegeben" (im Englischen: "executable").
  • Das "-" im 2. Beispiel bedeutet, dass keine Schreibberechtigung für diese Datei gegeben ist.

In Anlehnung an dieses System könnte man das Namensfeld also in ähnlicher Weise für die Programmabschnitt-Inhalte benutzen:
  1. "d" im Namen bedeutet
    • "deletable" und
    • dass das Bit mit der Wertigkeit "225" auf "1" gesetzt ist,
    also, dass der Bereich vom physikalischen Arbeitsspeicher, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.
  2. "i" im Namen bedeutet
    • "containing initialized data" und
    • dass das Bit mit der Wertigkeit "26" auf "1" gesetzt ist,
    also, dass im Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
  3. "p" im Namen bedeutet
    • "pageable" und
    • dass das Bit mit der Wertigkeit "227" auf "0" gesetzt ist,
    also, dass der Bereich in die Auslagerungsdatei verschoben werden darf.
  4. "r" im Namen bedeutet
    • "readable" und
    • dass das Bit mit der Wertigkeit "230" auf "1" gesetzt ist,
    also, dass der Bereich gelesen werden darf.
  5. "s" im Namen bedeutet
    • "shareable" und
    • dass das Bit mit der Wertigkeit "228" auf "1" gesetzt ist,
    also, dass der Bereich vom Speicher von mehrere Instanzen benutzt wird, anstatt dass jede Instanz ihren eigenen Bereich vom Speicher bekommt.
  6. "u" im Namen bedeutet
    • "containing uninitialized data" und
    • dass das Bit mit der Wertigkeit "27" auf "1" gesetzt ist,
    also, dass im Inhalt Daten enthalten sind, deren Größe bereits beim Programmstart bekannt ist, welche aber erst zur Laufzeit zum ersten Mal mit Werten definiert werden.
  7. "w" im Namen bedeutet
    • "writeable" und
    • dass das Bit mit der Wertigkeit "231" auf "1" gesetzt ist,
    also, dass der Bereich beschrieben werden darf.
  8. "x" im Namen bedeutet
    • "executable" und
    • dass die Bits mit den Wertigkeiten jeweils auf "1" gesetzt sind,
    also, dass
    • ausführbarer Code vorhanden ist und
    • der Bereich vom Speicher ausgeführt werden darf.

So würden alle 8 Byte sinnvoll genutzt werden, indem jeweils an der Stelle
  • entweder der Buchstabe,
  • oder "-"
steht. Also zum Beispiel "--prs--x" als Name.

Position
Die Inhalte von den Programmabschnitten kommen in der Datei nach der Kopfzeilen-Tabelle. Allerdings nicht zwangsweise direkt danach. Stattdessen kommt jetzt in der Regel erstmal ein unbenutzter Bereich, von welchem alle Bits in der Datei auf "0" gesetzt sind.

Wo jeweils das erste Byte von einem Inhalt von der Kopfzeilen-Tabelle angegeben.

Tabellen
Position
Soweit wurden zwar die Positionen von den Tabellen aus dem Tabellenverzeichnis für verschiedene Tabellen jeweils mit der Hilfe von einem Eintrag angegeben; die Inhalte von den Tabellen kommen allerdings erst hier, in den Inhalten von den Programmabschnitten und somit nach der Kopfzeilen-Tabelle von den Programmabschnitten.

Export-Tabelle für Adressen von Dingen
Zweck
Diese Tabelle listet die Adressen von den Dingen auf, welche für einen möglichen Export markiert werden sollen.

Ein Ding für einen möglichen Export zu markieren bedeutet, dass eine Freigabe gegeben wird, dass andere Dateien dieses Ding importieren können. Nicht, dass der Export hierdurch bereits stattfindet.

Obwohl das Exportieren von Dingen hauptsächlich bei Bibliotheken verwendet wird, ist es auch möglich, Dinge von einer ausführbaren Datei zu exportieren.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für jedes Ding, welches für einen möglichen Export markiert werden sollen, wird ein Offset in diese Tabelle eingefügt. Die Export-Tabelle für Adressen von Dingen ist also lediglich eine Auflistung von Offsets.

Jeder Offset ist "4 Byte"-groß. Da die Anzahl der Einträge von dieser Tabelle im Tabellenverzeichnis für Export-Tabellen angegeben ist, ist es nicht notwendig, mit der Hilfe von zusätzlichen Bytes das Ende von dieser Tabelle zu markieren. Die Gesamtgröße ergibt sich also aus (Anzahl der Einträge) * "4 Byte".

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird der Offset zum Ding, welches für einen möglichen Export markiert werden soll, im Segment in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches das Ding im Segment belegen soll.

Wenn
  • dieses Ding Daten sind,
dann
  • wird mit der Hilfe vom Eintrag in dieser Tabelle angegeben, wo diese Daten beginnen.
Ansonsten wenn
  • dieses Ding eine Funktion ist,
dann
  • wird mit der Hilfe vom Eintrag in dieser Tabelle die Einsprungadresse angegeben.

Wenn dann
  • bedeutet dies, dass dieses Ding
    • nicht in dieser Datei,
    • sondern in einer anderen Datei
    ist.

    An diesem angegebenen Offset beginnt in diesem Fall stattdessen eine ASCII-kodierte Zeichenkette, welche durch ein weiteres Byte abgeschlossen ist, von welchem alle Bits auf "0" gesetzt sind.

    Die Zeichenkette gibt mit der Hilfe von ihrem Inhalt an,
    • wie die Bibliothek heißt, welche das Ding enthält, und
      • wie der Name von diesem Ding in dieser Bibliothek lautet, oder
      • wie die fortlaufende Nummer von diesem Ding in dieser Bibliothek lautet.

    Der Inhalt von dieser Zeichenkette kann in den folgenden Formaten aufgebaut sein:
    • "Dateiname von der Bibliothek.Name vom Ding" oder
    • "Dateiname von der Bibliothek.#fortlaufende Nummer vom Ding"

    Der Dateiname von der Bibliothek muss allerdings ohne die Dateinamens-Endung ".dll" angegeben werden.

    Die fortlaufende Nummer vom Ding wird als Dezimalzahl mit der Hilfe von ASCII-Zeichen angegeben.

    Beispiele:
    • "kernel32.WriteConsoleA"
    • "kernel32.#27"

    Diese Art eine Adresse anzugeben, wird "Weiterleitung" (im Englischen: "forwarder") genannt.
Export RVA und
Forwarder RVA
4 Byte 0 Byte
bis
3 Byte
Gesamtgröße: 4 Byte

Bezeichnung
Die Export-Tabelle für Adressen von Dingen wird von Microsoft "Export-Adressen-Tabelle" (im Englischen: "export address table") genannt.

Position
Für diese Tabelle gibt es einen Eintrag im Tabellenverzeichnis für Export-Tabellen. Dieser Eintrag gibt an, wo sich die Export-Tabelle für Adressen von Dingen im Segment befinden soll.

Export-Tabelle für Adressen von Zeichenketten von Namen
Zweck
Diese Tabelle listet die Adressen von Zeichenketten von Namen auf.

Jeder Name identifiziert 1 Ding, welches für einen möglichen Export markiert werden soll. Es können allerdings mehrere Namen 1 spezifischem Ding zugewiesen werden.

Wenn
  • es für ein spezifisches Ding keinen Namen geben soll,
dann
  • gibt es keinen Eintrag für dieses Ding in dieser Tabelle.

    In diesem Fall muss dann das Ding beim Importieren mit der Hilfe von der fortlaufenden Nummer identifiziert werden.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

      Dies trifft allerdings nur zu, wenn das Programm diese Tabelle nicht zum Nachschauen von den ursprünglichen Funktionsnamen benutzt.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für jede Zeichenkette von einem Namen wird ein Offset in diese Tabelle eingefügt. Die Export-Tabelle für Adressen von Zeichenketten von Namen ist also lediglich eine Auflistung von Offsets.

Die zusammengehörenden Einträge in müssen in den beiden Tabellen sortiert angegeben werden. Die Sortierung muss anhand von den Zeichenketten von den Namen erfolgen. Dabei müssen die Rohdaten von den einzelnen Zeichen miteinander verglichen werden:
Wenn
  • beispielsweise die Funktionen
    • "ab",
    • "Ab" und
    • "Ba"
    enthalten sein sollen,
dann
  • müssen diese also in der folgenen Reihenfolge angegeben werden:
    1. "Ab"
    2. "Ba"
    3. "ab"

ASCII-Zeichen: Dezimalwert:
A 65
B 66
a 97
b 98

Wegen der Sortierung kann das Lade-Programm beim Importieren die gesuchte Zeichenkette schneller finden.

Unabhängig davon, ob man den Implementierungs-Mehraufwand für gerechtfertigt hält, ist man gezwungen diese Sortierung zu verwenden. Andernfalls findet das Lade-Programm möglicherweise manche Zeichenketten nicht und man erhält beim Importieren/Starten von der Anwendung eine Fehlermeldung in der folgenden Form:
Der Prozedureinsprungpunkt "meine_Funktion" wurde in der DLL "meine_Bibliothek.dll" nicht gefunden.

Jeder Offset ist "4 Byte"-groß. Da die Anzahl der Einträge von dieser Tabelle im Tabellenverzeichnis für Export-Tabellen angegeben wurde, ist es nicht notwendig, mit zusätzlichen Bytes das Ende von dieser Tabelle zu markieren. Die Gesamtgröße ergibt sich also aus (Anzahl der Einträge) * "4 Byte".

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird für 1 Ding der Offset zum Eintrag in der Export-Tabelle für Zeichenketten von Namen im Segment in Byte angegeben,
Da jeder Eintrag von der Export-Tabelle für Zeichenketten von Namen eine Zeichenkette ist, wird mit der Hilfe von diesem Feld auch der Offset zu einer Zeichenkette angegeben.
4 Byte 0 Byte
bis
3 Byte
Gesamtgröße: 4 Byte

Bezeichnung
Die Export-Tabelle für Adressen von Zeichenketten von Namen wird von Microsoft "Export-Namen-Zeiger-Tabelle" (im Englischen: "export name pointer table") genannt.

Position
Für diese Tabelle gibt es einen Eintrag im Tabellenverzeichnis für Export-Tabellen. Dieser gibt an, wo sich die Export-Tabelle für Adressen von Zeichenketten von Namen im Segment befinden soll.

Export-Tabelle für Positionen von Adressen von Dingen
Zweck
Einem Ding kann eine beliebige Anzahl an Namen zugewiesen werden. Also auch "0 Namen". Daher muss beispielsweise gehören. Das hat zur Folge, dass eine Zuweisung notwendig ist.

Mit der Hilfe von dieser Tabelle werden die Zuweisungen definiert, welcher Name von einem Ding zu welcher Adresse von einem Ding gehört.


┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│
││┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐││
││╔═════════════════════════════════════════════════════╗   ╔═══════════════════════════════════════════════════════╗     ╔════════════════════════════════════╗    ╔══════════════════════════════════════╗ ││
││Export-Tabelle für Positionen von Adressen von Dingen║   ║Export-Tabelle für Adressen von Zeichenketten von Namen║     ║restlicher Speicher                 ║    ║Export-Tabelle für Adressen von Dingen║ ││
││╠═════════════════════════════════════════════════════╣   ╠═══════════════════════════════════════════════════════╣     ╠════════════════════════════════════╣    ╠══════════════════════════════════════╣ ││
││└╢Position vom Ding #1                                 ╟◄─►╢Adresse zur Zeichenkette vom Name #1 vom Ding #1       ╟───┐ ║Ding #1                             ╟◄───╢Adresse zum Ding #1                   ╟◄┘││
││ ╟─────────────────────────────────────────────────────╢   ╟───────────────────────────────────────────────────────╢    ╟────────────────────────────────────╢    ╟──────────────────────────────────────╢  ││
│└─╢Position vom Ding #2                                 ╟◄─►╢Adresse zur Zeichenkette vom Name #1 vom Ding #2       ╟──┐└►╢Zeichenkette vom Name #1 vom Ding #1║ ┌──╢Adresse zum Ding #2                   ╟◄─┴┘
  ╟─────────────────────────────────────────────────────╢   ╟───────────────────────────────────────────────────────╢    ╟────────────────────────────────────╢   ╟──────────────────────────────────────╢    
└──╢Position vom Ding #2                                 ╟◄─►╢Adresse zur Zeichenkette vom Name #2 vom Ding #2       ╟─┐│  ║Ding #2                             ╟◄┘┌─╢Adresse zum Ding #3                   ║    
   ╟─────────────────────────────────────────────────────╢   ╟───────────────────────────────────────────────────────╢ ││  ╟────────────────────────────────────╢   ╟──────────────────────────────────────╢    
└───╢Position vom Ding #4                                 ╟◄─►╢Adresse zur Zeichenkette vom Name #1 vom Ding #4       ╟┐│└─►╢Zeichenkette vom Name #1 vom Ding #2║  ┌╢Adresse zum Ding #4                   ╟◄───┘
    ╚═════════════════════════════════════════════════════╝   ╚═══════════════════════════════════════════════════════╝   ╟────────────────────────────────────╢  ╚══════════════════════════════════════╝
                                                                                                                          ║                                    ║  
                                                                                                                          ╟────────────────────────────────────╢  
                                                                                                                       └──►╢Zeichenkette vom Name #2 vom Ding #2║  
                                                                                                                           ╟────────────────────────────────────╢  
                                                                                                                           ║                                    ║  
                                                                                                                           ╟────────────────────────────────────╢  
                                                                                                                           ║Ding #3                             ╟◄─┘
                                                                                                                           ╟────────────────────────────────────╢   
                                                                                                                           ║                                    ║   
                                                                                                                           ╟────────────────────────────────────╢   
                                                                                                                       └───►╢Zeichenkette vom Name #1 vom Ding #4║   
                                                                                                                            ╟────────────────────────────────────╢   
                                                                                                                            ║Ding #4                             ╟◄──┘
                                                                                                                            ╚════════════════════════════════════╝

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für Welcher Eintrag von der einen Tabelle zu welchem Eintrag von der anderen Tabelle gehört ergibt sich daraus, dass keine Einträge vertauscht sind. Das heißt, und
Daraus ergibt sich, dass ein Eintrag in der Export-Tabelle für Positionen von Adressen von Dingen nur noch 1 Information enthalten muss:
Die Angabe zu welchem Eintrag aus der Export-Tabelle für Adressen von Dingen die beiden zusammengehörenden Einträge aus gehören.

Die Export-Tabelle für Positionen von Adressen von Dingen ist also lediglich eine Auflistung von Positionsangaben. Diese Positionsangaben geben an, mit welchem Eintrag aus der Export-Tabelle für Adressen von Dingen die Zugehörigkeit besteht.

Die zusammengehörenden Einträge in müssen in den beiden Tabellen sortiert angegeben werden. Weitere Informationen zu dieser Sortierung sind im Kapitel "Export-Tabelle für Adressen von Zeichenketten von Namen - Aufbau" enthalten.

Jede Positionsangabe ist "2 Byte"-groß. Da die Anzahl der Einträge von dieser Tabelle im Tabellenverzeichnis für Export-Tabellen angegeben ist, ist es nicht notwendig, mit zusätzlichen Bytes das Ende von dieser Tabelle zu markieren. Die Gesamtgröße ergibt sich also aus (Anzahl der Einträge) * "2 Byte".

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird die Position vom Eintrag in der Export-Tabelle für Adressen von Dingen angegeben.

Die Einträge werden in der Export-Tabelle für Adressen von Dingen von "0" aus gezählt.
ordinal 2 Byte 0 Byte
bis
1 Byte
Gesamtgröße: 2 Byte

Bezeichnung
Die Export-Tabelle für Positionen von Adressen von Dingen wird von Microsoft "Export-fortlaufende Nummer-Tabelle" (im Englischen: "export ordinal table") genannt.

Die Bezeichnung ist hier irreführend, da diese Tabelle nicht fortlaufende Nummern angibt, welche zum Beispiel von "1" aus gezählt werden, sondern Positionsangaben, welche von "0" aus gezählt werden.

Position
Für diese Tabelle gibt es einen Eintrag im Tabellenverzeichnis für Export-Tabellen. Dieser gibt an, wo sich die Export-Tabelle für Positionen von Adressen von Dingen im Segment befindet.

Export-Tabelle für Zeichenketten von Namen
Zweck
Mit der Hilfe von dieser Tabelle werden die ASCII-kodierten Zeichenketten von Namen aufgelistet.

Jeder Name identifiziert 1 Ding, welches für einen möglichen Export markiert werden soll. Es können allerdings mehrere Namen 1 spezifischem Ding zugewiesen werden.

Wenn
  • es für ein spezifisches Ding keinen Namen geben soll,
dann

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • können diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

      Dies trifft allerdings nur zu, wenn das Programm diese Tabelle nicht zum Nachschauen von den ursprünglichen Funktionsnamen benutzt.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für jedes Ding,
  • welches für einen möglichen Export markiert werden soll, und
  • für welches dem Lade-Programm von Windows ein Finden anhand vom Namen ermöglicht werden soll, befindet sich mindestens 1 Eintrag in dieser Tabelle.

Die Einträge müssen allerdings nicht alle direkt hintereinander kommen, sondern können auch quer in der Datei verstreut sein. Dies kann beispielsweise nützlich sein, wenn kleine, unbenutzte Bereiche aufgefüllt werden sollen.

Die Anzahl der Einträge von dieser Tabelle ist im Tabellenverzeichnis für Export-Tabellen angegeben. Es ist keine Kennzeichnung vom Ende von der Tabelle notwendig, da mit der Hilfe von der Export-Tabelle für Adressen von Zeichenketten von Namen bekannt ist, wo jeder einzelne Eintrag ist.

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird eine ASCII-kodierte Zeichenkette angegeben, welche den Namen von dem Ding gespeichert hält, welches für einen möglichen Export markiert werden soll.

Dieser Namen muss mit dem Namen in der Import-Tabelle für Zeichenketten von Namen von der Datei übereinstimmen, welche dieses Ding importieren möchte. Hier ist die exakte Zeichenfolge unter Berücksichtigung von der Groß- und Kleinschreibung relevant.

Nach dem letzten Byte muss ein weiteres Byte kommen, von welchem alle Bits auf "0" gesetzt sind. Damit ist das Ende von der Zeichenkette gekennzeichnet.
variabel 0 Byte
bis
x Byte
Gesamtgröße: variabel

Bezeichnung
Die Export-Tabelle für Zeichenketten von Namen wird von Microsoft "Export-Namen-Tabelle" (im Englischen: "export name table") genannt.

Position
Wo sich die Export-Tabelle für Zeichenketten von Namen im Segment befinden soll, wird nirgends angegeben. Stattdessen wird in der Export-Tabelle für Adressen von Zeichenketten von Namen angegeben, wo sich jeder einzelne Eintrag von dieser Tabelle im Segment befinden soll.

So ist es möglich, kleinere, unbenutzte Bereiche
  • in der Datei und
  • im Segment
mit einzelnen Einträgen aufzufüllen, da die Einträge nicht alle direkt hintereinander kommen müssen.

Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung
Zweck
Die Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung dienen als Hilfskonstrukt für die Importe.

Für jede Datei, welche Dinge enthält, welche importiert werden sollen, kann es eine eigene Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung geben.

Für die zu importierenden Dinge ermittelt das Lade-Programm während dem Lade-Vorgang die Adressen und speichert sie dann in der zugehörigen Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung im Maschinencode.

enthalten, bevor das Lade-Programm zu arbeiten begonnen hat, die Angaben, welche Dinge benutzt werden sollen. Lediglich die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode wird vom Lade-Programm gelesen. Die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung dient lediglich als eine Sicherungskopie für die ursprünglichen Namen von den Dingen, da die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode zur Laufzeit nicht mehr auf die Einträge in der Import-Tabelle für Zeichenketten von Namen zeigt.

Diese Sicherungskopie kann theoretisch vom Maschinencode von der Anwendung verwendet werden. In der Regel verwendet der Maschinencode allerdings lediglich die Adressen aus der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode.

Eine Bibliothek kann, nachdem sie in den physikalischen Arbeitsspeicher geladen wurde und anschließend ins Segment von einer Anwendung geladen wurde, dort zunächst einige Zeit verbleiben. Im späteren Verlauf kann es sein, dass eine weitere Anwendung diese Bibliothek anfordert. Der selbe Bereich aus dem physikalischen Speicher wird dann auch dieser zweiten Anwendung in ihrem Segment zur Verfügung gestellt.

Wenn
  • in einem der beiden Segmente die Bibliothek nicht an die gewünschte Stelle geladen werden kann/konnte oder
  • die Bibliothek, auf die sich diese Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung bezieht, nicht an die gewünschte Stelle geladen werden kann/konnte,
dann
  • kann es sein, dass das Lade-Programm von Windows diese Sicherung benötigt. Ich bin mir allerdings nicht sicher, was das Lade-Programm von Windows in diesem Fall macht.
    • Vielleicht benutzt es in diesem Fall diese Sicherungskopie,
    • vielleicht berechnet es aber auch die Adressen von Zeichenketten neu, indem es die Abweichung reinrechnet,
    • vielleicht läd es aber auch die komplette Bibliothek nochmal von der Festplatte/Diskette/CD/was auch immer.
    (Notiz: das sollte ich prüfen; für einen Hinweis bin ich aber sehr dankbar)

Falls diese Tabelle weggelassen werden soll, dann können im Feld "Import Lookup Table RVA" vom Tabellenverzeichnis für Import-Tabellen alle Bits auf "0" gesetzt werden.

Ich habe es zwar nicht ausprobiert, aber vermutlich geht es auch, wenn in diesem Feld irgendein beliebiger Wert eingetragen ist, da das Lade-Programm von Windows sich ja ohnehin nicht für diese Tabelle interessiert.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt vom Prozess gelesen werden darf.

      Dies trifft allerdings nur zu, wenn das Programm diese Tabelle zum Nachschauen von den ursprünglichen Funktionsnamen benutzt.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

      Dies trifft allerdings nur zu, wenn das Programm diese Tabelle nicht zum Nachschauen von den ursprünglichen Funktionsnamen benutzt. Also wenn diese Tabelle ohnehin nie hätte definiert werden müssen.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
siehe: im Kapitel "Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode - Aufbau"

Bezeichnung
Die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung wird von Microsoft "Import-nachschau-Tabelle" (im Englischen: "import lookup table") genannt.

Position
Wo sich die einzelnen Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung befinden, wird im Tabellenverzeichnis für Import-Tabellen genannt.

Es gibt keinen Eintrag für die Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung im Tabellenverzeichnis für verschiedene Tabellen.

Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
Zweck
Die Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode dienen als Hilfskonstrukt für die Importe.

Für jede Datei, welche Dinge enthält, welche importiert werden sollen, gibt es eine eigene Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode.

Die Einträge werden vom Lade-Programm gelesen und dann mit der jeweiligen
  • Anfangsadresse oder
  • Einsprungadresse
überschrieben, welche angibt, wo
  • die Daten oder
  • die Funktion
beginnt.

So kann die Anwendung zur Laufzeit mit der Hilfe von einem indirekten Funktionsaufruf die importierten Funktion benutzen.

Im Maschinencode wird also die Adresse zu einem Eintrag von einer Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode als Parameter für den "call"-Befehl verwendet. Der Maschinencode benutzt ja nicht die Namen von den Funktionen um die Funktion aufzurufen, obwohl dieser Eindruck durch Hochsprachen entstehen kann.

Zur Laufzeit von der Anwendung befinden sich also in den Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode bereits die gültigen
  • Anfangsadressen von den Daten und
  • Einsprungadressen zu den Funktionen,
welche die Datei aus
  • Bibliotheken oder
  • anderen Programmen
verwenden möchte. Bei diesen Adressen handelt es sich um einen Offset vom Anfang vom Segment von der Anwendung.

Während die Datei jedoch noch auf der Festplatte/Diskette/CD/was auch immer ist, befinden sich in den Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode lediglich die Angaben, welche Dinge benötigt werden.

Diese Tabelle könnte man also
  • auf der Festplatte/Diskette/CD/was auch immer "Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern" und
  • im Segment "Import-Tabelle für Adressen von Dingen"
nennen. Der Maschinencode verwendet die Tabelle "Import-Tabelle für Adressen von Dingen". Dass jedoch die Tabelle "Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern" den Namens-Zusatz "für die Verwendung vom Maschinencode" bekommen hat, dient dafür, um sie von der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung zu unterscheiden.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "225" muss auf "0" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, nicht für andere Zwecke benutzt werden darf.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.
    • Das Bit mit der Wertigkeit "231" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt beschrieben werden darf.

    Die Auswirkungen auf den Namen sind also: "-i?r??w?"

Aufbau
Diese Tabelle ist exakt gleich aufgebaut wie die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung.

Für jedes Ding, welches importiert werden soll, wird ein "4 Byte"-großes Feld in diese Tabelle eingefügt. Diese Tabelle ist also lediglich eine Auflistung von "4 Byte"-großen Feldern.

Da nirgends die Anzahl von den Dingen in dieser Tabelle angegeben wird, wird nach dem letzten Feld eine weiteres Feld eingefügt, von dessen Wert alle Bits auf "0" gesetzt sind. Damit ist das Ende von der Tabelle erkennbar.

Ein Feld ist in 2 Teile aufgeteilt. Der
  • eine Teil ist "1 Bit"-groß und macht eine Auskunft über den anderen Teil.
  • andere Teil ist "31 Bit"-groß und macht eine Auskunft über das Ding.

Die Bedeutungen von den einzelnen Teilen sind wie folgt:
allgemeine Beschreibung: Wertigkeiten von den Bits:
Dieser Teil kann 2 verschiedene Bedeutungen haben. Welche Bedeutung die Angabe von diesem Teil hat, hängt davon ab, ob das Bit "31" gesetzt ist.

Wenn dann Ansonsten wenn
  • dieser Teil eine fortlaufende Nummer vom Ding ist,
dann
  • geben die Bits mit den Wertigkeiten "20 bis 215" die Nummer an.

    Die fortlaufende Nummer wird oft von "1" aus gezählt. Im Tabellenverzeichnis für Export-Tabellen von der exportierenden Datei kann aber ein anderer Wert als "1" angegeben sein.

    Die fortlaufende Nummer muss also der exportierenden Datei ausgelesen werden.

    Im Kapitel "weiteres Material zu diesem Thema - Programme" sind kostenlose Programme aufgelistet, mit deren Hilfe die fortlaufenden Nummern von den einzelnen Dingen angezeigt werden können.

Wenn
  • für alle Einträge auf die Angabe vom Namen verzichtet wird und stattdessen nur fortlaufende Nummern angegeben werden,
dann
Wenn
  • allerdings auf dem Computer, auf welchem die Anwendung ausgeführt wird, eine andere Version von der exportierenden Datei ist, als der Programmierer erwartet,
dann
  • kann es sein, dass das falsche Ding importiert wird.
20
bis
230
allgemeine Beschreibung: Bedeutung wenn Wert=="0": Bedeutung wenn Wert=="1": Wertigkeiten von den Bits:
Mit der Hilfe von diesem Bit wird angegeben, ob der obige Teil (die Bits mit den Wertigkeiten "20 bis 230") angibt. Der obige Teil (die Bits mit den Wertigkeiten "20 bis 230") gibt einen Eintrag in der Import-Tabelle für Zeichenketten von Namen an. Der obige Teil (die Bits mit den Wertigkeiten "20 bis 230") gibt eine fortlaufende Nummer vom Ding an. 231

Bezeichnung
Die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode wird von Microsoft "Import-Adressen-Tabelle" (im Englischen: "import address table") genannt.

Position
Wo sich die einzelnen Import-Tabellen für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode befinden, ist im Tabellenverzeichnis für Import-Tabellen angegeben.

Es gibt einen Eintrag mit dem Namen "Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode" im Tabellenverzeichnis für verschiedene Tabellen. Dieser wird allerdings nicht ausgewertet.

Import-Tabelle für Zeichenketten von Namen
Zweck
Die Import-Tabelle für Zeichenketten von Namen dient als Hilfskonstrukt für Für alle diese Tabellen gibt es allerdings nur 1 Import-Tabelle für Zeichenketten von Namen in der gesamten Datei.

Für jedes Ding
  • welches importiert werden soll, und
  • welches vom Lade-Programm von Windows anhand vom Namen anstatt anhand von der fortlaufenden Nummer gefunden werden soll,
befindet sich in der Import-Tabelle für Zeichenketten von Namen 1 Eintrag. Jeder Eintrag gibt einen Namen für das Ding an. Der selbe Name muss auch in der exportierenden Datei angegeben sein, damit das Lade-Programm ihn finden kann.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

      Dies trifft allerdings nur zu, wenn das Programm diese Tabelle nicht zum Nachschauen von den ursprünglichen Funktionsnamen benutzt.

      Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für jedes Ding
  • welches importiert werden soll, und
  • welches vom Lade-Programm von Windows anhand vom Namen anstatt anhand von der fortlaufenden Nummer gefunden werden soll,
befindet sich in der Import-Tabelle für Zeichenketten von Namen 1 Eintrag.

Die Einträge müssen allerdings nicht alle direkt hintereinander kommen, sondern können auch quer in der Datei verstreut sein. Dies kann beispielsweise dann nützlich sein, wenn kleine, unbenutzte Bereiche aufgefüllt werden sollen.

Die Anzahl der Einträge wird nicht ausdrücklich angegeben, sondern ergibt sich aus Es ist auch keine Kennzeichnung vom Ende von der Tabelle notwendig, da mit der Hilfe von bekannt ist, wo jeder einzelne Eintrag ist.

Die Adresse von einem Eintrag, welche in einer Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung angegeben wurde, kann auch in einer Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode angegeben werden. Dadurch müssen die Einträge nicht doppelt im Speicher vorhanden sein, sondern lediglich die Adressen zu den Einträgen sind dann doppelt vorhanden.

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Dieses Feld gibt die vermutete Position vom Namen in der Export-Tabelle für Zeichenketten von Namen von der exportierenden Datei an, aus der das Ding importiert werden soll.

Die Position wird immer von "0" aus gezählt.

Das Lade-Programm wird zuerst schauen, ob der Name tatsächlich an dieser Position in der Export-Tabelle für Zeichenketten von Namen ist. Wenn
  • dem so ist,
dann
  • sieht es den Namen als gefunden an.
Ansonsten
Die korrekte Angabe bedeutet also ein Geschwindigkeitsvorteil.

Einige Link-Programme bemühen sich nicht um das Nachschauen von der korrekten Position. Das Lade-Programm findet die Einträge trotzdem, aber der Programmstart benötigt länger.

In einer Bibliothek, welche ich mir angeschaut hatte, war Hier wurde also scheinbar im Lauf von der Entwicklungsgeschichte von der Bibliothek ein Ding gelöscht. Der Kompatibilität wegen wurden die anderen Einträge allerdings nicht verschoben.

Die Position vom Namen hängt allerdings sehrwohl von der Version von der Bibliothek ab. Einige Funktionen haben beispielsweise im Betriebssystem "Windows 2000" andere Positionen als im Betriebssystem "Windows experience".

Im Kapitel "weiteres Material zu diesem Thema - Programme" sind kostenlose Programme aufgelistet, mit deren Hilfe die Positionen von den einzelnen Einträgen in der Export-Tabelle für Zeichenketten von Namen von einer Bibliothek, oder sonst einer Datei im Dateiformat "portable executable" ("pe"), angezeigt werden können.
Hint 2 Byte 0 Byte
bis
1 Byte
Dieses Feld gibt eine ASCII-kodierte Zeichenkette an, welche den Namen von dem Ding, welches importiert werden soll, angibt.

Dieser Namen muss mit dem Namen in der Export-Tabelle für Zeichenketten von Namen von der Bibliothek übereinstimmen. Hier ist die exakte Zeichenfolge unter der Berücksichtigung von der Groß- und Kleinschreibung relevant.

Nach dem letzten Byte muss ein weiteres Byte kommen, von welchem alle Bits auf "0" gesetzt sind. Damit ist das Ende von der Zeichenkette gekennzeichnet.

Im Kapitel "weiteres Material zu diesem Thema - Programme" sind kostenlose Programme aufgelistet, mit deren Hilfe die Namen von den einzelnen Dingen in der Export-Tabelle für Zeichenketten von Namen von einer Bibliothek, oder sonst einer Datei im Dateiformat "portable executable" ("pe"), angezeigt werden können.
Name variabel 2 Byte
bis
x Byte
Gesamtgröße: variabel

Bezeichnung
Die Import-Tabelle für Zeichenketten von Namen wird von Microsoft "Hinweis/Namens-Tabelle" (im Englischen: "hint/name table") genannt.

Position
Wo sich die Import-Tabelle für Zeichenketten von Namen im Segment befinden soll, wird nirgends angegeben. Stattdessen wird in angegeben, wo sich jeder einzelne Eintrag von dieser Tabelle im Segment befindet.

So ist es möglich, auch kleinere, unbenutzte Bereiche
  • in der Datei und
  • im Segment
mit einzelnen Einträgen aufzufüllen, da die Einträge nicht alle direkt hintereinander kommen müssen.

Tabelle für Adressen-Reparaturen
Zweck
Im Feld "ImageBase" von der zusätzlichen Kopfzeile kann angegeben werden, wo die Datei im "4 Gigabyte"-großen Segment beginnen soll.

Wenn
  • es nicht möglich ist, sie dort zu platzieren,
dann
  • wird die Datei an eine andere Stelle geladen.

Wenn
  • im Maschinencode absolute Adressangaben verwendet wurden, welche nur gültig sind, wenn die Datei an die gewünschte Stelle im Segment geladen wurde,
dann
  • muss das Lade-Programm diese Adressangaben gegebenenfalls abändern.

Bei ausführbaren Dateien ist meistens keine Tabelle für Adressen-Reparaturen notwendig. Bei Bibliotheken hingegen ist fast immer mindestens 1 Tabelle für Adressen-Reparaturen notwendig.

Mit der Hilfe von dieser Tabelle ist es lediglich möglich, die Abänderung durchführen zu lassen, indem der Unterschied zwischen
  • der vom Erzeuger gewünschten Stelle im Segment und
  • der vom Lade-Programm gewählten Stelle im Segment
zur Adressangabe hinzuaddiert (Plus gerechnet) wird.

Die absoluten Adressangaben müssen also stimmen, wenn die Datei an die gewünschte Stelle im Segment geladen wird, weil in diesem Fall zu allen Adressangaben der Wert "0" addiert werden würde. In diesem Fall spart sich das Lade-Programm allerdings die Arbeit und führt keine Adressen-Reparaturen durch.

Relative Adressangaben sind hiervon nicht betroffen, da der Inhalt von einer Datei als ein zusammenhängender Block angesehen wird. Der Block wird nicht zerstückelt. Durch eine Zerstückelung könnten relative Adressangaben im Maschinencode ungültig werden.

Damit das Lade-Programm diese Adressangaben abändern kann, muss es wissen, wo diese Adressangaben sind. Um dies herauszufinden gibt es unter anderem diese Möglichkeiten:
  • Das Lade-Programm durchläuft den Maschinencode und sucht nach Befehlen mit einer absoluten Adressangabe als Parameter.

    Diese Methode ist langsam und erfordert vom Lade-Programm, dass es jeden Maschinenbefehl kennt, um zu wissen, wieviele Parameter folgen, um damit entscheiden zu können, welches Byte als nächstes wieder ein Maschinenbefehl ist und welche Byte Parameter sind. Außerdem muss das Lade-Programm von den Maschinenbefehlen wissen, ob einer von den Parametern eine absolute Adressangabe ist.

    Problematisch bei dieser Methode ist außerdem die Aufwärtskompatibilität. Also selbst wenn
    • die aktuelle Version vom Lade-Programm alle momentan existierenden Maschinenbefehle kennt,
    dann
    • kann das Lade-Programm keine neuen Maschinenbefehle kennen, welche erst in der Zukunft in einem neuen Prozessor das erste Mal auf den Markt kommen.

      Die Computerbenutzer wären also bei neuen Prozessoren völlig von den Entwicklern vom Lade-Programm abhängig und müssten sich gegebenfalls eine neuere Version vom Lade-Programm installieren, damit neue Programme die neuen Befehle benutzen zu können.

    Was allerdings vorteilhaft an dieser Methode ist, ist, dass die Entwickler von Compilern sich nicht um die Korrektur von absoluten Adressangaben kümmern müssen.
  • Eine andere Methode, und diese ist es, welche in diesem Dateiformat gewählt wurde, besteht darin, dass der Compiler angibt, wo absolute Adressangaben sind, welche geändert werden müssen.

    Ein Compiler wird von denjenigen entwickelt, welche die einzelnen Maschinenbefehle kennen. Diese Entwickler wissen auch, wo im Code absolute Adressangaben vorkommen. Ein Entwickler von einem Compiler muss nicht alle existierenden Maschinenbefehle von der CPU-Architektur kennen, aber er kennt wahrscheinlich die Maschinenbefehle, welche sein Compiler verwendet, um Quellcode in der Programmiersprache, für welche der Compiler geschrieben ist, in Maschinencode zu übersetzen.

    Um diese Positionsangaben zu speichern, wurde die Tabelle für Adressen-Reparaturen ins Dateiformat aufgenommen.

Wenn
  • der Maschinencode keine absoluten Adressangaben enthält, sondern alle Adressen relativ angegeben sind, oder
  • im Voraus klar ist, dass das Lade-Programm die Programmabschnitt-Inhalte an die gewünschte Stelle im Segment laden kann,
dann
  • kann diese Tabelle weggelassen werden.

Die Inhalte von der ausführbaren Datei sind eine der ersten Inhalte, welche ins Segment geladen werden. Daher lässt sich bei diesen Inhalten noch relativ einfach sagen, ob diese vom Lade-Programm an die gewünschte Stelle platziert werden können.

Die Inhalte von einer Bibliothek hingegen werden erst im späteren Lade-Vorgang ins Segment geladen. Zu diesem Zeitpunkt können sich bereits die Inhalte von anderen Bibliotheken im Segment befinden. Außerdem können sie von jeder beliebig großen Anwendung angefordert werden. Die Stelle, welche die Bibliothek als gewünschte Stelle angibt, ist daher mit einer größeren Wahrscheinlichkeit bereits, wenn vielleicht auch nur teilweise, belegt.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
In einer Datei kann es mehrere Tabellen für Adressen-Reparaturen geben, da in jeder Tabelle nur soviele Speicherzellen angegeben werden können, in welchen zu reparierende Adressen gespeichert sind, wie sich in einem maximal "4 Kilobyte"-großen und zusammenhängenden Bereich vom Segment befinden.

Zwischen 2 Tabellen dürfen keine unbenutzten Bytes sein.

Eine solche Tabelle besteht aus 2 Teilen:
  1. Am Anfang von der Tabelle ist eine Kopfzeile und
  2. am Ende von der Tabelle sind die Einträge.

Zwischen den beiden Teilen dürfen keine unbenutzen Bytes sein.

Die Kopfzeile macht, unter anderem eine Auskunft darüber, wie groß die komplette Tabelle ist. Damit wird also indirekt angegeben, wieviele Einträge in der restlichen Tabelle sind.

Im Folgenden ist diese Untergliederung grafisch dargestellt:
   ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
   ┃Tabelle für Adressen-Reparaturen
   ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
   ┃╔══════════════════════════════╗┃
   ┃║          Kopfzeile           ║┃
   ┃╠══════════════════════════════╣┃
   ┃║                              ║┃
   ┃╟──────────────────────────────╢┃
┌──╂╢     Anzahl der Einträge      ║┃
  ┃╚══════════════════════════════╝┃
  ┠────────────────────────────────┨
  ┃╔══════════════════════════════╗┃
  ┃║ Auflistung von den Einträgen ║┃
 ┃╠══════════════════════════════╣┃
 ┃║                              ║┃
 ┃╟──────────────────────────────╢┃
 ┃║                              ║┃
└►┤┃╟──────────────────────────────╢┃
  ┃║                              ║┃
  ┃╟──────────────────────────────╢┃
  ┃║                              ║┃
  ┃╚══════════════════════════════╝┃
   ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Der Aufbau von der Kopfzeile sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang
von der
Kopfzeile: Tabelle:
Mit der Hilfe von diesem Feld wird der Offset zu einem maximal "4 Kilobyte"-großen und zusammenhängenden Bereich vom Segment, in welchem sich Speicherzellen befinden, in welchen zu reparierende Adressen gespeichert sind, im Segment in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches der maximal "4 Kilobyte"-großen und zusammenhängenden Bereich vom Segment im Segment belegen soll.

Laut Microsoft muss dieser Offset restlos durch 4 teilbar sein. Nach meinen eigenen Tests überprüft das Lade-Programm dies allerdings nicht. Wenn
  • der Offset also nicht restlos durch 4 teilbar ist,
dann
  • funktionieren die Adressen-Reparaturen trotzdem.
Ansonsten
  • laufen die Adressen-Reparaturen wahrscheinlich ein kleinwenig schneller ab.

Dieser Offset ist der erste Teil von einer Auskunft, welche angibt, wo sich eine Speicherzelle befindet, in welcher eine zu reparierende Adresse gespeichert ist.
Page RVA 4 Byte 0 Byte
bis
3 Byte
0 Byte
bis
3 Byte
Mit der Hilfe von diesem Feld wird die Gesamtgröße von dieser Tabelle für Adressen-Reparaturen in Byte angegeben.

Diese Größe enthält die Kopfzeile und alle Einträge.
Block Size 4 Byte 4 Byte
bis
7 Byte
4 Byte
bis
7 Byte
Gesamtgröße: 8 Byte

Für jede Speicherzelle, in welcher eine zu reparierende Adresse gespeichert ist, muss ein Offset in Byte angegeben werden,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches die Speicherzelle im Segment belegen soll.

Dieser Offset ergibt sich allerdings durch eine Addition (Plus rechnen) von 2 Werten:
  • Der eine Wert ist in der Kopfzeile gespeichert und
  • der andere Wert ist im Eintrag gespeichert.

Dies hat
  • den Vorteil, dass die Größe von einem Eintrag lediglich "2 Byte" beträgt und
  • die Nachteile,
    • dass der Implementierungsaufwand für die Software, welche diese Tabellen erzeugt, ansteigt,
    • dass der Code von der Software größer und komplexer wird und
    • dass der Wartungsaufwand vom geschriebenen Code ansteigen kann.

Für jede Speicherzelle, in welcher eine zu reparierende Adresse gespeichert ist, ist ein Eintrag in einer Tabelle für Adressen-Reparaturen. Die Auflistung von den Einträgen von einer bestimmten Tabelle für Adressen-Reparaturen kommen direkt hintereinander. Also ohne unbenutzte Bytes zwischendrin.

Der Aufbau von einem Eintrag sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird der Offset in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches im Feld "Page RVA" von der Kopfzeile angegeben ist,
  • bis zum ersten Byte, welches die Speicherzelle, in welcher eine zu reparierende Adressen gespeichert ist, im Segment belegen soll.

Dieser Offset ist der zweite Teil von einer Auskunft, welche angibt, wo sich eine Speicherzelle befindet, in welcher eine zu reparierende Adresse gespeichert ist.
Offset 12 Bit 0 Bit
bis
11 Bit
Mit der Hilfe von diesem Feld wird die Größe vom Inhalt von der Speicherzelle angegeben.

Größe vom Inhalt von der Speicherzelle: Hexadezimalwert:
2 Byte 2
4 Byte 3
8 Byte A

Es gibt weitere gültige Werte, welche in dieser Dokumentation allerdings nicht beschrieben sind. Die unbeschriebenen Werte werden bei der x86-CPU-Architektur allerdings normalerweise nicht verwendet.

Für CPU-Architekturen von ARM oder sonstigen CPU-Architekturen, bei welchen die Speicherzelle aufgeteilt ist, können gegebenenfalls diese von mir undokumentierten Werte verwendet werden.
Type 4 Bit 12 Bit
bis
15 Bit
Gesamtgröße: 2 Byte

Bezeichnung
Die Tabelle für Adressen-Reparaturen wird von Microsoft heutzutage meistens "Verschiebungstabelle" (im Englischen: "relocation table") genannt. Früher wurde sie "fixup table" genannt.

Position
Für die erste Tabelle gibt es einen Eintrag im Tabellenverzeichnis für verschiedene Tabellen. Dieser gibt an, wo sich die erste Tabelle für Adressen-Reparaturen im Segment befinden soll.

Tabelle für Ressourcen
Text

Tabellenverzeichnis für Export-Tabellen
Zweck
Mit der Hilfe vom Exportieren wird ermöglicht, dass andere
  • Anwendungen und
  • Bibliotheken
einen Zugriff auf
  • Datensätze und
  • Funktionen
bekommen, welche in dieser Datei gespeichert sind.

Hierfür muss mit der Hilfe von mehreren Tabellen angegeben werden, welche Dinge aus dieser Datei für einen möglichen Export markiert werden sollen. Das Tabellenverzeichnis für Export-Tabellen gibt unter Anderem an, wo sich diese Tabellen befinden.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Das Tabellenverzeichnis für Export-Tabellen ist eine Auflistung von Feldern mit verschiedenen Größen.

Dieses Tabellenverzeichnis ist immer "40 Byte"-groß, daher muss nirgends ihre Größe angegeben werden. Das Ende von diesem Verzeichnis wird ebenfalls nicht markiert.

Der Aufbau vom Tabellenverzeichnis für Export-Tabellen sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Tabellenverzeichnis:
Dieses Feld ist unbenutzt.

Microsoft empfiehlt, alle Bits auf "0" zu setzen.
Export Flags 4 Byte 0 Byte
bis
3 Byte
Mit der Hilfe von diesem Feld wird, in der Form von einem Unix-Zeitstempel (im Englischen: "Unix timestamp"), die Auskunft über
  • das Datum und
  • die Uhrzeit
gemacht, wann das Tabellenverzeichnis für Export-Tabellen erzeugt wurde. Diese Angabe ist eine Art von Versionsangabe vom Verzeichnis.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument über Zeitsysteme aufgelistet. In diesem Dokument sind auch die Spezifikationen vom Zeitsystem "Unix-Zeitstempel" enthalten.

Es sieht so aus, als würde dieser Zeitstempel nicht ausgewertet werden. Daher können vermutlich alle Bits von diesem Feld auf "0" gesetzt werden.
Time/Date Stamp 4 Byte 4 Byte
bis
7 Byte
Mit der Hilfe von diesem Feld wird die Hauptversion von irgendetwas angegeben.

Wenn
  • die Hauptversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version inkompatibel zur Vorgängerversion ist.

Das Feld wird allerdings nicht ausgewertet. Daher können alle Bits von diesem Feld auf "0" gesetzt werden.
Major Version 2 Byte 8 Byte
bis
9 Byte
Mit der Hilfe von diesem Feld wird die Unterversion von irgendetwas angegeben.

Wenn
  • die Unterversion erhöht wird,
dann
  • bedeutet dies normalerweise, dass die neue Version kompatibel zur Vorgängerversion ist.

Das Feld wird allerdings nicht ausgewertet. Daher können alle Bits von diesem Feld auf "0" gesetzt werden.
Minor Version 2 Byte 10 Byte
bis
11 Byte
Mit der Hilfe von diesem Feld wird der Offset zu einer ASCII-kodierten Zeichenkette, welche irgendwo in einem Programmabschnitt-Inhalt im Segment platziert ist, in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches die Zeichenkette im Segment belegen soll.

Die Zeichenkette gibt den Dateinamen von dieser Datei an. Also zum Beispiel "meine_Bibliothek.dll".

Die Zeichenkette muss mit der Hilfe von einem weiteren Byte abgeschlossen werden, von welchem alle Bits auf "0" gesetzt sind. Damit ist das Ende von der Zeichenkette gekennzeichnet.

Leider konnte ich nicht zufriedenstellend klären, wofür in der Datei der eigene Dateiname angegeben werden soll. Wenn
  • eine Anwendung das Lade-Programm auffordert, ein Ding aus einer Bibliothek zu importieren,
dann
  • werden ohnehin nicht alle Dateien auf dem Computer geöffnet und gelesen, welche gemäß dem Dateiformat "portable executable" ("pe") gespeichert sind.

Nach meinen Tests können hier auch alle Bits auf "0" gesetzt werden.
Name RVA 4 Byte 12 Byte
bis
15 Byte
Mit der Hilfe von diesem Feld wird angegeben, bei welcher Zahl die fortlaufenden Nummern von den Dingen aus gezählt werden sollen, welche für einen möglichen Export markiert werden sollen.

Oft wird hier der Wert "1" angegeben. Ich empfehle hingegen, alle Bits auf "0" zu setzen.

Es gibt einen Fehler in der offiziellen Spezifikationsbeschreibung von Microsoft zum Dateiformat "portable executable" ("pe"). Dieser besteht darin, dass Microsoft in der Export-Tabelle für Positionen von Adressen von Dingen
  • die fortlaufende Nummer, welche nicht zwangsweise von "0" aus gezählt wird, und
  • die Position, welche zwangsweise von "0" aus gezählt wird,
vertauscht hat. Wenn
  • nun allerdings die erste Nummer von den fortlaufenden Nummern die Nummer "0" ist,
dann
  • stimmen die fortlaufenden Nummern mit den Positionen überein und es spielt keine Rolle mehr, ob man es nun "fortlaufende Nummer" oder "Position" nennt. Man spart sich also die Verwirrung, welche entstehen kann, wenn nicht klar ist, ob man bei einer Angabe nun den "Offset" von "1" hinzuaddieren muss oder nicht.

    Diese Ersparnis hat man dann allerdings nur bei
    • den eigenen Bibliotheken und
    • den Bibliotheken von Entwicklern, welche hier ebenfalls auf die Verwirrung verzichtet haben.
Ordinal Base 4 Byte 16 Byte
bis
19 Byte
Mit der Hilfe von diesem Feld wird die Anzahl der Einträge in der Export-Tabelle für Adressen von Dingen angegeben. Address Table Entries 4 Byte 20 Byte
bis
23 Byte
Mit der Hilfe von diesem Feld wird die Anzahl der Einträge angegeben, welche jeweils in enthalten sind. Jede von diesen Tabellen hat zwangsweise gleich viele Einträge.

Ein Ding, welches für einen möglichen Export markiert werden soll, kann mehrere Namen zugewiesen bekommen. Beim Import kann dann ein beliebiger Name von den zugewiesenen Namen verwendet werden.

Der Wert von diesem Feld kann also vom Wert im Feld "Address Table Entries" abweichen. Meistens ist es allerdings der selbe Wert.
Number of Name Pointers 4 Byte 24 Byte
bis
27 Byte
Mit der Hilfe von diesem Feld wird der Offset zur Export-Tabelle für Adressen von Dingen im Segment in Byte angegeben, Export Address Table RVA 4 Byte 28 Byte
bis
31 Byte
Mit der Hilfe von diesem Feld wird der Offset zur Export-Tabelle für Adressen von Zeichenketten von Namen im Segment in Byte angegeben,
Wenn
    • kein Ding anhand vom Namen exportiert werden soll,
    • sondern alle Dinge anhand von den fortlaufenden Nummern,
dann
  • können alle Bits von diesem Feld auf "0" gesetzt werden. Hierdurch ist angegeben, dass diese Tabelle nicht existiert.
Name Pointer RVA 4 Byte 32 Byte
bis
35 Byte
Mit der Hilfe von diesem Feld wird der Offset zur Export-Tabelle für Positionen von Adressen von Dingen im Segment in Byte angegeben, Ordinal Table RVA 4 Byte 36 Byte
bis
39 Byte
Gesamtgröße: 40 Byte

Bezeichnung
Das Tabellenverzeichnis für Export-Tabellen wird von Microsoft "Export-Verzeichnis-Tabelle" (im Englischen: "export directory table") genannt.

Position
Für dieses Verzeichnis gibt es einen Eintrag im Tabellenverzeichnis für verschiedene Tabellen. Dieser gibt an, wo sich das Tabellenverzeichnis für Export-Tabellen im Segment befinden soll.

Tabellenverzeichnis für Import-Tabellen
Zweck
Mit der Hilfe vom Importieren wird ermöglicht, dass diese
  • Anwendung oder
  • Bibliothek
einen Zugriff auf
  • Datensätze und
  • Funktionen
bekommt, welche in anderen Dateien gespeichert sind.

Hierfür muss mit der Hilfe von mehreren Tabellen angegeben werden, welche Dinge aus welchen Dateien benötigt werden, damit diese ins Segment von dieser
  • Anwendung oder
  • Bibliothek
geladen werden und die Adressen zu den Dingen dieser
  • Anwendung oder
  • Bibliothek
zur Verfügung gestellt werden.

Das Tabellenverzeichnis für Import-Tabellen gibt unter Anderem an, wo sich diese Tabellen befinden.

Prinzipiell ist es für den Programmierer möglich, sich die Datei, auf welche sich der Import bezieht, anzuschauen, damit er wenigstens angeben kann, welchen Offset das benötigte Ding vom Anfang von der Datei hat. So könnte dann zur Adresse, wo die Datei, auf welche sich der Import bezieht, ins Segment geladen wurde, dieser Offset hinzuaddiert werden, damit die Adresse vom benötigten Ding bekannt ist.

Das hätte allerdings den Nachteil, dass wenn
  • die Datei, auf welche sich der Import bezieht, geändert wird,
dass sich dann
  • alle Offset-Angaben verschieben können.

Um dieses Problem zu beheben, nennt die
  • Anwendung oder
  • Bibliothek,
welche das Ding aus der Datei importieren möchte, beispielsweise
  • eine fortlaufende Nummer oder
  • den Namen
vom Ding.

Eine fortlaufende Nummer behebt das Problem allerdings noch nicht vollständig, da mit der Hilfe von einer Änderung in der Datei, auf welche sich der Import bezieht, vor dem Ding
  • bestehende Dinge wegfallen oder
  • weitere Dinge hinzukommen
können und sich somit die fortlaufende Nummer vom benötigten Ding ändert.

Wenn
  • der Name genannt wird,
dann
Wenn
  • die Datei, auf welche sich der Import bezieht, geändert wird,
dann
  • werden die Export-bezüglichen Tabellen in der Datei, auf welche sich der Import bezieht, aktualisiert.

Die Export-bezüglichen Tabellen geben für alle Dinge, welche
  • in der Datei enthalten sind und
  • für einen möglichen Export markiert sind,
alle Namen zusammen mit jeweils einem Offset, wo sich dieses Ding in der Datei befindet, an.

Das Lade-Programm von Windows benutzt also, wenn es einen Import durchführt, auch die Export-bezüglichen Tabellen in der Datei, auf welche sich der Import bezieht, um die Adresse zum Ding herauszufinden.

Anforderungen an den Programmabschnitt-Inhalt
Vom Feld "Characteristics" von der Kopfzeilen-Tabelle von den Programmabschnitten
  • müssen diese Bits gesetzt werden:
    • Das Bit mit der Wertigkeit "26" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass im Programmabschnitt-Inhalt Daten enthalten sind, welche bereits beim Programmstart mit Werten definiert sind.
    • Das Bit mit der Wertigkeit "230" muss auf "1" gesetzt werden.

      Es muss also die Angabe gemacht werden, dass der Bereich vom Arbeitsspeicher von diesem Programmabschnitt-Inhalt gelesen werden darf.

    Die Auswirkungen auf den Namen sind also: "?i?r????"
  • kann dieses Bit gesetzt werden:
    • Das Bit mit der Wertigkeit "225" kann auf "1" gesetzt werden.

      Es kann also die Angabe gemacht werden, dass der Bereich vom physikalischen Arbeitsspeicher von diesem Programmabschnitt-Inhalt, nachdem der Lade-Vorgang abgeschlossen ist, für andere Zwecke benutzt werden darf.

    Die Auswirkungen auf den Namen wären also: "d???????"

Aufbau
Für jede Datei, von welcher
  • die Anwendung oder
  • die Bibliothek
ein oder mehrere Dinge importieren möchte, gibt es im Tabellenverzeichnis für Import-Tabellen eine Importbeschreibung. Das Tabellenverzeichnis für Import-Tabellen ist lediglich eine Auflistung von Importbeschreibungen.

Eine Importbeschreibung besteht aus 5 Feldern und ist insgesamt "20 Byte"-groß.

Nirgends wird die Anzahl von den Importbeschreibungen angegeben und die Gesamtgröße vom Tabellenverzeichnis für Import-Tabellen, welche im Tabellenverzeichnis für verschiedene Tabellen angegeben werden kann, wird vom Lade-Programm nicht ausgewertet. Damit das Lade-Programm dennoch das Ende von der Tabelle erkennt, wird nach der letzten Importbeschreibung eine weitere Importbeschreibung eingefügt, von welcher alle Bits von den 20 Byte auf "0" gesetzt sind.

Der Aufbau von einem Eintrag/einer Importbeschreibung sieht wie folgt aus:
Beschreibung: Bezeichnung: Größe: Offset vom Anfang vom Eintrag:
Mit der Hilfe von diesem Feld wird der Offset zur Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung im Segment in Byte angegeben,
Die exakt gleichen Angaben, welche in der gemacht werden, befinden sich auch in der
Von diesen beiden Tabellen kann die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung weggelassen werden.

Um diese Tabelle wegzulassen, müssen alle Bits von diesem Feld auf "0" gesetzt werden.
aktuell: Import Lookup Table RVA
früher: Characteristics
4 Byte 0 Byte
bis
3 Byte
Mit der Hilfe von diesem Feld wird, in der Form von einem Unix-Zeitstempel (im Englischen: "Unix timestamp"), eine Auskunft über
  • das Datum und
  • die Uhrzeit
gemacht, wann die Datei, auf welche sich die Importbeschreibung bezieht, erzeugt wurde. Diese Angabe ist eine Art von Versionsangabe von der Datei, auf welche sich die Importbeschreibung bezieht.

Weitere Informationen hierzu sind in der Beschreibung von dem Feld "TimeDateStamp" von der Datei-Kopfzeile enthalten.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument über Zeitsysteme aufgelistet. In diesem Dokument sind auch die Spezifikationen vom Zeitsystem "Unix-Zeitstempel" enthalten.
Time/Date Stamp 4 Byte 4 Byte
bis
7 Byte
Ich konnte noch nicht zufriedenstellend klären, wofür dieses Feld dient. (Notiz: hier sollte ich nochmal recherchieren)

Laut Bernd Luevelsmeyer können bei Unklarheit über die Funktion von diesem Feld einfach alle Bits auf "1" gesetzt werden.
Forwarder Chain 4 Byte 8 Byte
bis
11 Byte
Mit der Hilfe von diesem Feld wird der Offset zu einer ASCII-kodierten Zeichenkette, welche irgendwo in einem Programmabschnitt-Inhalt im Segment platziert werden soll, in Byte angegeben,
  • vom ersten Byte aus gerechnet, welches die Datei im Segment belegen soll (siehe hierzu: das Feld "ImageBase" von der zusätzlichen Kopfzeile),
  • bis zum ersten Byte, welches die Zeichenkette im Segment belegen soll.

Die Zeichenkette gibt den relativen Pfad + Dateinamen von der Datei an, auf welche sich die Importbeschreibung bezieht.

  1. Zuerst wird die Datei, auf welche sich die Importbeschreibung bezieht, im Verzeichnis von der Anwendung gesucht.

    Der volle Pfad zu diesem Verzeichnis ist beispielsweise
    "C:\mein_Programm\".

    Die Zeichenkette, welche die Datei angibt, kann in einem solchen Fall beispielsweise
    "Bibliotheken\mathematische Bibliothek.dll"
    sein.

    Hierdurch wird also angegeben, dass sich die Datei, auf welche sich die Importbeschreibung bezieht, an folgendem Ort befindet:
    "C:\mein_Programm\Bibliotheken\mathematische Bibliothek.dll"
  2. Wenn
    • sie dort nicht gefunden wurde,
    dann
    • wird sie im "system32"-Verzeichnis vom Windows-Installationsverzeichnis gesucht.

    Der volle Pfad zu diesem Verzeichnis ist beispielsweise
    "C:\Windows\system32\".

    Die Zeichenkette, welche die Datei angibt, kann in einem solchen Fall beispielsweise
    "kernel32.dll"
    sein.

    Hierdurch wird also angegeben, dass sich die Datei, auf welche sich die Importbeschreibung bezieht, an folgendem Ort befindet:
    "C:\Windows\system32\kernel32.dll"
  3. Wenn
    • sie dort auch nicht gefunden wurde,
    dann
    • wird sie im Windows-Installationsverzeichnis gesucht.

    Der volle Pfad zu diesem Verzeichnis ist beispielsweise
    "C:\Windows\".

    Die Zeichenkette, welche die Datei angibt, kann in einem solche Fall beispielsweise
    "..\Testbibliothek.dll"
    sein.

    Hierdurch wird also angegeben, dass sich die Datei, auf welche sich die Importbeschreibung bezieht, an folgendem Ort befindet:
    "C:\Testbibliothek.dll".

Die Zeichenkette muss mit der Hilfe von einem weiteren Byte abgeschlossen werden, von welchem alle Bits auf "0" gesetzt sind. Damit ist das Ende von der Zeichenkette gekennzeichnet.
Name RVA 4 Byte 12 Byte
bis
15 Byte
Mit der Hilfe von diesem Feld wird der Offset zur Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode im Segment in Byte angegeben, aktuell: Import Address Table RVA
früher: Thunk Table
4 Byte 16 Byte
bis
19 Byte
Gesamtgröße: 20 Byte

Bezeichnung
Das Tabellenverzeichnis für Import-Tabellen wird von Microsoft "Import-Tabelle" (im Englischen: "import table") genannt.

Importbeschreibungen werden von Microsoft "Import-Beschreiber" (im Englischen: "import descriptor") genannt. Ein Ding, also
  • ein Datensatz oder
  • eine Funktion,
welches importiert werden soll, wird von Microsoft "Symbol" (im Englischen: "symbol") genannt.

Position
Für diese Tabelle gibt es einen Eintrag im Tabellenverzeichnis für verschiedene Tabellen. Dieser gibt an, wo sich das Tabellenverzeichnis für Import-Tabellen im Segment befinden soll.


ein "Hallo Welt!"-Programm

Beschreibung

Im Nachfolgenden wird Schritt für Schritt gezeigt, wie mit der Hilfe von eine ausführbare Datei ("*.exe"-Datei) geschrieben werden kann, welche nach dem Aufrufen "Hallo Welt!" ausgibt.

Die vollständige Datei, welche im Lauf von den folgenden Schritten entstehen wird, kann allerdings auch im Kapitel "weiteres Material zu diesem Thema - Programme" heruntergeladen werden.

notwendige Voraussetzungen

Sie benötigen ein Möglichkeit, mit deren Hilfe Rohdaten in eine Datei geschrieben werden können. Also auch solche "Zeichen", welche sich nicht direkt mit der Tastatur eingeben lassen. Dies kann beispielsweise

Vorbereitung

die Datei anlegen

Als erstes hatte ich eine neue Textdatei auf meinem Desktop angelegt. Diese hatte ich dann von "Neu Textdokument.txt" in "Hallo_Welt.exe" umbenannt.

Wenn
  • Sie ebenfalls so vorgehen wollen, aber Ihnen als Dateiname "Neu Textdokument" anstatt "Neu Textdokument.txt" angezeigt wird,
dann
  • zeigt Ihnen Windows die Dateinamens-Endung ".txt" nicht an.

Diese Funktion gibt es, damit man nicht versehentlich die Dateinamens-Endung
  • ändert oder
  • löscht,
wenn man den Dateinamen ändert. In unserem Fall soll die Dateinamens-Endung allerdings gelöscht werden.

Damit Windows Ihnen die Dateinamens-Endung anzeigt, können Sie in "Windows experience" ("Windows xp") wie folgt vorgehen:
  1. Öffnen Sie den Arbeitsplatz und damit den Windows Explorer.
  2. Klicken Sie in der Menüleiste auf "Extras".
  3. Klicken Sie in dem Menü, welches sich eben geöffnet hat, auf "Ordneroptionen...".
  4. Klicken Sie in dem Fenster, welches sich eben geöffnet hat, auf den Reiter "Ansicht".
  5. Nehmen Sie den Haken von der Option "Erweiterungen bei bekannten Dateitypen ausblenden" weg.
  6. Klicken Sie unten auf den Knopf "Übernehmen".
  7. Klicken Sie oben auf den Knopf "Für alle übernehmen" und bestätigen Sie das aufspringende Fenster mit dem Knopf "Ja".
  8. Klicken Sie unten auf den Knopf "OK".

Nun sollte Windows auch bei Dateien auf Ihrem Desktop die Dateinamens-Endung anzeigen, sodass Sie die Änderung vornehmen können.

die Datei öffnen

Die Datei kann jetzt zur Bearbeitung mit
  • dem Hex-Editor oder
  • dem Text-Editor
geöffnet werden.

Anmerkungen zum Speichern

Wenn dann
Die Zeichenkodierung "ISO 8859-1" hingegen speichert jeden Wert zwischen 0 und 255 als 1 Byte ab. Um Rohdaten zu erzeugen, würden wir also eine Zeichenkodierung von dieser Art verwenden können.

Ich hingegen werde im Folgenden den Hex-Editor "Binary to Hex Editor" verwenden, welcher im Kapitel "weiteres Material zu diesem Thema - Programme" aufgelistet ist.

In einem Hex-Editor kann man für jedes Byte direkt den Wert als Zahl in der hexadezimal-Schreibweise angeben. Der Hex-Editor speichert dann die einzelnen Werte als einzelne Bytes ab, ohne dass dabei eine Zeichenkodierung angewand wird.

Damit erledigt sich das Problem mit dem Fehler durch eine ungeeignete Zeichenkodierung. Die einzelnen Werte sind ja ansich ohnehin nicht als "Zeichen" zu verstehen.

DOS-Abschnitt

die Kopfzeile schreiben

Allgemeines

Sie können sich gegebenenfalls den Aufbau vom DOS-Abschnitt nocheinmal anschauen, um leichter nachvollziehen zu können, wofür die folgenden Angaben dienen.

Die ersten 32 Byte vom DOS-Abschnitt beinhalten die komplette Kopfzeile vom DOS-Abschnitt. Da dieses "Hallo Welt!"-Programm allerdings nur in Windows laufen muss, werde ich nur die notwendigen Felder ausfüllen.

Die Kopfzeile beginnt mit der Signatur "MZ". Von den restlichen 30 Bytes setze ich alle Bits auf "0":
Inhalt: Offset vom Anfang von der Datei in Byte:
Schreibweise: Wert:
ASCII M
binär 0100 1101
dezimal 77
hexadezimal 4D
Schreibweise: Wert:
binär 0000 0000
dezimal 0
hexadezimal 00
Schreibweise: Wert:
ASCII Z
binär 0101 1010
dezimal 90
hexadezimal 5A
Schreibweise: Wert:
binär 0000 0001
dezimal 1
hexadezimal 01
30 mal:
Schreibweise: Wert:
ASCII - nicht darstellbar -
binär 0000 0000
dezimal 0
hexadezimal 00
Schreibweise: Wert:
binär 0000 0010 bis 0001 1111
dezimal 2 bis 31
hexadezimal 02 bis 1F

Um diese Werte in den Hex-Editor übernehmen zu können, müssen Sie in diesem Format eingetragen werden:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Um die Datei anschließend zu speichern, gehen Sie wie folgt vor:
  1. Klicken Sie in der Menüleiste auf "File".
  2. Klicken Sie in dem Menü, welches sich eben geöffnet hat, auf "Save Hex as Binary File".

Wenn
  • Sie die Werte in einem anderen Format eintragen,
dann
  • kann das Programm beim Speichern abstürzen.

Änderung

Schreiben Sie die folgenden Werte in die "Hallo_Welt.exe"-Datei:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: die Signatur "MZ"
gelb hinterlegt: der Rest

Ergebnis

Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Die Dateigröße von der "Hallo_Welt.exe"-Datei müsste nun exakt 32 Byte betragen.

Größe

   2 Byte für die Signatur "MZ"
+ 30 Byte für den Rest
= 32 Byte für die komplette Kopfzeile vom DOS-Abschnitt

den unbenutzten Bereich schreiben

Allgemeines

Von den Bytes vom unbenutzten Bereich sollen alle Bits auf "0" gesetzt werden.

Änderung

Erweitern Sie die Datei um die folgenden Werte:
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00
rot hinterlegt: der unbenutzte Bereich

Ergebnis

Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00

Nach dem Speichern müsste die Datei nun "60 Byte"-groß sein.

Größe

Der unbenutzte Bereich ist "28 Byte"-groß.

den Offset zum Windows-Abschnitt schreiben

Allgemeines

Dieser Offset gibt an, an welcher Stelle in der Datei der Windows-Abschnitt beginnt.

Nach diesem Offset würde das DOS-Programm kommen. Da allerdings schon die nicht vollständig ausgefüllte Kopfzeile vom DOS-Abschnitt dafür sorgen würde, dass die Datei "Hallo_Welt.exe" in DOS nicht funktioniert, wird auch kein DOS-Programm eingefügt. Stattdessen werde ich angeben, dass der Windows-Abschnitt direkt nach diesen 4 Bytes kommen wird.

Änderung

Erweitern Sie die Datei um die folgenden Werte:
                                                40 00 00 00 rot hinterlegt: der Offset zum Windows-Abschnitt

Ergebnis

Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00

Nach dem Speichern müsste die Datei nun "64 Byte"-groß sein.

Größe

Dieser Offset ist "4 Byte"-groß.

Übersicht

Das war soweit der komplette DOS-Abschnitt:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
rot hinterlegt: die Kopfzeile
gelb hinterlegt: der unbenutzte Bereich
grün hinterlegt: der Offset zum Windows-Abschnitt

Windows-Abschnitt

Kopfzeile

die Signatur schreiben

Allgemeines
Der Windows-Abschnitt beginnt mit seiner Kopfzeile. Die Kopfzeile wiederum beginnt mit der Signatur.

Die ersten beiden Bytes von der Signatur sind die ASCII-Zeichen "PE". Von den letzten beiden Bytes werden alle Bits auf "0" gesetzt.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000040: 50 45 00 00 rot hinterlegt: "PE"
gelb hinterlegt: "\0\0"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00

Nach dem Speichern müsste die Datei nun "68 Byte"-groß sein.

Größe
  2 Byte für die Zeichen "PE"
+ 2 Byte von welchen alle Bits auf "0" gesetzt sind
= 4 Byte für die komplette Signatur

die Datei-Kopfzeile schreiben

Allgemeines
Für die einzelnen Felder von diesem Abschnitt werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
x86er von Intel mit "32 Bit"-Architektur, also 386er, oder eine spätere, darauf basierende Architektur Machine 4C 01 - -
3 Programmabschnitte NumberOfSections 03 00 - -
0 Sekunden seit 1. Januar 1970; wird eh nicht ausgewertet TimeDateStamp 00 00 00 00
keine Symboltabelle PointerToSymbolTable 00 00 00 00
keine Symbole in der Symboltabelle NumberOfSymbols 00 00 00 00
  96 Byte für die zusätzliche Kopfzeile
+ 56 Byte für das Tabellenverzeichnis für verschiedene Tabellen (da sie 7 "8 Byte"-große Einträge haben wird)
= 152 Byte
SizeOfOptionalHeader 98 00 - -
Die einzelnen Bits werden wie folgt gesetzt:
Bedeutung: Wert: Wertigkeit:
Wenn
  • die Datei nicht an der gewünschten Stelle im Segment platziert werden kann,
dann
  • soll der Lade-Vorgang abgebrochen werden.
1 20
Die Datei kann verwendet werden. 1 21
Es sind keine Informationen über die Zeilennummer vorhanden. 1 22
Es sind keine Informationen über lokale Symbole vorhanden. 1 23
Der belegte Arbeitsspeicher soll nicht auf die Festplatte ausgelagert werden. 0 24
Das Programm kann keine Adressen handhaben, welche über 31 Bit lang sind.

Ich habe keine Ahnung, was das bewirkt. Aber weil es in allen anderen ausführbaren Dateien, welche ich mir angeschaut hatte, auch so gemacht ist, mache ich es auch so.
0 25
unbenutzt 0 26
veraltet 0 27

Die Architektur muss eine "32 Bit"-Architektur, oder eine darauf basierende Architektur, sein. 1 28
Es sind keine Hilfs-Informationen für eine Fehersuche vorhanden. 1 29
Das Programm darf auch von einem Wechselmedium ausgeführt werden. 0 210
Das Programm darf auch über ein Netzwerk ausgeführt werden. 0 211
Diese Datei ist
  • weder eine Systemdatei vom Betriebssystem
  • noch ein Treiber.
0 212
Die Datei ist keine Bibliothek. 0 213
Die Datei darf auch auf einem "ACPI-Multiprocessor-PC" ausgeführt werden. 0 214
veraltet 0 215
Characteristics 0F 03 - -

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                      4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03
rot hinterlegt: der Wert für das Feld "Machine"
gelb hinterlegt: der Wert für das Feld "NumberOfSections"
grün hinterlegt: der Wert für das Feld "TimeDateStamp"
blau hinterlegt: der Wert für das Feld "PointerToSymbolTable"
lila hinterlegt: der Wert für das Feld "NumberOfSymbols"
rot hinterlegt: der Wert für das Feld "SizeOfOptionalHeader"
gelb hinterlegt: der Wert für das Feld "Characteristics"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03

Nach dem Speichern müsste die Datei nun "88 Byte"-groß sein.

Größe
  2 Byte für das Feld "Machine"
+ 2 Byte für das Feld "NumberOfSections"
+ 4 Byte für das Feld "TimeDateStamp"
+ 4 Byte für das Feld "PointerToSymbolTable"
+ 4 Byte für das Feld "NumberOfSymbols"
+ 2 Byte für das Feld "SizeOfOptionalHeader"
+ 2 Byte für das Feld "Characteristics"
= 20 Byte für die komplette Datei-Kopfzeile

die zusätzliche Kopfzeile schreiben

Allgemeines
Für die einzelnen Felder von diesem Abschnitt werde ich die folgende Werten verwenden
Beschreibung: Bezeichnung: Hexadezimalwert:
2560: 2561: 2562: 2563:
Dateiformat "32 Bit portable executable" ("pe32") Magic 0B 01 - -
Hauptversion "0" vom Link-Programm; wird eh nicht ausgewertet MajorLinkerVersion 00 - - -
Unterversion "0" vom Link-Programm; wird eh nicht ausgewertet MinorLinkerVersion 00 - - -
0 Byte für die Größe vom ausführbaren Code von allen Programmabschnitt-Inhalten zusammengerechnet; wird eh nicht ausgewertet SizeOfCode 00 00 00 00
0 Byte für die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet, welche bereits beim Programmstart mit Werten definiert sind; wird eh nicht ausgewertet SizeOfInitializedData 00 00 00 00
0 Byte für die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet, die erst zur Laufzeit zum ersten Mal mit Werten definiert werden; wird eh nicht ausgewertet SizeOfUninitializedData 00 00 00 00
4 Kilobyte als Offset zum Maschinencode, welcher nach dem Laden von der Anwendung ausgeführt werden soll; der Offset zeigt zum Anfang vom ersten Programmabschnitt-Inhalt AddressOfEntryPoint 00 10 00 00
0 Byte als Offset zum Anfang vom Maschinencode; wird eh nicht ausgewertet BaseOfCode 00 00 00 00
0 Byte als Offset zu den Daten, welche bereits beim Programmstart mit Werten definiert sind; wird eh nicht ausgewertet BaseOfData 00 00 00 00
4 Megabyte als Anfangsadresse, wo die ausführbare Datei im Segment platziert werden soll.

Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.
ImageBase 00 00 40 00
4 Kilobyte als Seitengröße von einem Programmabschnitt-Inhalt im Arbeitsspeicher SectionAlignment 00 10 00 00
512 Byte als Seitengröße von einem Programmabschnitt-Inhalt auf der Festplatte FileAlignment 00 02 00 00
Hauptversion "0" vom notwendigen Betriebssystem; wird eh nicht ausgewertet MajorOperatingSystemVersion 00 00 - -
Unterversion "0" vom notwendigen Betriebssystem; wird eh nicht ausgewertet MinorOperatingSystemVersion 00 00 - -
Hauptversion "0" von diesem "Hallo Welt!"-Programm; wird eh nicht ausgewertet MajorImageVersion 00 00 - -
Unterversion "0" von diesem "Hallo Welt!"-Programm; wird eh nicht ausgewertet MinorImageVersion 00 00 - -
Hauptversion "4" vom notwendigen Betriebssystem; wird ausgewertet MajorSubsystemVersion 04 00 - -
Unterversion "0" vom notwendigen Betriebssystem; wird ausgewertet MinorSubsystemVersion 00 00 - -
alle unbenutzten Bits auf "0" gesetzt Win32VersionValue 00 00 00 00
   3 * 4 Kilobyte für die 3 ersten RAM-Seiten
+ 84 Byte für die letzte RAM-Seite mit dem letzten Programmabschnitt-Inhalt
= 12.372 Byte als Gesamtgröße von der Datei im Arbeitsspeicher
SizeOfImage 54 30 00 00
512 Bytes für die Größe vom
  DOS-Abschnitt
+ Kopfzeile vom Windows-Abschnitt
+ Kopfzeilen-Tabelle
auf die nächsten 512 Bytes aufgerundet

bei uns ist bei einem "7 Einträge"-großen Tabellenverzeichnis für verschiedene Tabellen und einer "4 Einträge"-großen Kopfzeilen-Tabelle der unaufgerundete Wert "400 Byte"
SizeOfHeaders 00 02 00 00
alle Bits von der Prüfsumme auf "0" gesetzt; wird eh nicht ausgewertet CheckSum 00 00 00 00
benötigtes Untersystem: Konsole (Eingabeaufforderung) Subsystem 03 00 - -
alle Flaggen auf "0" gesetzt, diese sind ohnehin nicht für ausführbare Dateien, sondern für Bibliotheken DllCharacteristics 00 00 - -
256 Kilobyte als maximale Stapelgröße SizeOfStackReserve 00 00 04 00
4 Kilobyte als Anfangsgröße vom Stapel SizeOfStackCommit 00 10 00 00
0 KB als maximale Haufengröße; wird eh nicht ausgewertet SizeOfHeapReserve 00 00 00 00
0 KB als Anfangsgröße vom Haufen; wird eh nicht ausgewertet SizeOfHeapCommit 00 00 00 00
alle unbenutzten Bits auf "0" gesetzt LoaderFlags 00 00 00 00
7 Einträge im Tabellenverzeichnis für verschiedene Tabellen NumberOfRvaAndSizes 07 00 00 00

Die einzelnen Programmabschnitt-Inhalte sind alle kleiner als 512 Byte und damit auch kleiner als 4 Kilobyte. Dadurch ist für jeden Programmabschnitt-Inhalt nur 1 Seite notwendig.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                    0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00
rot hinterlegt: der Wert vom Feld "Magic"
gelb hinterlegt: der Wert vom Feld "MajorLinkerVersion"
grün hinterlegt: der Wert vom Feld "MinorLinkerVersion"
blau hinterlegt: der Wert vom Feld "SizeOfCode"
lila hinterlegt: der Wert vom Feld "SizeOfInitializedData"
rot hinterlegt: der Wert vom Feld "SizeOfUninitializedData"
gelb hinterlegt: der Wert vom Feld "AddressOfEntryPoint"
grün hinterlegt: der Wert vom Feld "BaseOfCode"
blau hinterlegt: der Wert vom Feld "BaseOfData"
lila hinterlegt: der Wert vom Feld "ImageBase"
rot hinterlegt: der Wert vom Feld "SectionAlignment"
gelb hinterlegt: der Wert vom Feld "FileAlignment"
grün hinterlegt: der Wert vom Feld "MajorOperatingSystemVersion"
blau hinterlegt: der Wert vom Feld "MinorOperatingSystemVersion"
lila hinterlegt: der Wert vom Feld "MajorImageVersion"
rot hinterlegt: der Wert vom Feld "MinorImageVersion"
gelb hinterlegt: der Wert vom Feld "MajorSubsystemVersion"
grün hinterlegt: der Wert vom Feld "MinorSubsystemVersion"
blau hinterlegt: der Wert vom Feld "Win32VersionValue"
lila hinterlegt: der Wert vom Feld "SizeOfImage"
rot hinterlegt: der Wert vom Feld "SizeOfHeaders"
gelb hinterlegt: der Wert vom Feld "CheckSum"
grün hinterlegt: der Wert vom Feld "Subsystem"
blau hinterlegt: der Wert vom Feld "DllCharacteristics"
lila hinterlegt: der Wert vom Feld "SizeOfStackReserve"
rot hinterlegt: der Wert vom Feld "SizeOfStackCommit"
gelb hinterlegt: der Wert vom Feld "SizeOfHeapReserve"
grün hinterlegt: der Wert vom Feld "SizeOfHeapCommit"
blau hinterlegt: der Wert vom Feld "LoaderFlags"
lila hinterlegt: der Wert vom Feld "NumberOfRvaAndSizes"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00

Nach dem Speichern müsste die Datei nun "184 Byte"-groß sein.

Größe
  2 Byte für das Feld "Magic"
+ 1 Byte für das Feld "MajorLinkerVersion"
+ 1 Byte für das Feld "MinorLinkerVersion"
+ 4 Byte für das Feld "SizeOfCode"
+ 4 Byte für das Feld "SizeOfInitializedData"
+ 4 Byte für das Feld "SizeOfUninitializedData"
+ 4 Byte für das Feld "AddressOfEntryPoint"
+ 4 Byte für das Feld "BaseOfCode"
+ 4 Byte für das Feld "BaseOfData"
+ 4 Byte für das Feld "ImageBase"
+ 4 Byte für das Feld "SectionAlignment"
+ 4 Byte für das Feld "FileAlignment"
+ 2 Byte für das Feld "MajorOperatingSystemVersion"
+ 2 Byte für das Feld "MinorOperatingSystemVersion"
+ 2 Byte für das Feld "MajorImageVersion"
+ 2 Byte für das Feld "MinorImageVersion"
+ 2 Byte für das Feld "MajorSubsystemVersion"
+ 2 Byte für das Feld "MinorSubsystemVersion"
+ 4 Byte für das Feld "Win32VersionValue"
+ 4 Byte für das Feld "SizeOfImage"
+ 4 Byte für das Feld "SizeOfHeaders"
+ 4 Byte für das Feld "CheckSum"
+ 2 Byte für das Feld "Subsystem"
+ 2 Byte für das Feld "DllCharacteristics"
+ 4 Byte für das Feld "SizeOfStackReserve"
+ 4 Byte für das Feld "SizeOfStackCommit"
+ 4 Byte für das Feld "SizeOfHeapReserve"
+ 4 Byte für das Feld "SizeOfHeapCommit"
+ 4 Byte für das Feld "LoaderFlags"
+ 4 Byte für das Feld "NumberOfRvaAndSizes"
= 96 Byte für die komplette zusätzliche Kopfzeile

das Tabellenverzeichnis für verschiedene Tabellen schreiben

Allgemeines
Damit später "Hallo Welt!" ausgegeben werden kann, werde ich hierfür die Funktion "WriteConsoleA" von der Windows-API benutzen. Dieser Funktion muss man als einen von den Parametern angeben, in welche Konsole (in welches Eingabeaufforderungs-Fenster) etwas geschrieben werden soll. Um dies herauszufinden, werde ich die Funktion "GetStdHandle" benutzen.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument aufgelistet, welches diese Funktionen von der Windows-API beschreibt.

Damit die beiden Funktionen später jeweils mit der Hilfe vom Befehl "call" benutzt werden können, muss das Lade-Programm die Bibliothek "kernel32.dll" in den Arbeitsspeicher laden und anschließend die beiden Einsprungadressen zu den Funktionen bereitstellen.

Daher wird mit der Hilfe vom 1. Eintrag (von "0" ausgehend gezählt) vom Tabellenverzeichnis für verschiedene Tabellen angegeben, dass das Tabellenverzeichnis für Import-Tabellen existiert. Es wird im 2./letzten Programmabschnitt-Inhalt platziert, jedoch nicht direkt am Anfang.

Als Größe für das Tabellenverzeichnis für Import-Tabellen werde ich "0 Byte" angeben, da diese Größenangabe ohnehin nicht ausgewertet wird.

Der 6. Eintrag im Tabellenverzeichnis für verschiedene Tabellen ist für die Tabelle für eine Fehlersuche und existiert nur wegen einem Fehler in Windows experience. Alle anderen Tabellen werden als "nicht existent" angegeben.

Das Tabellenverzeichnis für verschiedene Tabellen wird daher "7 Einträge"-groß sein.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                    00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: der 0. Eintrag
gelb hinterlegt: der 1. Eintrag (für das Tabellenverzeichnis für Import-Tabellen)
grün hinterlegt: der 2. Eintrag
blau hinterlegt: der 3. Eintrag
lila hinterlegt: der 4. Eintrag
rot hinterlegt: der 5. Eintrag
gelb hinterlegt: der 6. Eintrag (für die Tabelle für eine Fehlersuche)

Später, wenn
  • die exakte Adresse bekannt ist,
dann
  • werden die Fragezeichen ersetzt.

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "240 Byte"-groß sein.

Größe
7 Einträge * 8 Byte pro Eintrag
= 56 Byte für das komplette Tabellenverzeichnis für verschiedene Tabellen

Übersicht

Das war soweit die komplette Kopfzeile vom Windows-Abschnitt:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: die Signatur
gelb hinterlegt: die Datei-Kopfzeile
grün hinterlegt: die zusätzliche Kopfzeile
blau hinterlegt: das Tabellenverzeichnis für verschiedene Tabellen

Programmabschnitte

die Kopfzeilen-Tabelle schreiben

Allgemeines
Später werden 3 Programmabschnitt-Inhalte verwendet, daher wird die Kopfzeilen-Tabelle von den Programmabschnitten 3 Einträge enthalten.

Um
  • "Hallo Welt!" auszugeben und
  • die Importe zu definieren,
werden ich die folgenden Inhalte in die Programmabschnitt-Inhalte speichern:
#: Größe: Inhalte: Name: Offset vom
Anfang von der Datei: ersten Byten, welches die Datei im Segment belegt:
0
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
  1. Maschinencode zum Ausgeben von der "Hallo Welt!"-Zeichenkette
--p-s--x
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
Schreibweise: Wert:
binär 1 0000 0000 0000 Byte
dezimal 4.096 Byte
hexadezimal 10 00 Byte
1
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
  1. Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll"
  2. "Hallo Welt!"-Zeichenkette
-ipr--w-
Schreibweise: Wert:
binär 100 0000 0000 Byte
dezimal 1.024 Byte
hexadezimal 4 00 Byte
Schreibweise: Wert:
binär 10 0000 0000 0000 Byte
dezimal 8.192 Byte
hexadezimal 20 00 Byte
2
Schreibweise: Wert:
binär 101 0100 Byte
dezimal 84 Byte
hexadezimal 54 Byte
  1. Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. Tabellenverzeichnis für Import-Tabellen
  3. "kernel32.dll\0"-Zeichenkette
dipr----
Schreibweise: Wert:
binär 110 0000 0000 Byte
dezimal 1.536 Byte
hexadezimal 6 00 Byte
Schreibweise: Wert:
binär 11 0000 0000 0000 Byte
dezimal 12.288 Byte
hexadezimal 30 00 Byte

Für die einzelnen Felder von jedem Eintrag in der Kopfzeilen-Tabelle werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
der Name entsprechend der obigen Tabelle Name
0 Byte als Größe von den genutzten Bytes vom Programmabschnitt-Inhalt; wird eh nicht ausgewertet VirtualSize 00 00 00 00
Der Offset vom ersten Byte, welches die Datei im Segment belegen soll, bis zum Anfang vom Programmabschnitt-Inhalt, wenn er ins Segment geladen wurde, entsprechend der obigen Tabelle. VirtualAddress
die Größe entsprechend der obigen Tabelle SizeOfRawData
Der Offset vom Anfang von der Datei bis zum Anfang vom Programmabschnitt-Inhalt, solange er noch auf der Festplatte ist, entsprechend der obigen Tabelle.. PointerToRawData
alle unbenutzten Bits auf "0" gesetzt PointerToRelocations 00 00 00 00
PointerToLinenumbers 00 00 00 00
NumberOfRelocations 00 00 - -
NumberOfLinenumbers 00 00 - -
Die Flaggen entsprechend dem Namen; siehe: Namensgebung von einem spezifischen Programmabschnitt.

Für die Zeichenkette "Hallo Welt!" ist die Schreibberechtigung ("??????w?") nicht notwendig. Es ist allerdings universeller, für die Daten/Variablen eine Schreibberechtigung zu geben. So muss man nicht bei jeder Datei/jedem Projekt prüfen, ob die Daten/Variablen beschreibbar sein müssen.
Characteristics

Änderung
Erweitern Sie die Datei um die folgenden Werte:
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42
rot hinterlegt: der 0. Eintrag/Kopfzeile
gelb hinterlegt: der 1. Eintrag/Kopfzeile
grün hinterlegt: der 2. Eintrag/Kopfzeile

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42

Nach dem Speichern müsste die Datei nun "360 Byte"-groß sein.

Größe
3 Einträge * 40 Byte pro Eintrag
= 120 Byte für die komplette Kopfzeilen-Tabelle

den unbenutzten Zwischenraum füllen

Allgemeines
Da die Datei nun "360 Byte"-groß ist, wurden soweit die Bytes "0" bis "359" mit Werten gefüllt. Der 0. Programmabschnitt-Inhalt soll allerdings erst beim Byte "512" beginnen.

Aus diesem Grund muss ein Zwischenraum geschaffen werden, damit der 0. Programmabschnitt-Inhalt auch tatsächlich erst beim Byte "512" beginnt und nicht schon beim Byte "360".

Ich werde alle Bits vom Zwischenraum auf "0" setzen.

Ein derartiger Zwischenraum wird im Englischen "cave" genannt.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000160:                           00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: der unbenutzte Zwischenraum

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "512 Byte"-groß sein.

Größe
Der Zwischenraum füllt die Bytes "360" bis "511" und ist somit "152 Byte"-groß.

0. Programmabschnitt-Inhalt

die Funktion "WriteConsoleA"
den Wert vom Parameter "unbenutzt" auf den Stapel legen
Allgemeines
Im 0. Programmabschnitt-Inhalt ist im Wesentlichen der Maschinencode, um die "Hallo Welt!"-Zeichenkette auszugeben.

Um eine Zeichenkette auszugeben, kann in Windows eine Zeichenkette in den Ausgabe-Datenkanal von einer Konsole (Eingabeaufforderungs-Fenster) übertragen werden. Damit wird die Zeichenkette in der Konsole angezeigt.

Um dieses Übertragen durchzuführen, kann die Funktion "WriteConsoleA" von der Bibliothek "kernel32.dll" verwendet werden.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument aufgelistet, welches die Funktionen vom Betriebssystem "Windows" beschreibt. Aus diesem Dokument ist auch ablesbar, dass die Funktion "WriteConsoleA" beim Aufrufen einige Parameter erfordert:
WriteConsoleA(
    Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung,
    Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte,
    Quelle_-_Nutzdaten_-_Länge_in_Zeichen,
    Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte,
    unbenutzt
)

Damit Funktionen von der Windows-API korrekt funktionieren, muss
  • als Erstes der Wert vom letzten Parameter ("unbenutzt") auf den Stapel gelegt werden und
  • als Letztes der Wert vom ersten Parameter ("Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung").

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist auch ein Dokument aufgelistet, welches die Maschinensprache der x86-CPU-Architektur beschreibt und somit zeigt, wie ein Wert auf den Stapel gelegt werden kann.

Ich werde nun den Wert vom Parameter "unbenutzt" auf den Stapel legen, von welchem ich alle Bits auf "0" setzen werde.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000200: 68 00 00 00 00 rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert "0"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00

Nach dem Speichern müsste die Datei nun "517 Byte"-groß sein.

Sie können nach diesem Schritt das Programm "DumpPE" mit der Option "-disasm" über Ihre "Hallo_Welt.exe"-Datei laufen lassen. Sie werden dann sehen, dass das Programm versucht hat Ihre "Hallo_Welt.exe"-Datei zu disassemblieren. Somit wird Ihnen "push 0" angezeigt.

Die folgenden Zeilen ("add [eax], al") kommen zustande, wenn man lauter Bytes disassembliert, von welchen alle Bits auf "0" gesetzt sind. Das Programm geht davon aus, dass der Programmabschnitt-Inhalt "512 Byte"-groß ist.

Geben Sie dazu beispielsweise in eine Konsole (in ein Eingabeaufforderungs-Fenster) etwas wie Folgendes ein:
"C:\DumpPE.exe" -disasm "C:\Hallo_Welt.exe"

Größe
  1 Byte für die Befehlsnummer vom Befehl "push"
+ 4 Byte für den Wert
= 5 Byte für den kompletten Maschinenbefehl

den Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Mit der Hilfe von diesem Schritt wird der Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel gelegt.

Der Wert gibt eine Speicherstelle im Segment von der Anwendung an. An dieser Speicherstelle würde die Funktion "WriteConsoleA" die Anzahl der Zeichen speichern, welche mit der Hilfe vom Funktionsdurchlauf tatsächlich in die Konsole übertragen wurden.

Da ich davon ausgehe, dass alle Zeichen übertragen werden können und ich diesen Wert ohnehin nicht auswerte, werde ich den Wert "0" als Adresse angeben. Dieser bedeutet, dass die Funktion die Anzahl nicht speichern soll.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                         68 00 00 - 00 00 rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert "0"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00

Nach dem Speichern müsste die Datei nun "522 Byte"-groß sein.

Größe
  1 Byte für die Befehlsnummer vom Befehl "push"
+ 4 Byte für den Wert
= 5 Byte für den kompletten Maschinenbefehl

den Wert vom Parameter "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" auf den Stapel legen
Allgemeines
Mit der Hilfe von diesem Schritt wird der Wert vom Parameter "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" auf den Stapel gelegt.

Der Wert gibt die Anzahl der Zeichen an, welche in die Konsole übertragen werden sollen. Die Zeichenkette "Hallo Welt!" ist "11 Zeichen"-lang.

Da die Anzahl der Zeichen angegeben wird, ist es nicht notwendig, die Zeichenkette "Hallo Welt!" mit der Hilfe von einem Byte abzuschließen, von welchem alle Bits auf "0" gesetzt sind.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                          68 0B 00 00 00 rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert "11|d = B|h"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00

Nach dem Speichern müsste die Datei nun "527 Byte"-groß sein.

Größe
  1 Byte für die Befehlsnummer vom Befehl "push"
+ 4 Byte für den Wert
= 5 Byte für den kompletten Maschinenbefehl

den Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Mit der Hilfe von diesem Schritt wird der Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel gelegt.

Der Wert gibt eine Speicherstelle im Segment vom "Hallo Welt!"-Programm an. Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.

An der Speicherstelle beginnt die "Hallo Welt!"-Zeichenkette.

Der Wert von diesem Parameter ist
  4 Megabyte (die Adresse, an welche die Datei im Segment platziert wird)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt)
+ 12 Byte (Größe von der "2 + 1 Einträge"-großen Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll")
= 4.202.508 Byte.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                         68
00000210: 0C 20 40 00
rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00

Nach dem Speichern müsste die Datei nun "532 Byte"-groß sein.

Größe
  1 Byte für die Befehlsnummer vom Befehl "push"
+ 4 Byte für den Wert
= 5 Byte für den kompletten Maschinenbefehl

die Funktion "GetStdHandle"
den Wert vom Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" auf den Stapel legen
Allgemeines
Bevor der Wert vom nächsten Parameter von der Funktion "WriteConsoleA" auf den Stapel gelegt werden kann, muss er zuerst ermittelt werden.

Der nächste Parameter von dieser Funktion ist eine Identifikationskennung von einem Datenkanal von einer Konsole.

  • Zum Einen muss also die Konsole ausgewählt werden, da zur Laufzeit vom Programm mehrere Konsolen offen sein können und ein Programm theoretisch auch in eine Konsole von einem anderen Programm schreiben kann und
  • zum Anderen muss die Art vom Datenkanal ausgewählt werden, da jede Konsole mehrere Datenkanäle anbietet. Die Konsole, welche einem Programm beim Lade-Vorgang zugewiesen wird, hat 3 Datenkanäle:
    • Einen Datenkanal um Daten auszugeben.

      Dieser wird normalerweise von einem Programm beschrieben.
    • Einen Datenkanal um Daten einzulesen.

      Dieser wird normalerweise vom Benutzer durch eine Tastatureingabe beschrieben und von einem Programm ausgelesen. Er kann allerdings auch von einem Programm beschrieben werden und von einem anderen Programm ausgelesen werden.
    • Einen Datenkanal um Fehlermeldungen auszugeben.

Im Schritt "Windows-Abschnitt - Kopfzeile - die zusätzliche Kopfzeile schreiben" haben wir angegeben, dass eine Konsole als Untersystem benötigt wird. Daher wird dem Programm automatisch eine Konsole nach dem Starten zugewiesen.

Wenn
  • das Programm mit der Hilfe von einer Konsole (einem Eingabeaufforderungs-Fenster) gestartet wurde,
dann
  • wird diese Konsole dem Programm zugewiesen. Diese bleibt nach dem Beenden vom Programm geöffnet, sodass, wenn die Funktion "Hallo_Welt_ausgeben" benutzt wurde, auch das "Hallo Welt!" auf dem Bildschirm bleibt.
Ansonsten wenn
  • das Programm mit der Hilfe von einen Doppelklick gestartet wurde,
dann
  • wird für das Programm eine neue Konsole gestartet. Diese wird nach dem Beenden vom Programm automatisch wieder geschlossen. Damit erscheint das "Hallo Welt!" nur ganz kurz auf dem Bildschirm und verschwindet dann gleich wieder.

Um nun die zugewiesene Konsole zu ermitteln, kann die Funktion "GetStdHandle" verwendet werden.

Diese Funktion hat nur 1 Parameter:
GetStdHandle(
    Quelle_-_Konsole_-_Datenkanal_-_Art
)

Ich werde nun den Wert
Schreibweise: Wert:
binär
(gemäß Variablentyp "Ganzzahl mit Vorzeichen")
1111 0101 1111 1111 1111 1111 1111 1111
dezimal
(gemäß regulärer Schreibweise)
-11
hexadezimal
(gemäß Variablentyp "Ganzzahl mit Vorzeichen")
F5 FF FF FF
auf den Stapel legen, damit dieser als Wert für den Parameter dient und damit angegeben wird, dass die Funktion die Identifikationskennung vom Ausgabe-Datenkanal zurückgeben soll.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                      68 F5 FF FF - FF rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF

Nach dem Speichern müsste die Datei nun "537 Byte"-groß sein.

Größe
  1 Byte für die Befehlsnummer vom Befehl "push"
+ 4 Byte für den Wert
= 5 Byte für den kompletten Maschinenbefehl

die Funktion aufrufen
Allgemeines
Da der Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" der einzige Parameter von der Funktion "GetStdHandle" ist und der Wert von diesem nun ganz "oben" auf dem Stapel liegt, kann die Funktion nun aufgerufen werden.

Mit der Hilfe vom Funktionsdurchlauf wird der Wert vom Stapel gelesen und gelöscht. Anschließend wird das Ergebnis in das Allzweckregister "extended accumulator" ("eax") gespeichert.

Um die Funktion aufzurufen, werde ich mit der Hilfe vom Befehl "call" einen indirekten Funktionsaufruf durchführen lassen. "indirekt" heißt, dass ich
  • nicht die Adresse von der Speicherstelle angebe, wo die Funktion beginnt,
  • sondern dass ich die Adresse von der Speicherstelle angebe, welche als Wert die Adresse von der Speicherstelle gespeichert hält, welche angibt, wo die Funktion beginnt.

Die Adresse, wo die Funktion beginnt, speichert das Lade-Programm von Windows beim Laden von der "Hallo_Welt.exe"-Datei in die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode. Der Eintrag für die Funktion "GetStdHandle" ist der 0. Eintrag in dieser Tabelle.

Somit ist die Adresse von der Speicherstelle, dessen Wert angibt, wo die Funktion beginnt, die Folgende:
  4 Megabyte (die Adresse, an welcher die ausführbare Datei im Segment platziert wurde)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt))
= 4.202.496 Byte

Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                       FF 15 00 20 40 00 rot hinterlegt: die Befehlsnummer vom Befehl "call"
gelb hinterlegt: die Adresse

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00

Nach dem Speichern müsste die Datei nun "543 Byte"-groß sein.

Größe
  2 Byte für die Befehlsnummer vom Befehl "call"
+ 4 Byte für die Adresse
= 6 Byte für den kompletten Maschinenbefehl

die Funktion "WriteConsoleA"
den Wert vom Parameter "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" auf den Stapel legen
Allgemeines
Die Werte von den Parametern
  • "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte",
  • "Quelle_-_Nutzdaten_-_Länge_in_Zeichen",
  • "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" und
  • "unbenutzt"
von der Funktion "WriteConsoleA" sind nun auf dem Stapel.

Der Wert vom Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" von der Funktion "GetStdHandle" wurde zwischenzeitlich mit der Hilfe vom Funktionsdurchlauf von der Funktion "GetStdHandle" wieder vom Stapel gelöscht.

Der Wert vom Parameter "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" von der Funktion "WriteConsoleA" fehlt noch auf dem Stapel. Er ist aber bereits im Allzweckregister "extended accumulator" ("eax") gespeichert.

Mit der Hilfe von diesem Schritt wird also der Wert vom Allzweckregister "extended accumulator" ("eax") auf den Stapel gelegt.

Änderung
Erweitern Sie die Datei um den folgenden Wert:
                                                         50 rot hinterlegt: die Befehlsnummer vom Befehl "push"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50

Nach dem Speichern müsste die Datei nun "544 Byte"-groß sein.

Größe
Dieser Maschinenbefehl ist "1 Byte"-groß.

die Funktion aufrufen
Allgemeines
Nun liegen die Werte von allen Parametern von der Funktion "WriteConsoleA" ganz "oben" auf dem Stapel, daher kann die Funktion nun aufgerufen werden.

Mit der Hilfe vom Funktionsdurchlauf werden die Werte vom Stapel gelesen und gelöscht. Anschließend wird in das Allzweckregister "extended accumulator" ("eax") gespeichert, ob Zeichen in die Konsole übertragen werden konnten und wenn ja, wieviele. Diese Angabe interessiert mich allerdings nicht weiter, da ich einfach davon ausgehe, dass die komplette Zeichenkette "Hallo Welt!" mit der Hilfe von 1 Funktionsdurchlauf übertragen werden konnte.

Um die Funktion aufzurufen, werde ich mit der Hilfe vom Befehl "call" einen indirekten Funktionsaufruf durchführen lassen.

Die Adresse, wo die Funktion beginnt, speichert das Lade-Programm von Windows beim Laden von der "Hallo_Welt.exe"-Datei in die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode. Der Eintrag für die Funktion "WriteConsoleA" ist der 1. Eintrag (von "0" ausgehend gezählt) in der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode.

Somit ist die Adresse von der Speicherstelle, dessen Wert angibt, wo die Funktion beginnt, die Folgende:
  4 Megabyte (die Adresse, an welcher die ausführbare Datei im Segment platziert wurde)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt))
+ 4 Byte (die Größe vom 0. Eintrag in der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode)
= 4.202.500 Byte

Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000220: FF 15 04 20 40 00 rot hinterlegt: die Befehlsnummer vom Befehl "call"
gelb hinterlegt: die Adresse

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00

Nach dem Speichern müsste die Datei nun "550 Byte"-groß sein.

Größe
  2 Byte für die Befehlsnummer vom Befehl "call"
+ 4 Byte für die Adresse
= 6 Byte für den kompletten Maschinenbefehl

das Programm beenden
Allgemeines
Das war soweit fast der komplette Maschinencode. Was noch übrig bleibt, ist das ordnungsgemäße Beenden vom Programm.

Das Lade-Programm von Windows legt hierfür eine Adresse auf den Stapel. Nachdem alle Daten, welche das Programm auf den Stapel geladen hat, wieder vom Stapel gelöscht wurden - was nun der Fall ist - liegt diese Adresse ganz "oben" auf dem Stapel.

Die Adresse zeigt zu Maschinencode von der Bibliothek "kernel32.dll" welcher das Folgende bewirkt:
push(extended accumulator (eax))
call(ExitThread)
Diese Bibliothek läd das Lade-Programm immer ins Segment von der Anwendung, also unabhängig davon, ob man irgendetwas aus dieser Bibliothek importiert hat.

Aus diesem Grund kann diese Funktion aufgerufen werden, indem man den Befehl "return" ("ret") verwendet. Dieser Befehl läd die Adresse vom Stapel und löscht sie vom Stapel. Anschließend wird die Adresse ins Befehlszeigerregister kopiert, damit an der Adresse die Maschinencode-Ausführung fortgesetzt wird.

Die Funktion "ExitThread" ist eine von den ganz wenigen Funktionen, welche keine Rücksprungadresse benötigt. Sie benötigt keine Rücksprungadresse, weil nicht zurückgesprungen wird.

Die Funktion hat allerdings 1 Parameter:
ExitThread(
    Ziel_-_Exitcode
)

Um die Funktion ordnungsgemäß zu beenden, muss der Wert "0" für den Parameter "Ziel_-_Exitcode" verwendet werden, was bedeutet, dass das Programm ohne einen Fehler beendet wurde. Der oben genannte Maschinencode von der Bibliothek "kernel32.dll" läd den Wert vom Allzweckregister "extended accumulator" ("eax") auf den Stapel. Somit dient der Wert aus diesem Register als Wert für den Parameter "Ziel_-_Exitcode".

Unglücklicherweise befindet sich in diesem Register nicht der Wert "0", sondern der Rückgabewert von der Funktion "WriteConsoleA", da wir diese eben aufgerufen haben. Der Rückgabewert ist die Anzahl der Zeichen, welche mit der Hilfe vom Funktionsdurchlauf tatsächlich in die Konsole übertragen wurden. Es wird also mit hoher Wahrscheinlichkeit der Wert "11" auf den Stapel geladen.

Da in unserem Fall kein Programm diesen Wert auswertet, verzichte ich in dieser "Schritt für Schritt"-Anweisung auf einen weiteren Schritt, mit dessen Hilfe der Wert "0" ins Allzweckregister "extended accumulator" ("eax") geladen wird.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                            C3 rot hinterlegt: die Befehlsnummer vom Befehl "return"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3

Nach dem Speichern müsste die Datei nun "551 Byte"-groß sein.

Größe
  1 Byte für die Befehlsnummer vom Befehl "return"
= 1 Byte für den kompletten Maschinenbefehl

den unbenutzten Zwischenraum füllen
Allgemeines
Da die Datei nun "551 Byte"-groß ist, wurden soweit die Bytes "0" bis "550" mit Werten gefüllt. Es wird allerdings erwartet, dass der 0. Programmabschnitt-Inhalt "512 Byte"-groß ist und damit erst beim Byte "1.023" endet.

Aus diesem Grund muss ein Zwischenraum geschaffen werden, damit der 0. Programmabschnitt-Inhalt auch tatsächlich erst beim Byte "1.023" endet und nicht schon beim Byte "550".

Ich werde alle Bytes vom Zwischenraum auf "90|h" setzen. Der Wert "90|h" ist der "1 Byte"-große Maschinenbefehl "no operation" ("nop").

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                               90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
rot hinterlegt: der unbenutzte Zwischenraum

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90

Nach dem Speichern müsste die Datei nun "1.024 Byte"-groß sein.

Größe
Der Zwischenraum füllt die Bytes "551" bis "1.023" und ist somit "473 Byte"-groß.

Übersicht
Dies war soweit der komplette 0. Programmabschnitt-Inhalt:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
rot hinterlegt: WriteConsoleA - "unbenutzt" → Stapel
gelb hinterlegt: WriteConsoleA - "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" → Stapel
grün hinterlegt: WriteConsoleA - "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" → Stapel
blau hinterlegt: WriteConsoleA - "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" → Stapel
lila hinterlegt: GetStdHandle - "Quelle_-_Konsole_-_Datenkanal_-_Art" → Stapel
rot hinterlegt: GetStdHandle - die Funktion aufrufen
gelb hinterlegt: WriteConsoleA - "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" → Stapel
grün hinterlegt: WriteConsoleA - die Funktion aufrufen
blau hinterlegt: der Befehl "return", um das Programm zu beenden
lila hinterlegt: der unbenutzte Zwischenraum

1. Programmabschnitt-Inhalt

Dieser Programmabschnitt-Inhalt verfügt über die folgenden Inhalte:
  1. Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll"
  2. "Hallo Welt!"-Zeichenkette

die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird der 0. Inhalt in den 1. Programmabschnitt-Inhalt eingefügt. Die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode wird also direkt am Anfang platziert.

In ihr werden insgesamt 3 Einträge sein:
Die Werte von den einzelnen Einträgen werden dann später vom Lade-Programm von Windows während dem Lade-Vorgang im Segment überschrieben. Die Werte von den Einträgen auf der Festplatte ändern sich dadurch nicht.

Ich werde die beiden Funktionen
  • nicht anhand von ihren fortlaufenden Nummern,
  • sondern anhand von ihren Namen
importieren. Die Bits mit der Wertigkeit "231" von den ersten beiden Einträgen werde ich daher auf "0" setzen.

Die Bits mit den Wertigkeiten "20" bis "230" geben dann den Offset in Byte an,

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 rot hinterlegt: der 0. Eintrag
gelb hinterlegt: der 1. Eintrag
grün hinterlegt: der 2. Eintrag

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.036 Byte"-groß sein.

Größe
3 Einträge * 4 Byte pro Eintrag
= 12 Byte für die komplette Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode

die "Hallo Welt!"-Zeichenkette schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird die "Hallo Welt!"-Zeichenkette in den Programmabschnitt-Inhalt eingefügt.

Diese Zeichenkette muss nicht mit einem Abschluss"zeichen" abgeschlossen werden, von welchem alle Bits auf "0" gesetzt sind, da beim Aufruf von der "WriteConsoleA"-Funktion als Parameter angegeben wurde, wieviele Zeichen in die Konsole übertragen werden (also wieviele Zeichen ausgegeben werden) sollen.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21
rot hinterlegt: die "Hallo Welt!"-Zeichenkette

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21

Nach dem Speichern müsste die Datei nun "1.047 Byte"-groß sein.

Größe
Die Zeichenkette ist "11 Byte"-groß.

den unbenutzten Zwischenraum füllen
Allgemeines
Da die Datei nun "1.047 Byte"-groß ist, wurden soweit die Bytes "0" bis "1.046" mit Werten gefüllt. Der 2. Programmabschnitt-Inhalt (von "0" ausgehend gezählt) soll allerdings erst beim Byte "1.536" beginnen.

Aus diesem Grund muss ein Zwischenraum geschaffen werden, damit der 2. Programmabschnitt-Inhalt auch tatsächlich erst beim Byte "1.536" beginnt und nicht schon beim Byte "1.047".

Ich werde alle Bits vom Zwischenraum auf "0" setzen.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                               00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: der unbenutzte Zwischenraum

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.536 Byte"-groß sein.

Größe
Der Zwischenraum füllt die Bytes "1.047" bis "1.535" und ist somit "489 Byte"-groß.

Übersicht
Dies war soweit der komplette 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt):
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
gelb hinterlegt: die "Hallo Welt!"-Zeichenkette
grün hinterlegt: der unbenutzte Zwischenraum

2. Programmabschnitt-Inhalt

Dieser Programmabschnitt-Inhalt verfügt über die folgenden Inhalte:
  1. Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. Tabellenverzeichnis für Import-Tabellen
  3. "kernel32.dll\0"-Zeichenkette

die Import-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird der 0. Inhalt in den 2. Programmabschnitt-Inhalt (von "0" ausgehend gezählt) eingefügt. Die Import-Tabelle für Zeichenketten von Namen wird also direkt am Anfang platziert.

Sie ist nicht zwangsläufig eine zusammenhängende Auflistung von Einträgen, da die einzelnen Einträge auch quer über die komplette Datei verstreut sein können, da die Position von jedem einzelnen Eintrag in der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode angegeben wurde. Aus diesem Grund ist es auch nicht notwendig, das "Ende" von der Import-Tabelle für Zeichenketten von Namen zu kennzeichnen.

Ich werde, der Übersicht halber, die beiden Einträge für die Funktionen
  • "GetStdHandle" und
  • "WriteConsoleA"
dennoch direkt hintereinander platzieren.

Für die einzelnen Felder von den beiden Einträgen werde ich die folgenden Werte verwenden:
Eintrag #: Feld
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561:
0 Hinweiswert für die Funktion "GetStdHandle" Hint 00 00
Zeichenkette für die Funktion "GetStdHandle" Name "GetStdHandle\0"
1 Hinweiswert für die Funktion "WriteConsoleA" Hint 00 00
Zeichenkette für die Funktion "WriteConsoleA" Name "WriteConsoleA\0"

Die echten Hinweiswerte können beispielsweise
Die nachgeschauten Werte gelten dann für eine spezifische Version vom Betriebssystem "Windows". Also zum Beispiel für "Windows experience".

Ich werde für beide Funktionen den Wert "0" angeben, sodass das Lade-Programm einen falschen Hinweis bekommt, wo sich die Zeichenkette in der Export-Tabelle für Zeichenketten von Namen befindet. Nachdem das Lade-Programm festgestellt hat, dass sich die Zeichenkette nicht an der 0. Stelle befindet, wird es die Einträge von der Export-Tabelle für Zeichenketten von Namen durchlaufen und die Zeichenketten abgleichen, um die Funktion zu finden.

Wenn
  • ich beispielsweise die Hinweiswerte angeben würde, welche in "Windows experience" stimmen,
dann
  • würde ich dem Lade-Programm falsche Hinweise geben, wenn das "Hallo Welt!"-Programm in einer anderen Version von Windows ausgeführt wird.

    Somit würden bei den anderen Versionen von Windows die Hinweiswerte zu keinem Geschwindigkeitsvorteil führen.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00
rot hinterlegt: der 0. Eintrag
gelb hinterlegt: der 1. Eintrag

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00

Nach dem Speichern müsste die Datei nun "1.567 Byte"-groß sein.

Größe
  15 Byte für den Eintrag für die Funktion "GetStdHandle"
+ 16 Byte für den Eintrag für die Funktion "WriteConsoleA"
= 31 Byte für die komplette Import-Tabelle für Zeichenketten von Namen

das Tabellenverzeichnis für Import-Tabellen schreiben
Allgemeines
Das Tabellenverzeichnis für Import-Tabellen wird
  • 1 Eintrag für die Bibliothek "kernel32.dll" haben und
  • 1 weiteren Abschluss-Eintrag, von welchem alle Bits auf "0" gesetzt sind, um das Ende von diesem Verzeichnis zu kennzeichnen.

Aus der Bibliothek "kernel32.dll" werden dann später die beiden Funktionen
  • "GetStdHandle" und
  • "WriteConsoleA"
importiert werden.

Für die einzelnen Felder vom 0. Eintrag (also von der 0. Importbeschreibung) werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
0 Byte als Offset zur Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für eine Sicherung (das heißt, dass sie nicht existiert) Import Lookup Table RVA 00 00 00 00
0 Sekunden seit 1. Januar 1970; wird eh nicht ausgewertet Time/Date Stamp 00 00 00 00
alle Bits vom unbekannten Feld auf "1" gesetzt Forwarder Chain FF FF FF FF
  12 Kilobyte (der Anfang von diesem Programmabschnitt-Inhalt
+ 31 Byte (die Größe von der Import-Tabelle für Zeichenketten von Namen)
+ 40 Byte (die Größe vom Tabellenverzeichnis für Import-Tabellen)
= 12.359 Byte als Offset zur Zeichenkette vom Bibliotheknamen
Name RVA 47 30 00 00
  8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt)
= 8 Kilobyte als Offset zur Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
Import Address Table RVA 00 02 00 00

Von den einzelnen Feldern vom 1. Eintrag (von "0" ausgehend gezählt) werde ich alle Bits auf "0" setzen.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                         00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00
rot hinterlegt: die 0. Importbeschreibung
gelb hinterlegt: die 1. Importbeschreibung

Geben Sie nun die endgültige Adresse vom Tabellenverzeichnis für Import-Tabellen im Tabellenverzeichnis für verschiedene Tabellen an:
000000C0: 1F 30 00 00 grün hinterlegt: der Offset in Byte,

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.607 Byte"-groß sein.

Größe
  20 Byte für die 0. Importbeschreibung
+ 20 Byte für die Abschluss-Importbeschreibung
= 40 Byte für das komplette Tabellenverzeichnis für Import-Tabellen

die "kernel32.dll\0"-Zeichenkette schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird
  • die Zeichenkette "kernel32.dll" angegeben und
  • ein weiteres Byte, von welchem alle Bits auf "0" gesetzt sind, um das Ende von der Zeichenkette zu kennzeichnen.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                               6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00
rot hinterlegt: die Zeichenkette "kernel32.dll"
gelb hinterlegt: das Abschlusszeichen

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00

Nach dem Speichern müsste die Datei nun "1.620 Byte"-groß sein.

Größe
  12 Byte für die Zeichenkette "kernel32.dll"
+  1 Byte für das Abschluss"zeichen"
= 13 Byte für die komplette Zeichenkette "kernel32.dll\0"

Übersicht
Das war soweit der komplette 2. Programmabschnitt-Inhalt (von "0" ausgehend gezählt) und die komplette "Hallo_Welt.exe"-Datei:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 98 00 0F 03 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 10 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 40 00 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 54 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 07 00 00 00 - 00 00 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000000F0: 2D 2D 70 2D 73 2D 2D 78 - 00 00 00 00 00 10 00 00
00000100: 00 02 00 00 00 02 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 20 00 00 30 - 2D 69 70 72 2D 2D 77 2D
00000120: 00 00 00 00 00 20 00 00 - 00 02 00 00 00 04 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 C0
00000140: 64 69 70 72 2D 2D 2D 2D - 00 00 00 00 00 30 00 00
00000150: 54 00 00 00 00 06 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 40 00 00 42 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 40 00 68 F5 FF FF - FF FF 15 00 20 40 00 50
00000220: FF 15 04 20 40 00 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00
rot hinterlegt: die Import-Tabelle für Zeichenketten von Namen
gelb hinterlegt: das Tabellenverzeichnis für Import-Tabellen
grün hinterlegt: die "kernel32.dll\0"-Zeichenkette

Nach dem letzten Programmabschnitt-Inhalt ist kein Zwischenraum notwendig, von welchem alle Bits beispielsweise auf "0|b" gesetzt sind. Der Programmabschnitt-Inhalt muss also nicht erweitert werden, bis seine Größe restlos durch die Größe von einer Seite teilbar ist. Bei einem Treiber ("*.sys"-Datei) wäre dies allerdings sehr wohl notwendig.

das Programm starten

Allgemeines

Sofern Sie die Datei ein letztes Mal gespeichert haben, dann kann sie jetzt mit einem Doppelklick oder über eine Konsole aufgerufen werden.

Obwohl ich einen recht langsamen Computer habe, schließt sich das Programm nach einem Doppelklick bei mir so schnell wieder, dass das "Hallo Welt!" meistens garnicht richtig angezeigt wird. Das schwarze Fenster von der Konsole wird auch nur teilweise angezeigt.

Um eine sich nicht selbst schließende Konsole zu starten, können Sie wie folgt vorgehen:
  1. Klicken Sie auf "Start".
  2. Klicken Sie im eben aufgesprungenen Startmenü auf "Ausführen...".
  3. Geben Sie "cmd.exe" ein und klicken Sie auf "OK". Dies wird die Datei "cmd.exe" aus dem "system32"-Verzeichnis starten. Also eine Eingabeaufforderung/eine Konsole.

Um anschließend die "Hallo_Welt.exe"-Datei von Ihrem Desktop zu starten, können Sie wie folgt vorgehen:
  1. Ziehen Sie die Datei per drag-und-drop in das Eingabeaufforderungs-Fenster. Dadurch wird für Sie der komplette Pfad an der Cursor-Position eingetragen, also so ähnlich, als hätten Sie den Pfad mit der Tastatur eingegeben.
  2. Drücken Sie auf "[Enter]".

Nun müsste das "Hallo Welt!" auf Ihrem Bildschirm bleiben, bis Sie die Konsole manuell schließen.


eine Bibliothek mit einer "Hallo Welt!"-Funktion

Beschreibung

Im Nachfolgenden wird Schritt für Schritt gezeigt, wie mit der Hilfe von eine Bibliothek ("*.dll"-Datei) geschrieben werden kann, welche eine Funktion enthält, welche "Hallo Welt!" ausgibt.

Die vollständige Datei, welche im Lauf von den folgenden Schritten entstehen wird, kann allerdings auch im Kapitel "weiteres Material zu diesem Thema - Bibliotheken" heruntergeladen werden.

Außerdem kann im Kapitel "weiteres Material zu diesem Thema - Programme" ein Programm heruntergeladen werden, welches die Funktion von der Bibliothek importiert und dann aufruft.

notwendige Voraussetzungen

siehe: hier

Vorbereitung

die Datei anlegen

siehe: hier

Anstatt dem Dateinamen "Hallo_Welt.exe", wie es in der verlinkten Beschreibung enthalten ist, soll stattdessen der Dateiname "Hallo_Welt.dll" verwendet werden.

die Datei öffnen

siehe: hier

Anmerkungen zum Speichern

siehe: hier

DOS-Abschnitt

siehe: hier

Schreiben Sie jedoch die Werte

Windows-Abschnitt

Kopfzeile

die Signatur schreiben

siehe: hier

die Datei-Kopfzeile schreiben

Allgemeines
Für die einzelnen Felder von diesem Abschnitt werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
x86er von Intel mit "32 Bit"-Architektur, also 386er, oder eine spätere, darauf basierende Architektur Machine 4C 01 - -
3 Programmabschnitte NumberOfSections 03 00 - -
0 Sekunden seit 1. Januar 1970; wird eh nicht ausgewertet TimeDateStamp 00 00 00 00
keine Symboltabelle PointerToSymbolTable 00 00 00 00
keine Symbole in der Symboltabelle NumberOfSymbols 00 00 00 00
  96 Byte für die zusätzliche Kopfzeile
+ 16 Byte für das Tabellenverzeichnis für verschiedene Tabellen (da sie 2 "8 Byte"-große Einträge haben wird)
= 112 Byte
SizeOfOptionalHeader 70 00 - -
Die einzelnen Bits werden wie folgt gesetzt:
Bedeutung: Wert: Wertigkeit:
Wenn
  • die Datei nicht an der gewünschten Stelle im Segment platziert werden kann,
dann
  • soll der Lade-Vorgang abgebrochen werden.

Bei einer Bibliothek würde der Wert von diesem Bit normalerweise auf "0|b" gesetzt werden. Damit würde der Lade-Vorgang nicht abgebrochen werden. Für diese Bibliothek werden jedoch keine Adressenreparaturen durchgeführt, obwohl dies sonst üblich ist. Aus diesem Grund muss die Bibliothek an die angegebene Adresse geladen werden, ansonsten stimmt die Adresse zur "Hallo Welt!"-Zeichenkette nicht.
1 20
Die Datei kann verwendet werden. 1 21
Es sind keine Informationen über die Zeilennummer vorhanden. 1 22
Es sind keine Informationen über lokale Symbole vorhanden. 1 23
Der belegte Arbeitsspeicher soll nicht auf die Festplatte ausgelagert werden. 0 24
Das Programm kann keine Adressen handhaben, welche über 31 Bit lang sind.

Ich habe keine Ahnung, was das bewirkt. Aber weil es in allen anderen ausführbaren Dateien, welche ich mir angeschaut hatte, auch so gemacht ist, mache ich es auch so.
0 25
unbenutzt 0 26
veraltet 0 27

Die Architektur muss eine "32 Bit"-Architektur, oder eine darauf basierende Architektur, sein. 1 28
Es sind keine Hilfs-Informationen für eine Fehersuche vorhanden. 1 29
Das Programm darf auch von einem Wechselmedium ausgeführt werden. 0 210
Das Programm darf auch über ein Netzwerk ausgeführt werden. 0 211
Diese Datei ist
  • weder eine Systemdatei vom Betriebssystem
  • noch ein Treiber.
0 212
Die Datei ist eine Bibliothek. 1 213
Die Datei darf auch auf einem "ACPI-Multiprocessor-PC" ausgeführt werden. 0 214
veraltet 0 215
Characteristics 0F 23 - -

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                      4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23
rot hinterlegt: der Wert für das Feld "Machine"
gelb hinterlegt: der Wert für das Feld "NumberOfSections"
grün hinterlegt: der Wert für das Feld "TimeDateStamp"
blau hinterlegt: der Wert für das Feld "PointerToSymbolTable"
lila hinterlegt: der Wert für das Feld "NumberOfSymbols"
rot hinterlegt: der Wert für das Feld "SizeOfOptionalHeader"
gelb hinterlegt: der Wert für das Feld "Characteristics"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23

Nach dem Speichern müsste die Datei nun "88 Byte"-groß sein.

Größe
  2 Byte für das Feld "Machine"
+ 2 Byte für das Feld "NumberOfSections"
+ 4 Byte für das Feld "TimeDateStamp"
+ 4 Byte für das Feld "PointerToSymbolTable"
+ 4 Byte für das Feld "NumberOfSymbols"
+ 2 Byte für das Feld "SizeOfOptionalHeader"
+ 2 Byte für das Feld "Characteristics"
= 20 Byte für die komplette Datei-Kopfzeile

die zusätzliche Kopfzeile schreiben

Allgemeines
Für die einzelnen Felder von diesem Abschnitt werde ich die folgende Werten verwenden
Beschreibung: Bezeichnung: Hexadezimalwert:
2560: 2561: 2562: 2563:
Dateiformat "32 Bit portable executable" ("pe32") Magic 0B 01 - -
Hauptversion "0" vom Link-Programm; wird eh nicht ausgewertet MajorLinkerVersion 00 - - -
Unterversion "0" vom Link-Programm; wird eh nicht ausgewertet MinorLinkerVersion 00 - - -
0 Byte für die Größe vom ausführbaren Code von allen Programmabschnitt-Inhalten zusammengerechnet; wird eh nicht ausgewertet SizeOfCode 00 00 00 00
0 Byte für die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet, welche bereits beim Programmstart mit Werten definiert sind; wird eh nicht ausgewertet SizeOfInitializedData 00 00 00 00
0 Byte für die Größe von den Daten von allen Programmabschnitt-Inhalten zusammengerechnet, die erst zur Laufzeit zum ersten Mal mit Werten definiert werden; wird eh nicht ausgewertet SizeOfUninitializedData 00 00 00 00
0 Byte als Offset zum Maschinencode, welcher nach dem Laden von der Bibliothek ausgeführt werden soll

Das heißt, dass keine solche Initialisierungsroutine existiert.
AddressOfEntryPoint 00 00 00 00
0 Byte als Offset zum Anfang vom Maschinencode; wird eh nicht ausgewertet BaseOfCode 00 00 00 00
0 Byte als Offset zu den Daten, welche bereits beim Programmstart mit Werten definiert sind; wird eh nicht ausgewertet BaseOfData 00 00 00 00
256 Megabyte als Anfangsadresse, wo die Bibliothek im Segment platziert werden soll.

Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.
ImageBase 00 00 00 10
4 Kilobyte als Seitengröße von einem Programmabschnitt-Inhalt im Arbeitsspeicher SectionAlignment 00 10 00 00
512 Byte als Seitengröße von einem Programmabschnitt-Inhalt auf der Festplatte FileAlignment 00 02 00 00
Hauptversion "0" vom notwendigen Betriebssystem; wird eh nicht ausgewertet MajorOperatingSystemVersion 00 00 - -
Unterversion "0" vom notwendigen Betriebssystem; wird eh nicht ausgewertet MinorOperatingSystemVersion 00 00 - -
Hauptversion "0" von diesem "Hallo Welt!"-Programm; wird eh nicht ausgewertet MajorImageVersion 00 00 - -
Unterversion "0" von diesem "Hallo Welt!"-Programm; wird eh nicht ausgewertet MinorImageVersion 00 00 - -
Hauptversion "4" vom notwendigen Betriebssystem; wird ausgewertet MajorSubsystemVersion 04 00 - -
Unterversion "0" vom notwendigen Betriebssystem; wird ausgewertet MinorSubsystemVersion 00 00 - -
alle unbenutzten Bits auf "0" gesetzt Win32VersionValue 00 00 00 00
    3 * 4 Kilobyte für die 3 ersten RAM-Seiten
+ 154 Byte für die letzte RAM-Seite mit dem letzten Programmabschnitt-Inhalt
= 12.442 Byte als Gesamtgröße von der Datei im Arbeitsspeicher
SizeOfImage 9A 30 00 00
512 Bytes für die Größe vom
  DOS-Abschnitt
+ Kopfzeile vom Windows-Abschnitt
+ Kopfzeilen-Tabelle
auf die nächsten 512 Bytes aufgerundet

bei uns ist bei einem "2 Einträge"-großen Tabellenverzeichnis für verschiedene Tabellen und einer "4 Einträge"-großen Kopfzeilen-Tabelle der unaufgerundete Wert "360 Byte"
SizeOfHeaders 00 02 00 00
alle Bits von der Prüfsumme auf "0" gesetzt; wird eh nicht ausgewertet CheckSum 00 00 00 00
benötigtes Untersystem: Konsole (Eingabeaufforderung) Subsystem 03 00 - -
alle Flaggen auf "0" gesetzt; die Bedeutung von den Flaggen ist mir noch recht unklar daher mache ich es so, wie es die meisten Link-Programme machen DllCharacteristics 00 00 - -
256 Kilobyte als maximale Stapelgröße SizeOfStackReserve 00 00 04 00
4 Kilobyte als Anfangsgröße vom Stapel SizeOfStackCommit 00 10 00 00
0 KB als maximale Haufengröße; wird eh nicht ausgewertet SizeOfHeapReserve 00 00 00 00
0 KB als Anfangsgröße vom Haufen; wird eh nicht ausgewertet SizeOfHeapCommit 00 00 00 00
alle unbenutzten Bits auf "0" gesetzt LoaderFlags 00 00 00 00
2 Einträge im Tabellenverzeichnis für verschiedene Tabellen NumberOfRvaAndSizes 02 00 00 00

Die einzelnen Programmabschnitt-Inhalte sind alle kleiner als 512 Byte und damit auch kleiner als 4 Kilobyte. Dadurch ist für jeden Programmabschnitt-Inhalt nur 1 Seite notwendig.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                    0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00
rot hinterlegt: der Wert vom Feld "Magic"
gelb hinterlegt: der Wert vom Feld "MajorLinkerVersion"
grün hinterlegt: der Wert vom Feld "MinorLinkerVersion"
blau hinterlegt: der Wert vom Feld "SizeOfCode"
lila hinterlegt: der Wert vom Feld "SizeOfInitializedData"
rot hinterlegt: der Wert vom Feld "SizeOfUninitializedData"
gelb hinterlegt: der Wert vom Feld "AddressOfEntryPoint"
grün hinterlegt: der Wert vom Feld "BaseOfCode"
blau hinterlegt: der Wert vom Feld "BaseOfData"
lila hinterlegt: der Wert vom Feld "ImageBase"
rot hinterlegt: der Wert vom Feld "SectionAlignment"
gelb hinterlegt: der Wert vom Feld "FileAlignment"
grün hinterlegt: der Wert vom Feld "MajorOperatingSystemVersion"
blau hinterlegt: der Wert vom Feld "MinorOperatingSystemVersion"
lila hinterlegt: der Wert vom Feld "MajorImageVersion"
rot hinterlegt: der Wert vom Feld "MinorImageVersion"
gelb hinterlegt: der Wert vom Feld "MajorSubsystemVersion"
grün hinterlegt: der Wert vom Feld "MinorSubsystemVersion"
blau hinterlegt: der Wert vom Feld "Win32VersionValue"
lila hinterlegt: der Wert vom Feld "SizeOfImage"
rot hinterlegt: der Wert vom Feld "SizeOfHeaders"
gelb hinterlegt: der Wert vom Feld "CheckSum"
grün hinterlegt: der Wert vom Feld "Subsystem"
blau hinterlegt: der Wert vom Feld "DllCharacteristics"
lila hinterlegt: der Wert vom Feld "SizeOfStackReserve"
rot hinterlegt: der Wert vom Feld "SizeOfStackCommit"
gelb hinterlegt: der Wert vom Feld "SizeOfHeapReserve"
grün hinterlegt: der Wert vom Feld "SizeOfHeapCommit"
blau hinterlegt: der Wert vom Feld "LoaderFlags"
lila hinterlegt: der Wert vom Feld "NumberOfRvaAndSizes"

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00

Nach dem Speichern müsste die Datei nun "184 Byte"-groß sein.

Größe
  2 Byte für das Feld "Magic"
+ 1 Byte für das Feld "MajorLinkerVersion"
+ 1 Byte für das Feld "MinorLinkerVersion"
+ 4 Byte für das Feld "SizeOfCode"
+ 4 Byte für das Feld "SizeOfInitializedData"
+ 4 Byte für das Feld "SizeOfUninitializedData"
+ 4 Byte für das Feld "AddressOfEntryPoint"
+ 4 Byte für das Feld "BaseOfCode"
+ 4 Byte für das Feld "BaseOfData"
+ 4 Byte für das Feld "ImageBase"
+ 4 Byte für das Feld "SectionAlignment"
+ 4 Byte für das Feld "FileAlignment"
+ 2 Byte für das Feld "MajorOperatingSystemVersion"
+ 2 Byte für das Feld "MinorOperatingSystemVersion"
+ 2 Byte für das Feld "MajorImageVersion"
+ 2 Byte für das Feld "MinorImageVersion"
+ 2 Byte für das Feld "MajorSubsystemVersion"
+ 2 Byte für das Feld "MinorSubsystemVersion"
+ 4 Byte für das Feld "Win32VersionValue"
+ 4 Byte für das Feld "SizeOfImage"
+ 4 Byte für das Feld "SizeOfHeaders"
+ 4 Byte für das Feld "CheckSum"
+ 2 Byte für das Feld "Subsystem"
+ 2 Byte für das Feld "DllCharacteristics"
+ 4 Byte für das Feld "SizeOfStackReserve"
+ 4 Byte für das Feld "SizeOfStackCommit"
+ 4 Byte für das Feld "SizeOfHeapReserve"
+ 4 Byte für das Feld "SizeOfHeapCommit"
+ 4 Byte für das Feld "LoaderFlags"
+ 4 Byte für das Feld "NumberOfRvaAndSizes"
= 96 Byte für die komplette zusätzliche Kopfzeile

das Tabellenverzeichnis für verschiedene Tabellen schreiben

Allgemeines
Um die Funktion, welche "Hallo Welt!" ausgibt, für den Export zu markieren, werde ich angeben, dass der 0. Eintrag im Tabellenverzeichnis für verschiedene Tabellen existiert. Dieser Eintrag ist für das Tabellenverzeichnis für Export-Tabellen. Es wird im 2./letzten Programmabschnitt-Inhalt (von "0" ausgehend gezählt) platziert werden, jedoch nicht direkt am Anfang.

Damit später "Hallo Welt!" ausgegeben werden kann, werde ich hierfür die Funktion "WriteConsoleA" von der Windows-API benutzen. Dieser Funktion muss man als einen von den Parametern angeben, in welche Konsole (in welches Eingabeaufforderungs-Fenster) etwas geschrieben werden soll. Um dies herauszufinden, werde ich die Funktion "GetStdHandle" benutzen.

Im Kapitel "weiteres Material zu diesem Thema - Dokumente" ist ein Dokument aufgelistet, welches diese Funktionen von der Windows-API beschreibt.

Damit die beiden Funktionen später jeweils mit der Hilfe vom Befehl "call" benutzt werden können, muss das Lade-Programm die Bibliothek "kernel32.dll" in den Arbeitsspeicher laden und anschließend die beiden Einsprungadressen zu den Funktionen bereitstellen.

Daher wird mit der Hilfe vom 1. Eintrag (von "0" ausgehend gezählt) vom Tabellenverzeichnis für verschiedene Tabellen angegeben, dass das Tabellenverzeichnis für Import-Tabellen existiert. Es wird im 2./letzten Programmabschnitt-Inhalt platziert werden und ebenfalls nicht direkt am Anfang.

Als Größe für diese beiden Tabellenverzeichnisse werde ich jeweils "0 Byte" angeben, da diese Größenangaben ohnehin nicht ausgewertet werden.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                    ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00
rot hinterlegt: 0. Eintrag (für das Tabellenverzeichnis für Export-Tabellen)
gelb hinterlegt: 1. Eintrag (für das Tabellenverzeichnis für Import-Tabellen)

Später, wenn
  • die exakten Adressen bekannt sind,
dann
  • werden die Fragezeichen ersetzt.

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "200 Byte"-groß sein.

Größe

2 Einträge * 8 Byte pro Eintrag
= 16 Byte für das komplette Tabellenverzeichnis für verschiedene Tabellen

Übersicht

Das war soweit die komplette Kopfzeile vom Windows-Abschnitt:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00
rot hinterlegt: die Signatur
gelb hinterlegt: die Datei-Kopfzeile
grün hinterlegt: die zusätzliche Kopfzeile
blau hinterlegt: das Tabellenverzeichnis für verschiedene Tabellen

Programmabschnitte

die Kopfzeilen-Tabelle schreiben

Allgemeines
Später werden 3 Programmabschnitt-Inhalte verwendet, daher wird die Kopfzeilen-Tabelle von den Programmabschnitten 3 Einträge enthalten.

Um
  • die Funktion zu speichern, welche "Hallo Welt!" ausgibt,
  • den Export zu definieren und
  • die Importe zu definieren,
werden ich die folgenden Inhalte in die Programmabschnitt-Inhalte speichern:
#: Größe: Inhalte: Name: Offset vom
Anfang von der Datei: ersten Byten, welches die Datei im Segment belegt:
0
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
  1. Maschinencode von der Funktion zum Ausgeben von der "Hallo Welt!"-Zeichenkette
--p-s--x
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
Schreibweise: Wert:
binär 1 0000 0000 0000 Byte
dezimal 4.096 Byte
hexadezimal 10 00 Byte
1
Schreibweise: Wert:
binär 10 0000 0000 Byte
dezimal 512 Byte
hexadezimal 2 00 Byte
  1. Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll"
  2. "Hallo Welt!"-Zeichenkette
-ipr--w-
Schreibweise: Wert:
binär 100 0000 0000 Byte
dezimal 1.024 Byte
hexadezimal 4 00 Byte
Schreibweise: Wert:
binär 10 0000 0000 0000 Byte
dezimal 8.192 Byte
hexadezimal 20 00 Byte
2
Schreibweise: Wert:
binär 1001 1010 Byte
dezimal 154 Byte
hexadezimal 9A Byte
  1. Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. Tabellenverzeichnis für Import-Tabellen
  3. "kernel32.dll\0"-Zeichenkette
  4. Export-Tabelle für Adressen von Dingen
  5. Export-Tabelle für Adressen von Zeichenketten von Namen
  6. Export-Tabelle für Positionen von Adressen von Dingen
  7. Export-Tabelle für Zeichenketten von Namen
  8. Tabellenverzeichnis für Export-Tabellen
dipr----
Schreibweise: Wert:
binär 110 0000 0000 Byte
dezimal 1.536 Byte
hexadezimal 6 00 Byte
Schreibweise: Wert:
binär 11 0000 0000 0000 Byte
dezimal 12.288 Byte
hexadezimal 30 00 Byte

Für die einzelnen Felder von jedem Eintrag in der Kopfzeilen-Tabelle werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
der Name entsprechend der obigen Tabelle Name
0 Byte als Größe von den genutzten Bytes vom Programmabschnitt-Inhalt; wird eh nicht ausgewertet VirtualSize 00 00 00 00
Der Offset vom ersten Byte, welches die Datei im Segment belegen soll, bis zum Anfang vom Programmabschnitt-Inhalt, wenn er ins Segment geladen wurde, entsprechend der obigen Tabelle. VirtualAddress
die Größe entsprechend der obigen Tabelle SizeOfRawData
Der Offset vom Anfang von der Datei bis zum Anfang vom Programmabschnitt-Inhalt, solange er noch auf der Festplatte ist, entsprechend der obigen Tabelle.. PointerToRawData
alle unbenutzten Bits auf "0" gesetzt PointerToRelocations 00 00 00 00
PointerToLinenumbers 00 00 00 00
NumberOfRelocations 00 00 - -
NumberOfLinenumbers 00 00 - -
Die Flaggen entsprechend dem Namen; siehe: Namensgebung von einem spezifischen Programmabschnitt.

Für die Zeichenkette "Hallo Welt!" ist die Schreibberechtigung ("??????w?") nicht notwendig. Es ist allerdings universeller, für die Daten/Variablen eine Schreibberechtigung zu geben. So muss man nicht bei jeder Datei/jedem Projekt prüfen, ob die Daten/Variablen beschreibbar sein müssen.
Characteristics

Änderung
Erweitern Sie die Datei um die folgenden Werte:
000000C0:                           2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
rot hinterlegt: der 0. Eintrag/Kopfzeile
gelb hinterlegt: der 1. Eintrag/Kopfzeile
grün hinterlegt: der 2. Eintrag/Kopfzeile

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42

Nach dem Speichern müsste die Datei nun "320 Byte"-groß sein.

Größe
3 Einträge * 40 Byte pro Eintrag
= 120 Byte für die komplette Kopfzeilen-Tabelle

den unbenutzten Zwischenraum füllen

Allgemeines
Da die Datei nun "320 Byte"-groß ist, wurden soweit die Bytes "0" bis "319" mit Werten gefüllt. Der 0. Programmabschnitt-Inhalt soll allerdings erst beim Byte "512" beginnen.

Aus diesem Grund muss ein Zwischenraum geschaffen werden, damit der 0. Programmabschnitt-Inhalt auch tatsächlich erst beim Byte "512" beginnt und nicht schon beim Byte "320".

Ich werde alle Bits vom Zwischenraum auf "0" setzen.

Ein derartiger Zwischenraum wird im Englischen "cave" genannt.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: der unbenutzte Zwischenraum

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "512 Byte"-groß sein.

Größe
Der Zwischenraum füllt die Bytes "320" bis "511" und ist somit "192 Byte"-groß.

0. Programmabschnitt-Inhalt

die Funktion "WriteConsoleA"
den Wert vom Parameter "unbenutzt" auf den Stapel legen
Allgemeines
Im 0. Programmabschnitt-Inhalt ist im Wesentlichen der Maschinencode von der Funktion, welche die "Hallo Welt!"-Zeichenkette ausgeben kann.

siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00

Nach dem Speichern müsste die Datei nun "517 Byte"-groß sein.

Sie können nach diesem Schritt das Programm "DumpPE" mit der Option "-disasm" über Ihre "Hallo_Welt.dll"-Datei laufen lassen. Sie werden dann sehen, dass das Programm versucht hat Ihre "Hallo_Welt.dll"-Datei zu disassemblieren. Somit wird Ihnen "push 0" angezeigt.

Die folgenden Zeilen ("add [eax], al") kommen zustande, wenn man lauter Bytes disassembliert, von welchen alle Bits auf "0" gesetzt sind. Das Programm geht davon aus, dass der Programmabschnitt-Inhalt "512 Byte"-groß ist.

Geben Sie dazu beispielsweise in eine Konsole (in ein Eingabeaufforderungs-Fenster) etwas wie Folgendes ein:
"C:\DumpPE.exe" -disasm "C:\Hallo_Welt.dll"

Größe
siehe: hier

den Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Mit der Hilfe von diesem Schritt wird der Wert vom Parameter "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" auf den Stapel gelegt.

Der Wert gibt eine Speicherstelle im Segment von der Anwendung und damit auch von der Bibliothek "Hallo_Welt" an. An dieser Speicherstelle würde die Funktion "WriteConsoleA" die Anzahl der Zeichen speichern, welche mit der Hilfe vom Funktionsdurchlauf tatsächlich in die Konsole übertragen wurden.

Da ich davon ausgehe, dass alle Zeichen übertragen werden können und ich diesen Wert ohnehin nicht auswerte, werde ich den Wert "0" als Adresse angeben. Dieser bedeutet, dass die Funktion die Anzahl nicht speichern soll.

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00

Nach dem Speichern müsste die Datei nun "522 Byte"-groß sein.

Größe
siehe: hier

den Wert vom Parameter "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" auf den Stapel legen
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00

Nach dem Speichern müsste die Datei nun "527 Byte"-groß sein.

Größe
siehe: hier

den Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel legen
Allgemeines
Mit der Hilfe von diesem Schritt wird der Wert vom Parameter "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" auf den Stapel gelegt.

Der Wert gibt eine Speicherstelle im Segment von der Anwendung und damit auch von der Bibliothek "Hallo_Welt" an. Es handelt sich bei dieser Adresse um einen Offset vom Anfang vom Segment.

An der Speicherstelle beginnt die "Hallo Welt!"-Zeichenkette.

Der Wert von diesem Parameter ist
  256 Megabyte (die Adresse, an welche die Datei im Segment platziert wird)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt)
+ 12 Byte (Größe von der "2 + 1 Einträge"-großen Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll")
= 268.443.660 Byte.

Bei einer Bibliothek wird normalerweise eine Tabelle für Adressen-Reparaturen verwendet, um sicherzustellen, dass die Adresse zur Laufzeit von der Anwendung stimmt. In unserem Fall kann die Bibliothek allerdings an der gewünschten Adresse "256 Megabyte" platziert werden. Daher ist die Adressen-Reparatur nicht notwendig.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                         68
00000210: 0C 20 00 10
rot hinterlegt: die Befehlsnummer vom Befehl "push"
gelb hinterlegt: der Wert

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10

Nach dem Speichern müsste die Datei nun "532 Byte"-groß sein.

Größe
siehe: hier

die Funktion "GetStdHandle"
den Wert vom Parameter "Quelle_-_Konsole_-_Datenkanal_-_Art" auf den Stapel legen
Allgemeines
Bevor der Wert vom nächsten Parameter von der Funktion "WriteConsoleA" auf den Stapel gelegt werden kann, muss er zuerst ermittelt werden.

Der nächste Parameter von dieser Funktion ist eine Identifikationskennung von einem Datenkanal von einer Konsole.

  • Zum Einen muss also die Konsole ausgewählt werden, da zur Laufzeit vom Programm mehrere Konsolen offen sein können und ein Programm theoretisch auch in eine Konsole von einem anderen Programm schreiben kann und
  • zum Anderen muss die Art vom Datenkanal ausgewählt werden, da jede Konsole mehrere Datenkanäle anbietet. Die Konsole, welche einem Programm beim Lade-Vorgang zugewiesen wird, hat 3 Datenkanäle:
    • Einen Datenkanal um Daten auszugeben.

      Dieser wird normalerweise von einem Programm beschrieben.
    • Einen Datenkanal um Daten einzulesen.

      Dieser wird normalerweise vom Benutzer durch eine Tastatureingabe beschrieben und von einem Programm ausgelesen. Er kann allerdings auch von einem Programm beschrieben werden und von einem anderen Programm ausgelesen werden.
    • Einen Datenkanal um Fehlermeldungen auszugeben.

Im Schritt "Windows-Abschnitt - Kopfzeile - die zusätzliche Kopfzeile schreiben" haben wir angegeben, dass eine Konsole als Untersystem benötigt wird. Daher wird dem Programm, welches diese Bibliothek einbindet, automatisch eine Konsole nach dem Starten zugewiesen.

Wenn
  • das Programm mit der Hilfe von einer Konsole (einem Eingabeaufforderungs-Fenster) gestartet wurde,
dann
  • wird diese Konsole dem Programm zugewiesen. Diese bleibt nach dem Beenden vom Programm geöffnet, sodass, wenn die Funktion "Hallo_Welt_ausgeben" benutzt wurde, auch das "Hallo Welt!" auf dem Bildschirm bleibt.
Ansonsten wenn
  • das Programm mit der Hilfe von einen Doppelklick gestartet wurde,
dann
  • wird für das Programm eine neue Konsole gestartet. Diese wird nach dem Beenden vom Programm automatisch wieder geschlossen. Damit erscheint das "Hallo Welt!" nur ganz kurz auf dem Bildschirm und verschwindet dann gleich wieder.

Um nun die zugewiesene Konsole zu ermitteln, kann die Funktion "GetStdHandle" verwendet werden.

Diese Funktion hat nur 1 Parameter:
GetStdHandle(
    Quelle_-_Konsole_-_Datenkanal_-_Art
)

Ich werde nun den Wert
Schreibweise: Wert:
binär
(gemäß Variablentyp "Ganzzahl mit Vorzeichen")
1111 0101 1111 1111 1111 1111 1111 1111
dezimal
(gemäß regulärer Schreibweise)
-11
hexadezimal
(gemäß Variablentyp "Ganzzahl mit Vorzeichen")
F5 FF FF FF
auf den Stapel legen, damit dieser als Wert für den Parameter dient und damit angegeben wird, dass die Funktion die Identifikationskennung vom Ausgabe-Datenkanal zurückgeben soll.

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF

Nach dem Speichern müsste die Datei nun "537 Byte"-groß sein.

Größe
siehe: hier

die Funktion aufrufen
Allgemeines
siehe: hier

Jedoch ist die Adresse von der Speicherstelle, dessen Wert angibt, wo die Funktion beginnt, die Folgende:
  256 Megabyte (die Adresse, an welcher die Bibliothek im Segment platziert wurde)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt))
= 268.443.648 Byte

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                       FF 15 00 20 00 10 rot hinterlegt: die Befehlsnummer vom Befehl "call"
gelb hinterlegt: die Adresse

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10

Nach dem Speichern müsste die Datei nun "543 Byte"-groß sein.

Größe
siehe: hier

die Funktion "WriteConsoleA"
den Wert vom Parameter "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" auf den Stapel legen
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50

Nach dem Speichern müsste die Datei nun "544 Byte"-groß sein.

Größe
siehe: hier

die Funktion aufrufen
Allgemeines
siehe: hier

Jedoch ist die Adresse von der Speicherstelle, dessen Wert angibt, wo die Funktion beginnt, die Folgende:
  256 Megabyte (die Adresse, an welcher die Bibliothek im Segment platziert wurde)
+ 8 Kilobyte (der Anfang vom 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt))
+ 4 Byte (die Größe vom 0. Eintrag in der Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode)
= 268.443.652 Byte

Änderung
Erweitern Sie die Datei um die folgenden Werte:
00000220: FF 15 04 20 00 10 rot hinterlegt: "call"-Befehl
gelb hinterlegt: Adresse

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10

Nach dem Speichern müsste die Datei nun "550 Byte"-groß sein.

Größe
siehe: hier

zurückkehren
Allgemeines
Das war soweit fast die komplette "Hallo_Welt_ausgeben"-Funktion. Damit das Programm, welches die Funktion aufruft, allerdings nicht wegen dem Aufruf abstürzt, werde ich noch den Befehl "return" ("ret") anhängen.

Dieser Befehl läd die Rücksprungadresse vom Stapel und löscht sie vom Stapel. Anschließend wird die Rücksprungadresse ins Befehlszeigerregister kopiert, damit an der Rücksprungadresse die Maschinencode-Ausführung fortgesetzt wird. Also direkt nach der Stelle, an welcher mit der Hilfe vom Befehl "call" die Rücksprungadresse auf den Stapel geladen wurde und zu dieser "Hallo_Welt_ausgeben"-Funktion gesprungen wurde.

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3

Nach dem Speichern müsste die Datei nun "551 Byte"-groß sein.

Größe
siehe: hier

den unbenutzten Zwischenraum füllen
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90

Nach dem Speichern müsste die Datei nun "1.024 Byte"-groß sein.

Größe
siehe: hier

Übersicht
Dies war soweit der komplette 0. Programmabschnitt-Inhalt:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
rot hinterlegt: WriteConsoleA - "unbenutzt" → Stapel
gelb hinterlegt: WriteConsoleA - "Ziel_-_Nutzdaten_-_Länge_in_Zeichen_-_Adresse_-_Offset_in_Byte" → Stapel
grün hinterlegt: WriteConsoleA - "Quelle_-_Nutzdaten_-_Länge_in_Zeichen" → Stapel
blau hinterlegt: WriteConsoleA - "Quelle_-_Nutzdaten_-_Adresse_-_Offset_in_Byte" → Stapel
lila hinterlegt: GetStdHandle - "Quelle_-_Konsole_-_Datenkanal_-_Art" → Stapel
rot hinterlegt: GetStdHandle - die Funktion aufrufen
gelb hinterlegt: WriteConsoleA - "Ziel_-_Konsole_-_Datenkanal_-_Identifikationskennung" → Stapel
grün hinterlegt: WriteConsoleA - die Funktion aufrufen
blau hinterlegt: der Befehl "return", um zum Aufrufer zurückzukehren
lila hinterlegt: der unbenutzte Zwischenraum

1. Programmabschnitt-Inhalt

Dieser Programmabschnitt-Inhalt verfügt über die folgenden Inhalte:
  1. Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode für die Bibliothek "kernel32.dll"
  2. "Hallo Welt!"-Zeichenkette

die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode schreiben
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.036 Byte"-groß sein.

Größe
siehe: hier

die "Hallo Welt!"-Zeichenkette schreiben
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21

Nach dem Speichern müsste die Datei nun "1.047 Byte"-groß sein.

Größe
siehe: hier

den unbenutzten Zwischenraum füllen
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.536 Byte"-groß sein.

Größe
siehe: hier

Übersicht
Dies war soweit der komplette 1. Programmabschnitt-Inhalt (von "0" ausgehend gezählt):
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
rot hinterlegt: die Import-Tabelle für Adressen von Zeichenketten von Namen und für fortlaufende Nummern für die Verwendung vom Maschinencode
gelb hinterlegt: die "Hallo Welt!"-Zeichenkette
grün hinterlegt: der unbenutzte Zwischenraum

2. Programmabschnitt-Inhalt

Dieser Programmabschnitt-Inhalt verfügt über die folgenden Inhalte:
  1. Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. Tabellenverzeichnis für Import-Tabellen
  3. "kernel32.dll\0"-Zeichenkette
  4. Export-Tabelle für Adressen von Dingen
  5. Export-Tabelle für Adressen von Zeichenketten von Namen
  6. Export-Tabelle für Positionen von Adressen von Dingen
  7. Export-Tabelle für Zeichenketten von Namen
  8. Tabellenverzeichnis für Export-Tabellen

die Import-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: ?? 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00

Nach dem Speichern müsste die Datei nun "1.567 Byte"-groß sein.

Größe
siehe: hier

das Tabellenverzeichnis für Import-Tabellen schreiben
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.607 Byte"-groß sein.

Größe
siehe: hier

die "kernel32.dll\0"-Zeichenkette schreiben
Allgemeines
siehe: hier

Änderung
siehe: hier

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00

Nach dem Speichern müsste die Datei nun "1.620 Byte"-groß sein.

Größe
siehe: hier

Soweit sind die folgenden Inhalte im 2. Programmabschnitt-Inhalt:
  1. die Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. das Tabellenverzeichnis für Import-Tabellen
  3. die "kernel32.dll\0"-Zeichenkette

Es fehlen noch die folgenden Inhalte:
  1. die Export-Tabelle für Adressen von Dingen
  2. die Export-Tabelle für Adressen von Zeichenketten von Namen
  3. die Export-Tabelle für Positionen von Adressen von Dingen
  4. die Export-Tabelle für Zeichenketten von Namen
  5. das Tabellenverzeichnis für Export-Tabellen

die Export-Tabelle für Adressen von Dingen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird die Export-Tabelle für Adressen von Dingen in den Programmabschnitt-Inhalt eingefügt.

Da nur 1 Ding für einen möglichen Export markiert wird, hat diese Tabelle nur 1 Eintrag. Er gibt den Offset zum Anfang vom Ding im Segment in Byte an,
  • vom ersten Byte aus gerechnet, welches die Bibliothek im Segment belegt,
  • bis zum ersten Byte, welches das Ding im Segment belegt.
Dieses Ding ist die Funktion "Hallo_Welt_ausgeben".

Diese Funktion beginnt am Anfang vom 0. Programmabschnitt-Inhalt. Daher ist ihr Offset "4 Kilobyte". Der 0. Programmabschnitt-Inhalt ist der Bereich, in welchem der Maschinencode gespeichert ist.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                      00 10 00 00 rot hinterlegt: der 0. Eintrag (der Offset zur Funktion "Hallo_Welt_ausgeben")

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00

Nach dem Speichern müsste die Datei nun "1.624 Byte"-groß sein.

Größe
  4 Byte für den Eintrag für die Funktion "Hallo_Welt_ausgeben"
= 4 Byte für die gesamte Export-Tabelle für Adressen von Dingen

die Export-Tabelle für Adressen von Zeichenketten von Namen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird die Export-Tabelle für Adressen von Zeichenketten von Namen in den Programmabschnitt-Inhalt eingefügt.

Da nur 1 Ding für einen möglichen Export markiert wird, hat diese Tabelle nur 1 Eintrag. Er gibt den Offset zum Anfang vom Ding im Segment in Byte an,
  • vom ersten Byte aus gerechnet, welches die Bibliothek im Segment belegt,
  • bis zum ersten Byte, welches eine ASCII-kodierte Zeichenkette im Segment belegt.
Diese Zeichenkette gibt den Namen an, anhand welcher das Ding identifiziert werden kann.

Die Zeichenkette wird im 94. Byte von diesem/2. Programmabschnitt-Inhalt beginnen. Daher ist ihr Offset:
  12 Kilobyte (Anfang von diesem/2. Programmabschnitt-Inhalt)
+ 94 Byte
= 12.382 Byte

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                    5E 30 00 00 rot hinterlegt: der 1. Eintrag (der Offset zur Zeichenkette "Hallo_Welt_ausgeben")

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00 - 5E 30 00 00

Nach dem Speichern müsste die Datei nun "1.628 Byte"-groß sein.

Größe
  4 Byte für den Eintrag für die Zeichenkette von der Funktion "Hallo_Welt_ausgeben"
= 4 Byte für die gesamte Export-Tabelle für Adressen von Zeichenketten von Namen

Soweit sind die folgenden Inhalte im 2. Programmabschnitt-Inhalt:
  1. die Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. das Tabellenverzeichnis für Import-Tabellen
  3. die "kernel32.dll\0"-Zeichenkette
  4. die Export-Tabelle für Adressen von Dingen
  5. die Export-Tabelle für Adressen von Zeichenketten von Namen

Es fehlen noch die folgenden Inhalte:
  1. die Export-Tabelle für Positionen von Adressen von Dingen
  2. die Export-Tabelle für Zeichenketten von Namen
  3. das Tabellenverzeichnis für Export-Tabellen

die Export-Tabelle für Positionen von Adressen von Dingen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird die Export-Tabelle für Positionen von Adressen von Dingen in den Programmabschnitt-Inhalt eingefügt.

Da nur 1 Ding für einen möglichen Export markiert wird, hat diese Tabelle nur 1 Eintrag. Er gibt die Position/den Index vom zugehörigen Eintrag in der Export-Tabelle für Adressen von Dingen an.

In der Export-Tabelle für Adressen von Dingen befindet sich ebenfalls nur 1 Eintrag. Dieser gibt die Adresse vom Ding an. Daher wird die Position vom relevanten Eintrag mit der Hilfe vom Wert "0" angegeben.

Die Position wird immer von "0" ausgehend gezählt. Die fortlaufende Nummer hingegen, welche angegeben werden könnte, wenn das Ding nicht anhand vom Namen importiert werden soll, wird hingegen nicht zwangsweise von "0" ausgehend gezählt. In unserem Fall allerdings schon, da dies im Tabellenverzeichnis für Export-Tabellen so angegeben werden wird.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                00 00 rot hinterlegt: der 1. Eintrag (die Position vom Ding in der Export-Tabelle für Adressen von Dingen)

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00 - 5E 30 00 00 00 00

Nach dem Speichern müsste die Datei nun "1.630 Byte"-groß sein.

Größe
  2 Byte für den Eintrag für die Funktion "Hallo_Welt_ausgeben"
= 2 Byte für die gesamte Export-Tabelle für Positionen von Adressen von Dingen

die Export-Tabelle für Zeichenketten von Namen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird die Export-Tabelle für Zeichenketten von Namen in den Programmabschnitt-Inhalt eingefügt.

Da nur 1 Ding für einen möglichen Export markiert wird, hat diese Tabelle nur 1 Eintrag. Er gibt die Zeichenkette vom Namen vom Ding an. Diese "Tabelle" ist also lediglich 1 Zeichenkette.

Die Zeichenkette ist ASCII-kodiert und mit der Hilfe von einem weiteren Byte abgeschlossen, von welchem alle Bits auf "0" gesetzt sind. Hierdurch ist das Ende von dieser Zeichenkette markiert.

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                                                      48 61
00000660: 6C 6C 6F 5F 57 65 6C 74 - 5F 61 75 73 67 65 62 65
00000670: 6E 00
rot hinterlegt: die Zeichenkette "Hallo_Welt_ausgeben"
gelb hinterlegt: das Abschlusszeichen

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - ?? 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00 - 5E 30 00 00 00 00 48 61
00000660: 6C 6C 6F 5F 57 65 6C 74 - 5F 61 75 73 67 65 62 65
00000670: 6E 00

Nach dem Speichern müsste die Datei nun "1.650 Byte"-groß sein.

Größe
  19 Byte für die Buchstaben von der Zeichenkette "Hallo_Welt_ausgeben"
+  1 Byte für das Abschlusszeichen von der Zeichenkette "Hallo_Welt_ausgeben"
= 20 Byte für die gesamte Export-Tabelle für Zeichenketten von Namen

Soweit sind die folgenden Inhalte im 2. Programmabschnitt-Inhalt:
  1. die Import-Tabelle für Zeichenketten von Namen für "alle" Bibliotheken (es gibt nur 1 Bibliothek)
  2. das Tabellenverzeichnis für Import-Tabellen
  3. die "kernel32.dll\0"-Zeichenkette
  4. die Export-Tabelle für Adressen von Dingen
  5. die Export-Tabelle für Adressen von Zeichenketten von Namen
  6. die Export-Tabelle für Positionen von Adressen von Dingen
  7. die Export-Tabelle für Zeichenketten von Namen

Es fehlt noch der folgende Inhalt:
  1. das Tabellenverzeichnis für Export-Tabellen

das Tabellenverzeichnis für Export-Tabellen schreiben
Allgemeines
Mit der Hilfe von diesem Schritt wird das Tabellenverzeichnis für Export-Tabellen in den Programmabschnitt-Inhalt eingefügt.

Für die einzelnen Felder werde ich die folgenden Werte verwenden:
Beschreibung: Bezeichnung: Hexadezimalwert
2560: 2561: 2562: 2563:
alle Bits von den 4 unbenutzten Bytes auf "0" gesetzt Export Flags 00 00 00 00
alle Bits vom Zeitstempel auf "0" gesetzt Time/Date Stamp 00 00 00 00
alle Bits von der Hauptversion auf "0" gesetzt Major Version 00 00 - -
alle Bits von der Unterversion auf "0" gesetzt Minor Version 00 00 - -
keine Zeichenkette für den Bibliotheknamen, also alle Bits auf "0" gesetzt Name RVA 00 00 00 00
die fortlaufende Nummer wird von "0" ausgehend gezählt, also alle Bits auf "0" gesetzt Ordinal Base 00 00 00 00
1 Eintrag in der Export-Tabelle für Adressen von Dingen für die 1 Funktion, welche "Hallo Welt!" ausgibt Address Table Entries 01 00 00 00
jeweils 1 Eintrag in den restlichen Export-Tabellen um den Funktionsnamen "Hallo_Welt_ausgeben" zu speichern Number of Name Pointers 01 00 00 00
  12 Kilobyte (der Anfang von diesem/2. Programmabschnitt-Inhalt)
+ 84 Byte
= 12.372 Byte = der Offset zur Export-Tabelle für Adressen von Dingen
Export Address Table RVA 54 30 00 00
  12 Kilobyte (der Anfang von diesem/2. Programmabschnitt-Inhalt)
+ 84 Byte
+ 4 Byte
= 12.376 Byte = der Offset zur Export-Tabelle für Adressen von Zeichenketten von Namen
Name Pointer RVA 58 30 00 00
  12 Kilobyte (der Anfang von diesem/2. Programmabschnitt-Inhalt)
+ 84 Byte
+ 4 Byte
+ 4 Byte
= 12.380 Byte = der Offset zur Export-Tabelle für Positionen von Adressen von Dingen
Ordinal Table RVA 5C 30 00 00

Änderung
Erweitern Sie die Datei um die folgenden Werte:
                00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000680: 00 00 00 00 00 00 01 00 - 00 00 01 00 00 00 54 30
00000690: 00 00 58 30 00 00 5C 30 - 00 00
rot hinterlegt: der Wert für das Feld "Export Flags"
gelb hinterlegt: der Wert für das Feld "Time/Date Stamp"
grün hinterlegt: der Wert für das Feld "Major Version"
blau hinterlegt: der Wert für das Feld "Minor Version"
lila hinterlegt: der Wert für das Feld "Name RVA"
rot hinterlegt: der Wert für das Feld "Ordinal Base"
gelb hinterlegt: der Wert für das Feld "Address Table Entries"
grün hinterlegt: der Wert für das Feld "Number of Name Pointers"
blau hinterlegt: der Wert für das Feld "Export Address Table RVA"
lila hinterlegt: der Wert für das Feld "Name Pointer RVA"
rot hinterlegt: der Wert für das Feld "Ordinal Table RVA"

Geben Sie nun die endgültige Adresse vom Tabellenverzeichnis für Export-Tabellen im Tabellenverzeichnis für verschiedene Tabellen an:
000000B0:                           72 30 00 00 gelb hinterlegt: der Offset zum Tabellenverzeichnis für verschiedene Tabellen im Segment in Byte,

Ergebnis
Die komplette Datei müsste jetzt wie folgt aussehen:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - 72 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00 - 5E 30 00 00 00 00 48 61
00000660: 6C 6C 6F 5F 57 65 6C 74 - 5F 61 75 73 67 65 62 65
00000670: 6E 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000680: 00 00 00 00 00 00 01 00 - 00 00 01 00 00 00 54 30
00000690: 00 00 58 30 00 00 5C 30 - 00 00

Nach dem Speichern müsste die Datei nun "1.690 Byte"-groß sein.

Größe
  4 Byte für das Feld "Export Flags"
+ 4 Byte für das Feld "Time/Date Stamp"
+ 2 Byte für das Feld "Major Version"
+ 2 Byte für das Feld "Minor Version"
+ 4 Byte für das Feld "Name RVA"
+ 4 Byte für das Feld "Ordinal Base"
+ 4 Byte für das Feld "Address Table Entries"
+ 4 Byte für das Feld "Number of Name Pointers"
+ 4 Byte für das Feld "Export Address Table RVA"
+ 4 Byte für das Feld "Name Pointer RVA"
+ 4 Byte für das Feld "Ordinal Table RVA"
= 40 Byte für das komplette Tabellenverzeichnis für Export-Tabellen

Übersicht
Das war soweit der komplette 2. Programmabschnitt-Inhalt und die komplette "Hallo_Welt.dll"-Datei:
00000000: 4D 5A 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 00
00000040: 50 45 00 00 4C 01 03 00 - 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 70 00 0F 23 - 0B 01 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 10 - 00 10 00 00 00 02 00 00
00000080: 00 00 00 00 00 00 00 00 - 04 00 00 00 00 00 00 00
00000090: 9A 30 00 00 00 02 00 00 - 00 00 00 00 03 00 00 00
000000A0: 00 00 04 00 00 10 00 00 - 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 02 00 00 00 - 72 30 00 00 00 00 00 00
000000C0: 1F 30 00 00 00 00 00 00 - 2D 2D 70 2D 73 2D 2D 78
000000D0: 00 00 00 00 00 10 00 00 - 00 02 00 00 00 02 00 00
000000E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 20 00 00 30
000000F0: 2D 69 70 72 2D 2D 77 2D - 00 00 00 00 00 20 00 00
00000100: 00 02 00 00 00 04 00 00 - 00 00 00 00 00 00 00 00
00000110: 00 00 00 00 40 00 00 C0 - 64 69 70 72 2D 2D 2D 2D
00000120: 00 00 00 00 00 30 00 00 - 9A 00 00 00 00 06 00 00
00000130: 00 00 00 00 00 00 00 00 - 00 00 00 00 40 00 00 42
00000140: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000150: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000160: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000170: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000180: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000190: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000001F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000200: 68 00 00 00 00 68 00 00 - 00 00 68 0B 00 00 00 68
00000210: 0C 20 00 10 68 F5 FF FF - FF FF 15 00 20 00 10 50
00000220: FF 15 04 20 00 10 C3 90 - 90 90 90 90 90 90 90 90
00000230: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000240: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000250: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000260: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000270: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000280: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000290: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000002F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000300: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000310: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000320: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000330: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000340: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000350: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000360: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000370: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000380: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000390: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003A0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003B0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003C0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003D0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003E0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
000003F0: 90 90 90 90 90 90 90 90 - 90 90 90 90 90 90 90 90
00000400: 00 30 00 00 0F 30 00 00 - 00 00 00 00 48 61 6C 6C
00000410: 6F 20 57 65 6C 74 21 00 - 00 00 00 00 00 00 00 00
00000420: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000430: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000440: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000450: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000460: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000470: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000480: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000490: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000004F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000500: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000510: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000520: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000530: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000540: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000550: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000560: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000570: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000580: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000590: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005A0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005B0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005C0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005D0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005E0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
000005F0: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000600: 00 00 47 65 74 53 74 64 - 48 61 6E 64 6C 65 00 00
00000610: 00 57 72 69 74 65 43 6F - 6E 73 6F 6C 65 41 00 00
00000620: 00 00 00 00 00 00 00 FF - FF FF FF 47 30 00 00 00
00000630: 20 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000640: 00 00 00 00 00 00 00 6B - 65 72 6E 65 6C 33 32 2E
00000650: 64 6C 6C 00 00 10 00 00 - 5E 30 00 00 00 00 48 61
00000660: 6C 6C 6F 5F 57 65 6C 74 - 5F 61 75 73 67 65 62 65
00000670: 6E 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00000680: 00 00 00 00 00 00 01 00 - 00 00 01 00 00 00 54 30
00000690: 00 00 58 30 00 00 5C 30 - 00 00
rot hinterlegt: die Import-Tabelle für Zeichenketten von Namen
gelb hinterlegt: das Tabellenverzeichnis für Import-Tabellen
grün hinterlegt: die "kernel32.dll\0"-Zeichenkette
blau hinterlegt: die Export-Tabelle für Adressen von Dingen
lila hinterlegt: die Export-Tabelle für Adressen von Zeichenketten von Namen
rot hinterlegt: die Export-Tabelle für Positionen von Adressen von Dingen
gelb hinterlegt: die Export-Tabelle für Zeichenketten von Namen
grün hinterlegt: das Tabellenverzeichnis für Export-Tabellen

Nach dem letzten Programmabschnitt-Inhalt ist kein Zwischenraum notwendig, von welchem alle Bits beispielsweise auf "0|b" gesetzt sind. Der Programmabschnitt-Inhalt muss also nicht erweitert werden, bis seine Größe restlos durch die Größe von einer Seite teilbar ist. Bei einem Treiber ("*.sys"-Datei) wäre dies allerdings sehr wohl notwendig.

die Bibliothek benutzen

Allgemeines

Sofern Sie die Datei ein letztes Mal gespeichert haben, dann kann sie von nun an benutzt werden.

Das heißt, dass eine ausführbare Datei die Funktion "Hallo_Welt_ausgeben" aus der Bibliothek "Hallo_Welt.dll" importieren kann und dann die Funktion aufrufen kann. Die Funktion aus der Bibliothek wird dann die "Hallo Welt!"-Zeichenkette in den Ausgabe-Datenkanal von der Konsole übertragen, welche der Anwendung zugewiesen wurde.

Hierfür muss die "Hallo_Welt.dll"-Datei im gleichen Verzeichnis sein, wie die ausführbare Datei ist. Alternativ kann die Datei "Hallo_Welt.dll" in den Ordner "system32" vom Windows-Installationsverzeichnis verschoben werden.

Mit der Hilfe von diesem Dokument kann auch eine Anwendung geschrieben werden, welche den Import durchführt und dann die Funktion aufruft.

Alternativ können Sie auch ein bereits vorbereitetes Programm verwenden. Dieses Programm ist im Kapitel "weiteres Material zu diesem Thema - Programme" aufgelistet und macht das aller notwendigste:
Es importiert die Bibliothek mit dem Namen "Hallo_Welt.dll" und ruft dann die Funktion mit dem Namen "Hallo_Welt_ausgeben" auf.

Obwohl ich einen relativ langsamen Computer habe, schließt sich das Programm nach einem Doppelklick bei mir so schnell wieder, dass das "Hallo Welt!" meistens garnicht richtig angezeigt wird. Das schwarze Fenster von der Konsole wird auch nur teilweise angezeigt.

Um eine sich nicht selbst schließende Konsole zu starten, können Sie wie folgt vorgehen:
  1. Klicken Sie auf "Start".
  2. Klicken Sie im eben aufgesprungenen Startmenü auf "Ausführen...".
  3. Geben Sie "cmd.exe" ein und klicken Sie auf "OK". Dies wird die Datei "cmd.exe" aus dem "system32"-Verzeichnis starten. Also eine Eingabeaufforderung/eine Konsole.

Um anschließend die vorbereitete Datei "Hallo_Welt.dll_benutzen.exe" von Ihrem Desktop zu starten, können Sie wie folgt vorgehen:
  1. Ziehen Sie die Datei per drag-und-drop in das Eingabeaufforderungs-Fenster. Dadurch wird für Sie der komplette Pfad an der Cursor-Position eingetragen, also so ähnlich, als hätten Sie den Pfad mit der Tastatur eingegeben.
  2. Drücken Sie auf "[Enter]".

Nun müsste das "Hallo Welt!" auf Ihrem Bildschirm bleiben, bis Sie die Konsole manuell schließen.


weiteres Material zu diesem Thema

Bibliotheken

Name Beschreibung: Weblink:
vom Autor: von der Bibliothek:
Hallo_Welt Diese allgemeinfreie und kostenlose Bibliothek ist in dieser Dokumentation Schritt für Schritt beschrieben.

Funktionen:
  • "Hallo_Welt_ausgeben" - gibt "Hallo Welt!" aus
./Bibliothek/kompiliert/
Hallo_Welt.dll

Dokumente

Name vom Sprache: Umfang vom Inhalt: Weblink:
Autor: Dokument:
Betriebssystem-spezifische - allgemeine Informationen - Dateiformate - ausführbare Dateien und Bibliotheken deutsch
  • enthält allgemeine Informationen über die Dateiformate von
    • ausführbaren Dateien und
    • Bibliotheken
    von verschiedenen Betriebssystemen
OnTheServer.de/Downloads/
Betriebssystem-spezifische - allgemeine Informationen - Funktionen von einem Betriebssystem
  • enthält allgemeine Informationen über die Funktionen von einem Betriebssystem, ohne dass dabei auf die Besonderheiten und Details von einem spezifischen Betriebssystem eingegangen wird
Betriebssystem-spezifische - Windows - Funktionen vom Betriebssystem
  • nennt Bibliotheken von Windows
  • beschreibt Funktionen von den Bibliotheken
  • zeigt, wie Datensätze und Funktionen von den Bibliotheken genutzt werden können
Betriebssystem-spezifische - Windows - Lade-Programme - für das Dateiformat "portable executable" ("pe")
  • zeigt, wie das Lade-Programm angeforderte Funktionen aus Bibliotheken bereit stellt
  • zeigt, mit welchen Inhalten das Segment beim Programmstart gefüllt wird und wo diese in diesem Speicher platziert werden
x86-Architektur - Maschinensprache
  • enthält Hintergrundinformationen über Maschinensprachen
  • beschreibt die Maschinensprache von der x86-CPU-Architektur
  • zeigt, wie die Maschinensprache von der x86-CPU-Architektur benutzt werden kann
Zeichenkodierungen
  • beschreibt mehrere Zeichenkodierungen
Zeit - Zeitsysteme
  • beschreibt die Zeitsysteme
    • "gregorianischer Kalender",
    • das von der Norm "ISO 8601",
    • "julianischer Kalender",
    • "koordinierte, universelle Zeit",
    • "Unix-Zeitstempel" und
    • "Windows-Zeitstempel"
Ange Albertini PE - the Portable Executable Format on Windows englisch
  • Auflistung von (fast) allen Feldern ohne Beschreibung
  • eigene Erfahrungen
pe.corkami.com
Bernd Luevelsmeyer the PE file format
  • einigermaßen ausführliche Beschreibung von fast allen Feldern
  • eigene Erfahrungen
  • zum Teil veraltet und nennt Werte für Felder, welche zwischenzeitlich nicht mehr gültig sind
"Iczelion" "Tutorial 1: Overview of PE file format",
"Tutorial 2: Detecting a Valid PE File",
"Tutorial 3: File Header",
"Tutorial 4: Optional Header",
"Tutorial 5: Section Table",
"Tutorial 6: Import Table" und
"Tutorial 7: Export Table"
  • knappe Beschreibung von manchen Feldern
  • zusammen mit der Dokumentation werden auch kleine Programme angeboten, mit deren Hilfe eine ausführbare Datei ausgelesen werden kann
  • es fehlt zuviel, um davon eine eigene ausführbare Datei schreiben zu können
win32assembly.online.fr
(oder alternative URL zur selben Webseite: win32asm.cjb.net)
Intel Corporation/Tool Interface Standard Committee Formats Specification for Windows
  • kaum Details über die einzelnen Felder und gültigen Werte
  • enthält veraltete Bedeutungen von Werten und Feldern
Matt Pietrek Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
  • kaum Details über die einzelnen Felder und gültigen Werte
  • umfangreiche generelle Beschreibung von den einzelnen Abschnitten
  • zeigt Unterschiede zwischen dem Dateiformat "portable executable" ("pe") und dem Dateiformat "new executable"
Microsoft Corporation Microsoft Portable Executable and Common Object File Format Specification
  • knappe Beschreibung von allen Felden und gültigen Werten
  • keine eigenen Erfahrungen
  • sehr aktuell
  • nur ein Teil vom Dokument beschreibt das Dateiformat "portable executable" ("pe")
microsoft.com/whdc/system/
platform/firmware/PECOFF.mspx
Microsoft Corporation - Micheal J. O'Leary THE PORTABLE EXECUTABLE FORMAT
  • zum Teil veraltet und nennt Werte für Felder, welche zwischenzeitlich nicht mehr gültig sind
  • die Beschreibung ist zum Teil widersprüchlich zu der anderen Beschreibung von Microsoft
  • knappe Beschreibung
  • enthält ein paar Hinweise, welche ich sonst nirgends gefunden habe
Randy Kath The Portable Executable File Format from Top to Bottom
  • basiert auf dem Artikel "The Portable Executable File Format" von Johannes Plachy mit Zusatzinformationen
  • enthält ein paar Hinweise zur Kopfzeile vom DOS-Abschnitt
  • knappe Beschreibung
  • mit einer Menge Werbung für seine Bibliothek zugemüllt, welche er geschrieben hat
  • Strukturen von einzelnen Abschnitten aus der "WINNT.H" vorhanden, welchen einen groben Überblick geben
  • ein Teil von den Feldern ist beschrieben
  • eigene Erfahrungen
  • zum Teil falsche Angaben
Alexander Sotirov
(alias "Solar Eclipse")
Tiny PE
  • zeigt verschiedene Möglichkeiten, wie die Dateigröße von einer ausführbaren Datei reduziert werden kann
  • eigene Erfahrungen und ein paar Hinweise, welche ich sonst nirgends gefunden habe
  • bietet Beispiel-"*.exe"-Dateien zum Download an
phreedom.org/research/tinype/

Programme

Name vom Beschreibung: Sprache: Weblink:
Autor: Programm:
Steve Hutchesson Binary to Hex Editor "Binary to Hex Editor" ist ein kostenloses, minimalistisches, "20 Kilobyte"-großes Programm mit grafischer Benutzeroberfläche. Das Programm ist nicht allgemeinfrei und den Quelltext bekommt man glaube ich auch nicht.

Funktionen:
  • Hexeditor, mit welchem man Rohdaten-Dateien öffnen und editieren kann
  • Speicherung von der hexadezimal-Darstellung von einer Rohdaten-Datei als ASCII-kodierte Textdatei
  • Speicherung von einer hexadezimal-Darstellung als Rohdaten-Datei

Nachteilhaft ist allerdings, dass es lange braucht und viel Arbeitsspeicher notwendig ist, um große Dateien zu öffnen.
englisch movsd.com/download/b2hedit.zip
Erik Pistelli CFF Explorer "CFF Explorer" ist ein kostenloses Programm mit einer grafischen Benutzeroberfläche. Das Programm ist nicht allgemeinfrei und den Quelltext bekommt man glaube ich auch nicht.

Funktionen:
  • kann Informationen über den Aufbau von einer angegebenen Datei im Dateiformat "portable executable" ("pe") auslesen, anzeigen und ändern
  • listet die Datensätze und Funktionen auf, welche eine Bibliothek zur Verfügung stellt
  • enthält einen Disassembler
ntcore.com/?page_id=388
Clive Turvey DumpPE "DumpPE" ist ein kostenloses Konsolen-Programm. Das Programm ist nicht allgemeinfrei und darf nicht für kommerzielle Zwecke benutzt werden.

Funktionen:
  • kann Informationen über den Aufbau von einer angegebenen Datei im Dateiformat "portable executable" ("pe") auslesen und anzeigen
  • listet die Datensätze und Funktionen auf, welche eine Bibliothek zur Verfügung stellt
  • enthält einen Disassembler
  • kann die Prüfsumme von einer Datei berechnen

Dieses Programm kommt auch mit kaputten oder halb-fertigen Dateien zurecht. Also Dateien, von welchen beispielsweise die Hälfte fehlt.
tbcnet.com/~clive
Hallo_Welt Dieses allgemeinfreie und kostenlose Konsolen-Programm ist in dieser Dokumentation Schritt für Schritt beschrieben.

Funktionen:
  • gibt "Hallo Welt!" aus
deutsch ./ausführbare Datei/
kompiliert/Hallo_Welt.exe
Hallo_Welt.dll_benutzen - kompilierte Datei Dieses allgemeinfreie und kostenlose Konsolen-Programm ist ein Hilfsprogramm um die Bibliothek "Hallo_Welt" zu benutzen.

Funktionen:
  • importiert die Bibliothek "Hallo_Welt"
  • ruft die Funktion "Hallo_Welt_ausgeben" auf
./kompiliert/
Hallo_Welt.dll_benutzen.exe
Marc Ochsenmeier PeStudio "PeStudio" ist ein kostenloses Programm mit einer grafischen Benutzeroberfläche. Das Programm ist nicht allgemeinfrei und den Quelltext bekommt man glaube ich auch nicht.

Funktionen:
  • kann Informationen über den Aufbau von einer gewählten Datei im Dateiformat "portable executable" ("pe") auslesen und anzeigen
  • listet die Datensätze und Funktionen auf, welche eine Bibliothek zur Verfügung stellt

Nachteilhaft ist allerdings, dass es relativ fehlerhaft ist.
englisch winitor.com

Aufnahme von weiteren Materialien

Wenn dann
Sie dürfen durchaus auch Ihre eigenen Materialien zuschicken.

Bei den zugesendeten Materialien werde ich beurteilen, ob sie sich für die Auflistung eignen. Manche Materialien werden nicht aufgenommen, weil beispielsweise ein Hinweis enthalten ist, dass Es besteht kein Anspruch darauf, dass zugesendete Materialien aufgenommen werden.

Link zum Kapitel "wie man den Autor kontaktiert".