Skip to content

Gepackte Executables erkennen: UPX, Entropie und mehr

Statische Hinweise auf gepackte Windows-Executables – Section-Namen, Entropie, W+X, Entry Point, Importe, Overlay – und ihre Fallstricke.

Veröffentlicht am Aktualisiert am 4 Min. Lesezeit

Kurz gesagt. Ein Packer komprimiert oder verschlüsselt das eigentliche Programm und fügt einen kleinen Stub hinzu, der es im Speicher wiederherstellt. Statisch sehen Sie den Stub: wenige Importe, seltsame Section-Namen, einen großen Block mit hoher Entropie, manchmal eine schreibbare und ausführbare Section und einen Entry Point außerhalb von .text. Kein einzelnes Anzeichen ist eindeutig, zusammen sind sie verlässlich. Die Lösung heißt entpacken – mit dem Tool des Packers, sofern es eines gibt, oder dynamisch in einer Sandbox – und erneut analysieren.

Die Anzeichen im Einzelnen

Section-Namen. Packer benennen ihre Sections meist selbst: UPX verwendet UPX0 (auf der Platte leer, im Speicher groß) und UPX1 (die komprimierten Daten plus Stub); MPRESS verwendet .MPRESS1/.MPRESS2, VMProtect .vmp0/.vmp1, Themida .themida. Namen lassen sich trivial ändern, sie sind also Hinweise – in der Praxis macht sich aber kaum ein Sample die Mühe.

Marker. UPX schreibt den Magic-String UPX! und einen Versions-String in die Header. Darauf stützt sich upx -d beim Dekomprimieren, und deshalb scheitert upx -d auch, wenn daran manipuliert wurde (UPX project).

Entropie. Die Shannon-Entropie in Bit pro Byte misst, wie zufällig die Bytes wirken. Kompilierter x86/x64-Code liegt typischerweise bei etwa 5–6,8; komprimierte oder verschlüsselte Daten liegen nahe 8. Der PE Parser markiert Sections ab 7,2 (ausgenommen .rsrc, wo Bilder und Archive normal sind).

Rechte. Ein Stub muss den entpackten Code irgendwohin schreiben und ihn dann ausführen. Eine Section, die zugleich schreibbar und ausführbar ist, kommt in Compiler-Ausgaben selten vor, bei Packern dagegen häufig.

Entry Point. Compiler legen den Entry Point in die Code-Section. Ein Stub liegt oft in einer eigenen Section, häufig der letzten.

Importe. Ein gepacktes Programm importiert, was der Stub braucht – typischerweise LoadLibraryA, GetProcAddress, VirtualProtect, VirtualAlloc, ExitProcess – und löst den Rest zur Laufzeit auf. Weniger als zehn Importe einschließlich GetProcAddress sind ein starkes Signal. Das macht auch den Imphash für das Clustern unbrauchbar: Alle mit demselben Tool gepackten Dateien teilen ihn.

Roh- vs. virtuelle Größe. Eine Section mit 0 Byte auf der Platte, aber großer virtueller Größe (UPX0) ist Platz, den der Stub zur Laufzeit füllt.

Overlay. Manche Packer, Installer und Dropper hängen ihre Payload hinter die letzte Section an statt in sie hinein.

Das Beispiel, statisch gelesen

Die synthetische m64.exe im Beispiel des PE Parser zeigt die meisten Anzeichen auf einmal, und zwar harmlos (ihr einziger Code ist ein ret): eine Section namens UPX1 voller Zufallsbytes (Entropie 7,96) und als RWX markiert, ein TLS-Callback, ein Overlay aus 4 KB Rauschen und Importe, die bekannten Verhaltensgruppen entsprechen. Das Tool meldet „UPX“ allein aufgrund des Section-Namens – es gibt keinen UPX!-Marker – und nennt, auf welchen Belegen jede Erkennung beruht.

Zu erwartende False Positives

  • Installer (NSIS, Inno Setup, selbstentpackende Archive) tragen große komprimierte Overlays oder Ressourcen.
  • Geschützte kommerzielle Software und Spiele setzen VMProtect, Themida oder Denuvo legitim ein.
  • Go- und Rust-Binaries sind groß und statisch gelinkt; sie sind nicht gepackt, haben aber ungewöhnliche Section-Layouts.
  • .NET-Assemblies importieren nur mscoree.dll!_CorExeMain; der eigentliche Code ist IL in den Metadaten.
  • Signierte Dateien: Eine gültige Signatur eines bekannten Herstellers senkt die Priorität, doch signierte Malware gibt es.

Wie es weitergeht

  1. UPX: Ziehen Sie die Datei in den PE Parser. Er entpackt sie statisch – auch wenn der UPX!-Header gelöscht oder die Sections umbenannt wurden, damit upx -d scheitert – und rekonstruiert die ursprünglichen Importe, sodass der Imphash zum Original-Build passt. Für andere Packer mit Entpacker: auf einer Kopie ausführen und das Ergebnis analysieren.
  2. Andernfalls dynamisch in einer isolierten Sandbox entpacken und den Prozessspeicher dumpen.
  3. Dokumentieren Sie auch die Hashes des gepackten Samples: Andere Betroffene haben die gepackte Form.

Die Erkennung im PE Parser besteht aus einer kleinen Menge dokumentierter, eigens für das Tool geschriebener Heuristiken – Section-Namen, Marker, Laufzeit-Strings, der Rich Header –, nicht aus einer Signaturdatenbank wie der von Detect It Easy. Verstehen Sie sie als Hinweis, und lesen Sie den Leitfaden zum PE-Format, um zu sehen, wo jedes Anzeichen in der Datei liegt.

FAQ

Wie erkenne ich, ob eine EXE gepackt ist, ohne sie auszuführen?

Achten Sie auf ausführbare Sections mit hoher Entropie, Sections, die zugleich schreibbar und ausführbar sind, einen Entry Point außerhalb von .text oder in der letzten Section, sehr wenige Importe mit LoadLibrary und GetProcAddress, Packer-Section-Namen wie UPX0 und UPX1 sowie Packer-Marker wie den String UPX!.

Ab welcher Entropie gilt eine Datei als gepackt?

Eine Entropie nahe 8 Bit pro Byte bedeutet komprimierte oder verschlüsselte Daten. Kompilierter Code liegt meist etwa zwischen 5 und 6,8; Werte über etwa 7,2 in einer ausführbaren Section sind ein starker Hinweis auf einen Packer, doch auch Bilder, Archive und Zertifikate haben eine hohe Entropie.

Verwandte Artikel

Statische Triage von Windows-Executables mit dem kostenlosen PE Parser: Dateien oder ZIP laden, Indikatoren lesen, Builds vergleichen, exportieren.
Verdächtige EXE-, DLL- und SYS-Dateien von einem Windows-Host oder Image finden und kopieren, ohne sie auszuführen: PowerShell, Velociraptor, Images.
Wo eine Windows-Executable ihre Zeiten speichert, welchen man trauen kann, wie sich Reproducible Builds und Timestomping zeigen – und wie man sie nutzt.