Analyse de malware packé UPX

VérifiéPrudence

Identifier et décompresser des échantillons de malware packés avec UPX, y compris ceux aux en-têtes modifiés, pour analyse statique.

Spar Skills Guide Bot
SecuriteAvancé
02/11/2026
Claude CodeCursorCodex
#malware-analysis#unpacking#upx#static-analysis#reverse-engineering

Recommandé pour

Synthèse automatique

Guide l’identification d’un malware packé avec UPX et la récupération de l’exécutable d’origine en réparant les en-têtes UPX modifiés lorsque la décompression automatique échoue.

Points forts

  • Fournit une chaîne de détection concrète : DIE, test UPX, entropie des sections et analyse de la table d’imports avec pefile.
  • Propose une démarche graduée : vérification du packer, tentative de décompression standard, puis réparation des octets magiques UPX.
  • Rappelle les prérequis outils et l’usage d’une VM d’analyse isolée et sans réseau.
  • Décrit les indicateurs typiques d’un binaire packé : peu d’imports, résolution via LoadLibrary/GetProcAddress, sections UPX0/UPX1.

Limites

  • Ne couvre que UPX et les altérations simples d’en-têtes, pas les packers personnalisés ni les protecteurs VM comme Themida ou VMProtect.
  • Le contenu fourni s’arrête au milieu de l’exemple de réparation d’en-têtes, donc le workflow n’est pas complet tel quel.
  • Repose sur des outils externes (UPX, DIE, pefile, PE-bear, x64dbg) et ne détaille pas la procédure de dump mémoire.
Quand l'utiliser

À utiliser lorsqu’un PE Windows suspect présente des signes de packing, comme une forte entropie, des sections UPX ou une table d’imports très réduite, et qu’il faut préparer une copie non packée pour l’analyse statique.

Quand l'éviter

À éviter face à un packer sur mesure, un protecteur virtualisé ou lorsqu’un unpacking dynamique sous débogueur est plus approprié.

Analyse de sécurité

Prudence
Score qualité84/100

The content is a legitimate defensive malware-analysis workflow: packer identification, UPX decompression, header repair, debugger-based manual unpacking, and PE validation. Code samples operate on local files and do not exfiltrate data or run obfuscated payloads. The only real risk is operational — manipulating and potentially executing live malware — which is mitigated by the stated requirement for an isolated, offline analysis VM. Hence caution rather than safe, but no inherent listing hazard.

Points d'attention
  • •Skill requires handling and modifying live malware samples (binary patching, upx -d, pefile writes) and describes executing unpacked binaries for validation; safe only if performed inside the isolated, network-disabled VM the skill itself specifies.
  • •Includes package installation (apt install upx-ucl) and external download from upx.github.io — legitimate but requires trust in the source/package.
  • •No exfiltration, no curl|sh piping, no destructive filesystem commands, no secret access, and no attempts to override the auditor's instructions.
  • •Contains Python scripts that open and rewrite binary files (sample and repair copies) — legitimate, but the repair loop replaces every 'UPX' three-byte sequence in the file, which could corrupt the sample rather than fix a single header; recommend operating only on copies and verifying before execution.
  • •Skill involves handling and potentially running live malware samples; it correctly mandates an isolated, network-disconnected analysis VM.
  • •No exfiltration, no obfuscated payloads, no credential/token handling, no destructive host commands (no rm -rf, no curl|sh), and no attempts to disable safety controls.
  • •No prompt-injection or instruction-override attempts found in the content.
Comment cette analyse est faite

Exemples

UPX decompression failure
I have a suspicious sample at /samples/invoice.exe. DIE reports UPX, but upx -d fails with 'not packed by UPX'. Walk me through identifying the packer and repairing the headers to get an unpacked copy for Ghidra.
Packed PE triage
Help me check whether this PE is packed: it has UPX0/UPX1 sections, entropy around 7.9, and only LoadLibrary/GetProcAddress imports. What should I do next in an isolated analysis VM?
Safe unpacking workflow
Create a safe workflow to confirm UPX packing, attempt decompression, repair modified UPX headers if needed, and verify the unpacked binary before disassembly.

name: analyzing-packed-malware-with-upx-unpacker description: 'Identifies and unpacks UPX-packed malware samples, including binaries with modified UPX magic bytes or headers that block automated decompression, to recover the original executable for static analysis. Use when a sample shows high entropy, minimal imports, or only LoadLibrary/GetProcAddress in its import table, or when preparing a packed binary for disassembly in Ghidra or IDA.

