Das PE-Dateiformat für Incident Responder
Was bei der Triage einer verdächtigen EXE, DLL oder eines Treibers zählt: Header, Sections, Importe, Ressourcen, Signatur und Overlay.
Kurz gesagt. Eine Windows-Executable ist eine Karte: Ein MS-DOS-Header zeigt auf den PE-Header, der PE-Header beschreibt, wie die Datei geladen wird, und eine Section-Tabelle legt fest, welche Bytes wohin gehören. Die meisten Fragen der ersten Triage – was ist es, wer hat es gebaut, wann, was kann es, ist es signiert, ist darin etwas versteckt – lassen sich durch das Lesen dieser Karte beantworten, ohne irgendetwas auszuführen. Der PE Parser erledigt das in Ihrem Browser.
Dieser Artikel ist der Einstieg in die Serie. Er geht die Struktur in der Reihenfolge durch, in der ein Responder sie braucht, mit den Feldnamen aus Microsofts PE-Format-Spezifikation.
Der Aufbau im Überblick
| Teil | Wo | Was er liefert |
|---|---|---|
| MS-DOS-Header | Offset 0, beginnt mit MZ | e_lfanew, den Offset des PE-Headers; den DOS-Stub und oft den Rich Header |
| PE-Signatur + COFF-File-Header | an e_lfanew | Maschine (x86, x64, ARM64), Anzahl der Sections, TimeDateStamp, Characteristics (EXE oder DLL) |
| Optional Header | direkt danach | PE32 oder PE32+, Entry Point, Image Base, Subsystem, Prüfsumme, DLL Characteristics (ASLR, DEP, CFG), 16 Datenverzeichnisse |
| Section-Tabelle | nach dem Optional Header | Name, virtuelle und Rohgröße, Datei-Offset und Rechte jeder Section |
| Datenverzeichnisse | innerhalb der Sections | Importe, Exporte, Ressourcen, Zertifikate, Debug, TLS, Load Config, Relocations, .NET |
| Overlay | nach der letzten Section | alles Angehängte: Installer-Payloads, Archive, Konfiguration, Signaturen |
Alles ist Little-Endian. Adressen innerhalb des Images sind RVAs (relative virtuelle Adressen); die Umrechnung einer RVA in einen Datei-Offset läuft über die Section-Tabelle – deshalb bringt eine beschädigte Section-Tabelle alle Tools gleichzeitig zu Fall.
Header: Identität und Build
Der TimeDateStamp des COFF-Headers ist die klassische Kompilierzeit in Unix-Sekunden. Er kann gefälscht, genullt oder – bei neueren Microsoft- und .NET-Builds – durch einen Hash ersetzt sein, wie im Artikel zu PE-Zeitstempeln erklärt. Der Optional Header verrät, ob die Datei 32-Bit (Magic 0x10b, PE32) oder 64-Bit (0x20b, PE32+) ist, wo die Ausführung beginnt (AddressOfEntryPoint) und welche Exploit-Schutzmechanismen angefordert wurden (DYNAMIC_BASE für ASLR, NX_COMPAT für DEP, GUARD_CF für Control Flow Guard).
Das Feld CheckSum wird bei gewöhnlichen Executables ignoriert, ist für Treiber aber Pflicht. Passt eine gespeicherte Prüfsumme nicht mehr zur neu berechneten, deutet das darauf hin, dass sich nach dem Linken Bytes geändert haben.
Sections: wo Code und Daten liegen
Ein typisches, mit Microsoft-Tools gelinktes Programm hat .text (Code), .rdata (schreibgeschützte Daten und Importtabellen), .data, .pdata (x64-Exception-Daten), .rsrc und .reloc. Drei Dinge verdienen Aufmerksamkeit:
- Rechte. Eine Section, die zugleich schreibbar und ausführbar ist, ist für Compiler-Ausgaben ungewöhnlich und für Packer typisch.
- Entropie. Nahe 8 Bit pro Byte bedeutet komprimierte oder verschlüsselte Inhalte. In einer Code-Section deutet das meist auf einen Packer hin – siehe gepackte Executables erkennen.
- Namen. Namen sind frei wählbar.
UPX0/UPX1,.vmp0oder.themidasind Hinweise, keine Beweise, und ein Packer lässt sich umbenennen.
Importe und Exporte: Fähigkeiten
Das Importverzeichnis listet jede DLL und Funktion auf, die der Loader auflösen muss, und trägt ihre Adressen in die Import Address Table ein. Importe sind der schnellste Überblick über die Fähigkeiten: WinHttpOpen steht für HTTP, CreateRemoteThread für Code in einem anderen Prozess, RegSetValueExW für Schreibzugriffe auf die Registry. Sehr wenige Importe plus LoadLibrary/GetProcAddress deuten darauf hin, dass die eigentlichen Importe zur Laufzeit aufgelöst werden. Aus der Importliste ergibt sich auch der Imphash, mit dem sich Samples clustern lassen (Imphash, Rich Header und TLSH).
DLLs exportieren Funktionen per Name und Ordinal; eine DLL mit einem einzigen Export wie DllRegisterServer oder ServiceMain verrät, wie sie geladen werden will.
Ressourcen, Debug-Daten und Signatur
Ressourcen enthalten die Versionsinformationen (CompanyName, FileDescription, OriginalFilename), das Manifest (angeforderte Berechtigungsstufe), Icons, Dialoge und String-Tabellen – und manchmal eine eingebettete Executable. Weicht OriginalFilename vom Namen auf der Platte ab, ist das eine schnelle Prüfung auf Masquerading.
Das Debug-Verzeichnis enthält meist einen CodeView-Eintrag mit dem PDB-Pfad, einer GUID und einem Age-Wert. Build-Pfade wie C:\Users\<name>\source\repos\… verraten die Umgebung des Autors (PDB-Pfad).
Die Zertifikatstabelle enthält die Authenticode-Signatur. Sie wird nicht in den Speicher abgebildet und liegt hinter den Sections, weshalb sie vom signierten Datei-Hash ausgenommen ist. Was eine Signatur beweist und was nicht, behandelt Authenticode offline.
Checkliste für die erste Triage
- Hashen (MD5, SHA-1, SHA-256) und in Ihren Threat-Intelligence-Quellen suchen; den Imphash berechnen.
- Die Zeiten lesen: Kompilierung, Debug, Signatur. Passen sie zueinander und zum Vorfall?
- Die Signatur prüfen: vorhanden, passend zur Datei, wer hat signiert, wann.
- Importe und Strings nach Fähigkeiten und Indikatoren durchsehen (URLs, IP-Adressen, Pfade, Registry-Schlüssel).
- Die Sections ansehen: Rechte, Entropie, Lage des Entry Point; auf ein Overlay prüfen.
- Versionsinformationen und PDB-Pfad lesen; mit Dateiname und Speicherort vergleichen.
Der PE Parser arbeitet diese Checkliste für eine einzelne Datei oder eine ganze Sammlung ab und erklärt jeden Indikator in klaren Worten. Er arbeitet rein statisch: Er entpackt UPX und extrahiert in einer Datei versteckte ausführbare Dateien, andere Packer müssen aber anderswo entpackt werden, und nichts, was er anzeigt, ist für sich allein ein Urteil.
FAQ
Was ist eine PE-Datei?
Portable Executable ist das Dateiformat von Windows-Programmen und -Bibliotheken: .exe, .dll, .sys-Treiber, .scr, .cpl, .ocx und EFI-Binaries. Es beginnt mit einem MS-DOS-Header (MZ), gefolgt von der PE-Signatur, einem COFF-File-Header, einem Optional Header und einer Section-Tabelle.
Welche PE-Felder zählen bei einer ersten Triage am meisten?
Hashes und Imphash für Threat-Intelligence-Abfragen, Kompilier-, Debug- und Signaturzeit, die Importtabelle, die Section-Tabelle mit Entropie und Rechten, die Versionsinformationen, die Authenticode-Signatur und alle hinter der letzten Section angehängten Daten (Overlay).