packer-unpacking

star 4.3k

Identify and unpack common binary packers — UPX, ASPack, Themida, VMProtect, MPRESS, PECompact, Enigma.

PurpleAILAB By PurpleAILAB schedule Updated 6/2/2026

name: packer-unpacking description: Identify and unpack common binary packers — UPX, ASPack, Themida, VMProtect, MPRESS, PECompact, Enigma. metadata: subdomain: reverse-engineering when_to_use: "packer unpack upx aspack themida vmprotect mpress pecompact enigma unpacking" mitre_attack: - T1027.002


Packer Unpacking Playbook

Packers compress and/or obfuscate binaries to defeat static analysis. The first job: identify which packer, then dispatch the right unpacker (or manual unpacking strategy if no automated tool exists).

1. Detect packing

# Entropy quick-check (>7.0 across the binary = likely packed)
ent /tmp/sample
# or
python3 -c "
import sys, math
d = open('/tmp/sample','rb').read()
f = [0]*256
for b in d: f[b] += 1
h = -sum((c/len(d))*math.log2(c/len(d)) for c in f if c)
print(f'entropy={h:.3f}')
"

# Section-level entropy via radare2
r2 -qc "iSj" /tmp/sample | jq '.[] | "\(.name): \(.entropy)"'

# Tool-based detection
detect-it-easy /tmp/sample  # most reliable, GUI + CLI
diec /tmp/sample           # CLI for DIE
yara -r /opt/yara-rules/packers/ /tmp/sample

Decepticon helper:

bin_packer("/tmp/sample")

2. Common packer signatures

Packer Signature
UPX UPX! magic at section header, sections named UPX0, UPX1
ASPack .aspack section, jump after entry to packed code
Themida .themida section, anti-debug, anti-VM heavy
VMProtect .vmp0, .vmp1 sections; obfuscated EP w/ virtualized handlers
MPRESS .MPRESS1, .MPRESS2 sections
PECompact pec1 section, encrypted sections
Enigma .enigma1, .enigma2 sections
Petite small overlay, .petite section
FSG tiny imports, packed sections
MEW MEW magic in section name
Armadillo runtime decryption, anti-debug (older)

3. Automated unpacking

UPX (easy)

upx -d /tmp/sample -o /tmp/unpacked
file /tmp/unpacked

If upx -d fails with "not packed by UPX", the version field has been tampered with (anti-unpack trick). Fix:

# Patch the version byte back
python3 -c "
d = bytearray(open('/tmp/sample','rb').read())
# Find UPX! magic, fix version
import re
for m in re.finditer(b'UPX!', d):
    d[m.end()] = 0x0d  # set version field
open('/tmp/patched','wb').write(d)
"
upx -d /tmp/patched -o /tmp/unpacked

ASPack

unaspack /tmp/sample  # or use ASPackDie / ASPack Stripper

Manual: ASPack's OEP jump is JMP <reg> at the end of unpack stub. Set breakpoint there in x64dbg, dump from Scylla (PE only).

MPRESS

quickunpack /tmp/sample
# Or load in x64dbg, set BP on tail jump (E9 to OEP), dump w/ Scylla

PECompact / FSG

Use unpacme (uploads to UnpacMe service if engagement permits cloud processing), or run in monitored sandbox + memory-dump strategy.

4. Manual unpacking strategy (Themida / VMProtect / Enigma)

These are commercial-grade and don't have reliable auto-unpackers. Approach:

Themida

  1. Static: identify anti-debug checks, patch them or rewrite
  2. Dynamic: x64dbg + ScyllaHide plugin → bypass anti-debug
  3. Set hardware breakpoint on VirtualProtect (Themida unpacks via this)
  4. When hit, walk back to find decrypted code regions
  5. Dump w/ Scylla after OEP is reached
  6. Themida often has multiple layers — repeat per layer

VMProtect

VMProtect translates code into bytecode for a custom VM. No simple "unpack" — you must either:

  • Devirtualize (extract VM handlers + write a translator). Tools: VTIL (Vladimir's tools), vmpfix, manual w/ IDA + bytecode trace
  • Trace + symbolic execute via Triton or angr
  • Skip RE and treat as black-box (fuzz the interfaces)

Enigma Protector

Similar to Themida. ScyllaHide handles many checks. The license / virt machine layer is hardest. Some Enigma variants:

  • v3-v5: scriptable unpack via Enigma Static Unpacker
  • v6+: manual w/ x64dbg + Scylla, multiple decryption passes

5. Manual unpack technique (universal)

For any packer:

  1. Disable ASLR / DEP if needed (ScyllaHide / setdllchar)
  2. Set BP on entry point
  3. Step through unpack stub; watch for:
    • Large VirtualAlloc (decryption region)
    • memset followed by decrypted code being written
    • Tail jump to OEP (often JMP <reg> or RET after PUSHAD/POPAD)
  4. At suspected OEP, dump process w/ Scylla (PE) or r2 -d
  5. Fix imports (Scylla auto-rebuild IAT), save dumped PE
  6. Re-run static analysis on the dumped file

6. Anti-anti-unpacking tricks

Anti-unpack Counter
IsDebuggerPresent ScyllaHide, or patch w/ NOP
NtQueryInformationProcess(ProcessDebugPort) ScyllaHide
Timing checks (rdtsc measure) x64dbg "timing" plugin or patch
INT3 detection (BP byte scan) hardware BPs only
Self-checksum identify check loop, patch comparison
TLS callbacks (run before main entry) BP in TLS callback list (IDA: View → Open Subviews → TLS)
Anti-VM (CPUID hypervisor bit) Run on bare metal or KVM w/ CPUID masking

7. Promote

kg_add_node(kind="observation", label="packed: <packer-name>",
            props={"sample":"<sha256>","entropy":<float>,"packer":"<name>"})
kg_add_edge(src=<sample>, dst=<observation>, kind="exhibits")

# After unpack, re-run triage on the dumped file
kg_add_node(kind="artifact", label="unpacked: <sha256>",
            props={"original":"<orig-sha256>","unpacker":"<tool>"})

Severity (not a vuln, but a triage gate)

Outcome Implication for engagement
Automated unpack succeeded → static analysis viable Normal triage path
Only partial unpack (multi-layer) Use dynamic analysis as primary
VMProtect / Themida heavy Likely commercial protection — escalate effort, schedule realistically
Cannot unpack Black-box fuzz + dynamic only; document static-blind constraint

Known exemplars

  • Stuxnet: multi-layer packing including custom routines
  • WannaCry: UPX + custom obfuscation
  • Most commodity malware: UPX (because it's free + easy)
  • Banking trojans: Themida or VMProtect common
  • Cobalt Strike beacons: encrypted shellcode + reflective loader, "packer-like"
Install via CLI
npx skills add https://github.com/PurpleAILAB/Decepticon --skill packer-unpacking
Repository Details
star Stars 4,323
call_split Forks 860
navigation Branch main
article Path SKILL.md
More from Creator