' domain: cybersecurity subdomain: malware-analysis tags:

  • malware
  • unpacking
  • UPX
  • packing
  • static-analysis version: 1.0.0 author: mahipal license: Apache-2.0 nist_csf:
  • DE.AE-02
  • RS.AN-03
  • ID.RA-01
  • DE.CM-01 mitre_attack:
  • T1027.002
  • T1140
  • T1620

Analyzing Packed Malware with UPX Unpacker

When to Use

  • Static analysis reveals high entropy sections and minimal imports indicating the binary is packed
  • PEiD, Detect It Easy, or PEStudio identifies UPX or another known packer
  • The import table contains only LoadLibrary and GetProcAddress (runtime import resolution typical of packed binaries)
  • You need to recover the original binary for proper disassembly and decompilation in Ghidra or IDA
  • Automated UPX decompression fails because the malware author modified UPX magic bytes or headers

Do not use when dealing with custom packers, VM-based protectors (Themida, VMProtect), or samples where dynamic unpacking via debugging is more appropriate.

Prerequisites

  • UPX (Ultimate Packer for eXecutables) installed (apt install upx-ucl or download from https://upx.github.io/)
  • Detect It Easy (DIE) for packer identification
  • Python 3.8+ with pefile library for manual header repair
  • x64dbg or x32dbg for manual unpacking when automated tools fail
  • PE-bear or CFF Explorer for PE header inspection and repair
  • Isolated analysis VM without network connectivity

Workflow

Step 1: Identify the Packer

Determine if the sample is packed and identify the packer:

# Check with Detect It Easy
diec suspect.exe

# Check with UPX (test without unpacking)
upx -t suspect.exe

# Python-based entropy and packer detection
python3 << 'PYEOF'
import pefile
import math

pe = pefile.PE("suspect.exe")

print("Section Analysis:")
for section in pe.sections:
    name = section.Name.decode().rstrip('\x00')
    entropy = section.get_entropy()
    raw = section.SizeOfRawData
    virtual = section.Misc_VirtualSize
    print(f"  {name:8s} Entropy: {entropy:.2f}  Raw: {raw:>8}  Virtual: {virtual:>8}")

# Check for UPX section names
section_names = [s.Name.decode().rstrip('\x00') for s in pe.sections]
if 'UPX0' in section_names or 'UPX1' in section_names:
    print("\n[!] UPX section names detected")
elif '.upx' in [s.lower() for s in section_names]:
    print("\n[!] UPX variant section names detected")

# Check import count (packed binaries have very few)
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    total_imports = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"\nTotal imports: {total_imports}")
    if total_imports < 10:
        print("[!] Very few imports - likely packed")
else:
    print("\n[!] No import directory - heavily packed")
PYEOF

Step 2: Attempt Standard UPX Decompression

Try the built-in UPX decompression:

# Standard UPX decompress
upx -d suspect.exe -o unpacked.exe

# If UPX fails with "not packed by UPX" error, the headers may be modified
# Verbose output for debugging
upx -d suspect.exe -o unpacked.exe -v 2>&1

# Verify the unpacked file
file unpacked.exe
diec unpacked.exe

Step 3: Repair Modified UPX Headers

If standard decompression fails, repair tampered magic bytes:

# Repair modified UPX headers
import struct

with open("suspect.exe", "rb") as f:
    data = bytearray(f.read())

# UPX magic bytes: "UPX!" (0x55505821)
# Malware authors commonly modify these to prevent automatic unpacking

# Search for modified UPX signatures
upx_magic = b"UPX!"
modified_patterns = [b"UPX0", b"UPX\x00", b"\x00PX!", b"UPx!"]

# Find and restore section names
pe_offset = struct.unpack_from("<I", data, 0x3C)[0]
num_sections = struct.unpack_from("<H", data, pe_offset + 6)[0]
section_table_offset = pe_offset + 0x18 + struct.unpack_from("<H", data, pe_offset + 0x14)[0]

print(f"PE offset: 0x{pe_offset:X}")
print(f"Number of sections: {num_sections}")
print(f"Section table offset: 0x{section_table_offset:X}")

for i in range(num_sections):
    offset = section_table_offset + (i * 40)
    name = data[offset:offset+8]
    print(f"Section {i}: {name}")

# Restore UPX magic bytes in the binary
# Search for the UPX header signature location (typically near the end of packed data)
for i in range(len(data) - 4):
    if data[i:i+3] == b"UPX" and data[i+3] != ord("!"):
        print(f"Found modified UPX magic at offset 0x{i:X}: {data[i:i+4]}")
        data[i:i+4] = b"UPX!"
        print(f"Restored to: UPX!")

