# Unpacking Basics

> Use when a malware sample is packed or obfuscated — recognising packing and getting to the real payload so static and dynamic analysis can actually see the code.

- Skill: `jihedbfr-art/unpacking-basics` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add jihedbfr-art/unpacking-basics`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jihedbfr-art/unpacking-basics/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: jihedbfr-art (https://skillmd.com/u/jihedbfr-art)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/jihedbfr-art/unpacking-basics

---




## Prerequisites
- Target system, dependencies and environment configured.

## Usage
### Purpose

Most malware is packed — compressed or encrypted so its real code is hidden until runtime, defeating static analysis and antivirus signatures. To analyse the actual malware, you first have to unpack it: get to the payload that exists in memory after the packer runs. This skill covers recognising packing and the basic approaches to reaching the unpacked code, the prerequisite for meaningful static analysis and disassembly of packed samples.

### When to use it

When static triage shows packing indicators (high entropy, few imports, odd sections) and you need to see the real code. It sits between triage and deep static analysis/disassembly — you can't meaningfully disassemble a packed binary until you've unpacked it.

### How packing works (and why it matters)

A packer wraps the real payload in a small "stub". At runtime, the stub decompresses/decrypts the payload into memory and jumps to it. So on disk the malware is unreadable, but in memory (after the stub runs) the real code is exposed. Unpacking is fundamentally about capturing that in-memory payload after the stub has done its work but before (or as) it executes.

### Procedure

1. **Confirm and identify the packer.** Packing signs from static triage (entropy, tiny import table, sections named `UPX0`/random). Tools like Detect It Easy (DIE) or PEiD can identify known packers, which shortcuts everything:
   ```
   # DIE / PEiD -> identify packer (UPX? ASPack? custom?)
   ```
2. **Try the easy path for known packers.** Some packers have a clean unpacker. UPX, the most common, unpacks with its own tool:
   ```
   upx -d packed.exe -o unpacked.exe        # works for standard UPX
   ```
   If a known-packer unpacker exists, use it — no need to do it manually.
3. **For custom/unknown packers, unpack from memory (in the isolated lab).** The general approach: let the stub decrypt the payload, then dump the process memory once the real code is present.
   - **Dynamic dumping:** run under a debugger (x64dbg) in the sandbox, run until the payload is unpacked in memory (find the "tail jump" / OEP — original entry point — where the stub hands off to the real code), then dump.
   - **Automated memory scanning:** tools like PE-sieve/hollows_hunter scan a running process for unpacked/injected PE images and dump them, often getting the payload without manual OEP-finding.
   ```
   pe-sieve /pid <pid>            # dump unpacked/injected modules from a running process
   ```
4. **Fix the dumped payload for analysis.** A memory dump often needs its import table rebuilt and headers fixed to be a valid, analysable PE (tools like Scylla assist). The goal is a payload you can then treat with static-triage and disassembly.
5. **Or side-step unpacking with dynamic analysis.** If you only need *behaviour* (not the code), running the sample (dynamic-analysis skill) shows what the unpacked malware does without you manually unpacking — sometimes the pragmatic choice.
6. **Then analyse the payload** — the unpacked code goes back through static triage (real strings/imports now visible) and disassembly.

### Cheatsheet

```
why: packer stub decrypts payload into MEMORY at runtime -> capture it there
     on disk = unreadable ; in memory (after stub) = the real code

1. identify packer   Detect It Easy (DIE) / PEiD  (known packer = shortcut)
2. known packer?     use its unpacker:  upx -d packed.exe -o out.exe
3. custom/unknown -> unpack from memory (in the LAB):
     debugger (x64dbg): run to OEP (tail jump), dump process
     automated: pe-sieve /pid <pid>  (scans+dumps unpacked/injected PE)
4. fix the dump      rebuild imports / fix headers (Scylla) -> valid analysable PE
5. shortcut          only need BEHAVIOUR? -> dynamic analysis instead of unpacking
6. analyse           unpacked payload -> static triage + disassembly (real code now)
```

### Reading the situation

- **A known packer (UPX etc.) identified** = the easy path; use its unpacker and move straight to analysis. Don't do manual work when a clean unpacker exists.
- **High entropy + tiny import table + custom stub** = a custom packer; you'll unpack from memory (debugger to OEP, or PE-sieve). Expect real effort.
- **The in-memory payload dumped and imports rebuilt** = you now have the real code; re-run static triage and the strings/imports that were hidden appear — that's the whole point.
- **A sample where you only need indicators, not the code** = dynamic analysis may get you there faster than unpacking; choose the pragmatic route.
- **Anti-analysis in the stub** (anti-debug, anti-VM) = the packer is fighting you; combine with anti-evasion techniques, and recognise this is the advanced end where it gets slow.
- **A clean unpacked PE** = the deliverable; hand it to disassembly and IoC extraction.

### Pitfalls

- **Trying to analyse the packed binary directly.** Disassembling the stub tells you about the packer, not the malware; you must reach the payload first. Unpack before deep static analysis.
- **Manual unpacking when a tool exists.** Standard UPX and known packers have unpackers; don't hand-unpack what `upx -d` or PE-sieve handles.
- **Unpacking outside the lab.** Reaching the in-memory payload means running the sample — that's execution, so it happens only in the isolated environment.
- **Forgetting to fix the dump.** A raw memory dump usually isn't a valid PE (broken imports/headers); rebuild it or your disassembler chokes.
- **Assuming one payload.** Some malware unpacks in stages or injects into another process; be ready for multiple layers (PE-sieve helps find injected modules).

### References

- Practical Malware Analysis (packing/unpacking chapters)
- Detect It Easy, x64dbg, PE-sieve/hollows_hunter, Scylla documentation
- The static-triage, dynamic-analysis-sandboxing, and disassembly-with-ghidra skills
- MITRE ATT&CK — T1027.002 (Software Packing)

## Inputs
- Relevant source code, logs, network traces, or system specifications.

## Outputs
- Analysis findings, security audit report, or generated code artifacts.
