debugging-malware-with-x64dbg

Uses x64dbg to dynamically debug Windows malware: setting strategic breakpoints on APIs, stepping through unpacking and decryption, dumping memory at the right moment, and manipulating execution to re

SKILL.md

GitHub

Debugging Malware with x64dbg

When to Use

  • You need to observe a sample's runtime behavior at the instruction level on Windows.
  • You are manually unpacking, decrypting strings, or reaching code guarded by anti-analysis.
  • You want to dump a payload from memory after it is decoded but before it is hidden.

Do not use a debugger on a host you care about — debug only inside the isolated victim VM, and revert the snapshot after.

Prerequisites

  • x64dbg (and the matching x32/x64 build for the sample's bitness) inside the victim VM.
  • A clean snapshot; the lab's simulated internet.
  • Familiarity with Windows APIs commonly used by malware.

Safety & Handling

  • The sample executes under the debugger; this is detonation. Stay in the isolated VM.
  • Revert the snapshot after the session; treat memory dumps as live samples.

Workflow

Step 1: Set strategic API breakpoints

Rather than stepping from the entry point, break on APIs that mark interesting moments:

VirtualAlloc / VirtualProtect  -> unpacking buffer about to be written/executed
CreateProcessInternalW         -> process hollowing target
WriteProcessMemory             -> injection payload in a register/buffer
CryptDecrypt / lstrcpy         -> decoded data available
ResumeThread                   -> hollowed process about to run

Use bp VirtualAlloc then inspect the return value (allocated base) on return.

Step 2: Step through unpacking

Run to the allocation, set a memory breakpoint on the new region, and continue until the unpacker writes and jumps to it. The tail jump to OEP marks the unpacked entry.

Step 3: Dump at the right moment

When the payload is decoded in memory (e.g. after VirtualProtect makes it executable), dump the region with Scylla/the dump plugin and fix the import table for the unpacked PE.

Step 4: Defeat simple anti-debugging

Patch or skip checks like IsDebuggerPresent, PEB BeingDebugged, and timing checks (see the anti-debugging skill). Set the return value to evade detection rather than removing the call.

Step 5: Record breakpoints and notes

Save a breakpoint plan and observations. The bundled script generates an x64dbg command script of API breakpoints to bootstrap a session.

python scripts/analyst.py breakpoints --preset unpacking > bp.txt

Validation

  • The dumped region is a valid PE (MZ/PE headers) and disassembles to real code.
  • API breakpoints fire in an order consistent with unpacking/injection.
  • Patched anti-debug checks no longer alter the execution path.

Pitfalls

  • Stepping blindly from the entry point instead of using API breakpoints — slow and easy to get lost.
  • Dumping too early (still encrypted) or too late (already executed/freed).
  • Removing anti-debug calls entirely, which can break control flow; prefer faking the result.

References