# Also restore section names if modified
for i in range(num_sections):
    offset = section_table_offset + (i * 40)
    name = data[offset:offset+8].rstrip(b'\x00')
    if name in [b"UPX0", b"UPX1", b"UPX2"]:
        continue  # Already correct
    # Check for common modifications
    if name.startswith(b"UP") or name.startswith(b"ux"):
        original = f"UPX{i}".encode().ljust(8, b'\x00')
        data[offset:offset+8] = original
        print(f"Restored section name at 0x{offset:X} to {original}")

with open("suspect_fixed.exe", "wb") as f:
    f.write(data)

print("\nFixed file written. Retry: upx -d suspect_fixed.exe -o unpacked.exe")

Step 4: Manual Unpacking with Debugger

When automated unpacking fails entirely, use dynamic unpacking:

Manual UPX Unpacking with x64dbg:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Load packed sample in x64dbg
2. Run to the entry point (system breakpoint then F9)
3. UPX unpacking stub pattern:
   a. PUSHAD (saves all registers)
   b. Decompression loop (processes packed sections)
   c. Resolves imports (LoadLibrary/GetProcAddress calls)
   d. POPAD (restores registers)
   e. JMP to OEP (original entry point)
4. Set hardware breakpoint on ESP after PUSHAD:
   - After PUSHAD, right-click ESP in registers -> Follow in Dump
   - Set hardware breakpoint on access at [ESP] address
   - Run (F9) - breaks at POPAD before JMP to OEP
5. Step forward (F7/F8) until you reach the JMP to OEP
6. At OEP: Use Scylla plugin to dump and fix imports:
   - Plugins -> Scylla -> OEP = current EIP
   - Click "IAT Autosearch" -> "Get Imports"
   - Click "Dump" to save unpacked binary
   - Click "Fix Dump" to repair import table

Step 5: Validate Unpacked Binary

Verify the unpacked sample is valid and complete:

# Verify unpacked PE is valid
python3 << 'PYEOF'
import pefile

pe = pefile.PE("unpacked.exe")

# Check sections are normal
print("Unpacked Section Analysis:")
for section in pe.sections:
    name = section.Name.decode().rstrip('\x00')
    entropy = section.get_entropy()
    print(f"  {name:8s} Entropy: {entropy:.2f}")

# Verify imports are resolved
print(f"\nImport count:")
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
    for entry in pe.DIRECTORY_ENTRY_IMPORT:
        dll = entry.dll.decode()
        count = len(entry.imports)
        print(f"  {dll}: {count} functions")
    total = sum(len(e.imports) for e in pe.DIRECTORY_ENTRY_IMPORT)
    print(f"  Total: {total} imports")

# Compare file sizes
import os
packed_size = os.path.getsize("suspect.exe")
unpacked_size = os.path.getsize("unpacked.exe")
print(f"\nPacked:   {packed_size:>10} bytes")
print(f"Unpacked: {unpacked_size:>10} bytes")
print(f"Ratio:    {unpacked_size/packed_size:.1f}x")
PYEOF

Key Concepts

| Term | Definition | |------|------------| | Packing | Compressing or encrypting executable code to reduce file size and hinder static analysis; the binary contains an unpacking stub that restores code at runtime | | UPX | Ultimate Packer for eXecutables; open-source executable packer commonly abused by malware authors because it is free and effective | | Original Entry Point (OEP) | The real starting address of the malware code before packing; the unpacking stub decompresses code then jumps to the OEP | | Import Reconstruction | Process of rebuilding the import address table after dumping an unpacked process from memory using tools like Scylla or ImpRec | | PUSHAD/POPAD | x86 instructions that save/restore all general-purpose registers; UPX uses this pattern to preserve register state during unpacking | | Section Entropy | Randomness measure of PE section data; packed sections show entropy > 7.0 while normal code sections average 5.0-6.5 | | Magic Bytes | Signature bytes within a file identifying its format; UPX uses "UPX!" which malware authors modify to prevent automated decompression |

Tools & Systems

  • UPX: Open-source executable packer with built-in decompression capability for properly packed files
  • Detect It Easy (DIE): Packer, compiler, and linker detection tool that identifies protection on PE, ELF, and Mach-O files
  • x64dbg/x32dbg: Open-source Windows debugger used for manual unpacking through dynamic execution and breakpoint-based OEP finding
  • Scylla: Import reconstruction tool integrated with x64dbg for rebuilding IAT after memory dumping
  • PE-bear: PE file viewer and editor for inspecting and repairing PE headers after unpacking

Common Scenarios

Scenario: Unpacking Malware with Modified UPX Headers

