| name | debugging-malware-with-x64dbg |
| description | 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 reach hidden code. Activates for requests to debug malware with x64dbg, set API breakpoints, or step through unpacking in a debugger. |
| domain | cybersecurity |
| subdomain | reverse-engineering |
| tags | ["reverse-engineering","x64dbg","debugging","unpacking","breakpoints","windows"] |
| version | 1.0.0 |
| author | analyst-ai-pack |
| license | Apache-2.0 |
| mitre_attack | ["T1027","T1140","T1497","T1055"] |
| d3fend | ["D3-PSA","D3-FCR"] |
| references | ["x64dbg documentation — https://help.x64dbg.com/","Windows API reference — https://learn.microsoft.com/windows/win32/api/"] |
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