Context: A malware sample is identified as UPX-packed by section names (UPX0, UPX1) but upx -d fails with "CantUnpackException: header corrupted". The malware author modified the UPX magic bytes to prevent automated decompression.

Approach:

  1. Open the binary in a hex editor and search for the UPX header area (typically at the end of packed data)
  2. Identify the modified magic bytes (e.g., "UPX!" changed to "UPX\x00" or completely zeroed)
  3. Use the Python repair script to restore "UPX!" magic and correct section names
  4. Retry upx -d on the repaired binary
  5. If repair fails, fall back to manual unpacking with x64dbg (PUSHAD -> hardware BP on ESP -> POPAD -> JMP OEP)
  6. Validate the unpacked binary has proper imports and reasonable entropy values
  7. Import into Ghidra or IDA for full static analysis

Pitfalls:

  • Assuming UPX is the only packer; the binary may be double-packed (UPX + custom layer)
  • Modifying the original packed sample instead of working on a copy
  • Not reconstructing imports after manual memory dump (the dumped binary will crash without IAT fix)
  • Forgetting to check for overlay data appended after the UPX-packed PE sections

Output Format

UNPACKING ANALYSIS REPORT
===========================
Sample:           suspect.exe
SHA-256:          e3b0c44298fc1c149afbf4c8996fb924...
Packer:           UPX 3.96 (modified headers)

PACKED BINARY
Sections:         UPX0 (entropy: 0.00) UPX1 (entropy: 7.89) .rsrc (entropy: 3.45)
Imports:          2 (kernel32.dll: LoadLibraryA, GetProcAddress)
File Size:        98,304 bytes

UNPACKING METHOD
Method:           Header repair + UPX -d
Header Fix:       Restored UPX! magic at offset 0x1F000
Command:          upx -d suspect_fixed.exe -o unpacked.exe
Result:           SUCCESS

UNPACKED BINARY
Sections:         .text (entropy: 6.21) .rdata (entropy: 4.56) .data (entropy: 3.12) .rsrc (entropy: 3.45)
Imports:          147 (kernel32, user32, advapi32, wininet, ws2_32)
File Size:        245,760 bytes (2.5x expansion)
OEP:              0x00401000

VALIDATION
PE Valid:         Yes
Imports Resolved: Yes (147 functions across 8 DLLs)
Executable:       Yes (runs without crash in sandbox)

NEXT STEPS
- Import unpacked.exe into Ghidra for full disassembly
- Run YARA rules against unpacked binary
- Submit unpacked binary to VirusTotal for improved detection

Du fichier au premier essai

Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.

Consulter la source et ses fichiers annexes

Ce téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.

1. Télécharger le fichier

Télécharger SKILL.md

Depuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.

Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.

mkdir -p '.skill-downloads/analyzing-upx-packed-malware-mveraooe' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/analyzing-upx-packed-malware-mveraooe/download' --output '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md.part' && mv '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md.part' '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md'

2. Vérifier les prérequis

Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.

Extrait original : Prerequisites
  • UPX (Ultimate Packer for eXecutables) installed (apt install upx-ucl or download from https://upx.github.io/)
  • Detect It Easy (DIE) for packer identification
  • Python 3.8+ with pefile library for manual header repair
  • x64dbg or x32dbg for manual unpacking when automated tools fail
  • PE-bear or CFF Explorer for PE header inspection and repair
  • Isolated analysis VM without network connectivity

Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.

3. Charger la skill

Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.

Claude Code
test -f '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && test -s '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/analyzing-packed-malware-with-upx-unpacker' && cp -R '.skill-downloads/analyzing-upx-packed-malware-mveraooe' '.claude/skills/analyzing-packed-malware-with-upx-unpacker'

Cursor
test -f '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && test -s '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/analyzing-packed-malware-with-upx-unpacker' && cp -R '.skill-downloads/analyzing-upx-packed-malware-mveraooe' '.cursor/skills/analyzing-packed-malware-with-upx-unpacker'

Codex
test -f '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && test -s '.skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/analyzing-packed-malware-with-upx-unpacker' && cp -R '.skill-downloads/analyzing-upx-packed-malware-mveraooe' '.agents/skills/analyzing-packed-malware-with-upx-unpacker'

OpenSkills

OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.

Installation officielle d’OpenSkills
openskills install './.skill-downloads/analyzing-upx-packed-malware-mveraooe'

openskills read 'analyzing-upx-packed-malware-mveraooe'

La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.

Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.

openskills sync

Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.

4. Faire un premier essai

Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :

Lis .skill-downloads/analyzing-upx-packed-malware-mveraooe/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.

Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.

Skills similaires