When to use / when not to use
- Use: dynamic debugging of native Windows targets (PE); attach/launch/breakpoints/memory search; Scylla repairing the IAT after unpacking
- Don't use: Linux targets (use [[re-gdb]]); macOS targets ([[re-lldb]]); analysis inside WSL (cannot attach across the boundary, see the WSL branch of [[re-analyze/platform-tips]])
- Don't use: read-only memory without interaction (on the Windows side use procdump/DumpIt + Volatility, see the Windows branch of [[re-analyze/platform-tips]])
- Don't use: automated batch runs/large-scale scripted operations without a UI (heavy lifting goes to the command box and scripts, see [[commands]])
- Use: verification scenarios that need a register/memory-level chain of evidence (authorization check path, decryption moment, call arguments); dynamic conclusions go into [[re-analyze/analysis-contract]]
Tool preparation
See the Windows branch of [[re-analyze/platform-tips]]—attach requires administrator privileges; memory dump toolchain procdump/DumpIt.
x64dbg
- Download: GitHub
x64dbg/x64dbgrelease (unzip and use, x64dbg.exe; x32dbg.exe in the same package handles 32-bit targets) - Windows:
choco install x64dbg - Verify: open x64dbg.exe,
File > Openloading any exe stops at the entry point - Version: v1.0 in 2023 is the only official stable release; from 2025.06.30 it switched to CalVer major versions (type system rework, AVX-512, script engine rewrite); snapshot builds (rolling dev) are newer than release but carry regression risk—use release for formal analysis, see [[gotchas]] for details
- The interface trio: CPU view (four panes: disassembly/registers/memory/stack), bottom command box (expressions+commands, see [[commands]]), view switching Alt+C / Alt+M / Alt+B, etc.
Scylla (IAT repair plugin)
- Newer official x64dbg releases already bundle it (Scylla is under the plugins/ directory, open with Ctrl+I)
- Standalone version: GitHub
NtQuery/Scyllarelease - Verify: Scylla appears in the x64dbg plugins menu, and can Attach to a process and list modules
OllyDbg (old 32-bit)
- Download: official site ollydbg.de (32-bit only, the mainstay before x64dbg appeared)
- Verify: opens and loads a 32-bit exe normally
- Note: plugins/scripts/databases are not interchangeable with x64dbg (see [[gotchas]])
Operating steps
-
Attach and launch modes (choose the right entry method first):
- Launch (
File > Open/ F3 / drag the exe into the window): the debugger takes over from process creation, and by default stops at the system breakpoint (ntdll);Alt+F9run to user code - Breakpoint timing:
Options > Settings > Eventsthe tab can check System/Entry Breakpoint, System/User TLS Callbacks, DLL Load/Unload, Thread Create/Exit, Exit Breakpoint—when you need logic before the entry point (TLS callbacks, constructors, DLL loading), enable the corresponding events here; if missed, it cannot be replayed - Attach (
File > Attach/ Alt+A, administrator privileges): the process is already running, and early initialization has finished—anti-debugging/anti-attach logic may have already run; if missed, it cannot be recovered; for multithreaded processes, after attaching press F12 to pause first and then set breakpoints, to avoid thread races; to end, usedetach/Alt+F2 - Windowless services/background processes: after attach, filter by process name/pid
- Static reconnaissance before dynamic: [[re-triage]] hash/packer identification → [[re-format-pe]] examine section permissions and entry point—decides where to set breakpoints and whether anti-debugging must be handled first
- For attach failures (permissions/protection), see pitfalls 1 and 3
- Launch (
-
Breakpoint family:
F2software breakpoint at address/symbol (INT3);Shift+F2conditional breakpoint, e.g.:[401000]==0x90(only when the memory value satisfies),eax==0x1000; breakpoint windowAlt+Bmanagement (Space to enable/disable, Delete to remove, double-click to edit condition/log)- Hardware breakpoint: right-click the selected line > Hardware breakpoint (execute/read/write), or command
bph—uses DR registers, at most 4, can break on data access without modifying code bytes (resists integrity checks) - Memory breakpoint:
Alt+Mright-click the selected region in the memory window > Set Memory BPX (triggered on access/write, implemented via GUARD_PAGE)—commonly used to catch the moment a key is decrypted or self-decrypting unpacking code - Log/command breakpoint: right-click in the breakpoint window to set a log expression and a command on hit; logs without pausing—batch-verify call arguments
- If a breakpoint does not hit, first check module loading:
Alt+Ein the module window, see whether the target module is already loaded; for breakpoints across reloads useAPI名or模块.函数form (e.g.bp kernel32.VirtualAlloc), effective automatically after the module reloads
-
Run and trace combinations:
F9continue running;F4run to cursor;Ctrl+F9run to function return (withF8to skip the call and quickly exit the function);Alt+F9run to user code (return from a system breakpoint/library code to the user module);F12pause;Ctrl+F2restart sessionF7/F8single-step (step in/step over);Shift+F7/Shift+F8single-step but skip exceptions (use when system APIs raise many internal exceptions)- Conditional tracing: command
ticnd <条件>/tocnd <条件>single-step continuously until the condition holds—automatically walk decryption loops/search for a specific state; trace recording (opentracecommand + run) can replay the instruction stream - For command-line combinations see [[commands]] (
bp/bph/bpm/find/savedataentered in the command box at the bottom, etc.)
-
Memory window and search:
Alt+Mopen Memory Map: view section permissions (abnormal RWX = packer/decryption section), module list- Search:
Ctrl+Bbinary mode (e.g.55 8B EC, supports?wildcards),Ctrl+Ffind in current view,Shift+Dstrings within a module - Locating workflow: string/constant →
Ctrl+Rfind cross-references → breakpoint at the reference/trace callers upward—validation comparison points and decryption functions both start from "who references it" - Dump window
Ctrl+Gjump to address;Ctrl+Eedit memory (change bytes to bypass checks) - Export: command
savedata <文件> <地址> <大小>save a memory region;minidump <文件>generate a full-memory dmp for [[re-mem-forensics]]
-
Registers and call stack:
- Modify values directly in the register window (right-click to change EAX/EFLAGS, etc.)—changing the return register (
EAX=0) or flags is the fastest way to rewrite a branch Alt+KCall stack window: Trace back the return address chain to locate "who called here"; the stack pane shows local variables/parameters (in x64, arguments are passed in RCX/RDX/R8/R9; on the stack they start at [rsp+0x28])- Set a breakpoint on the call target (
bp <API名>) to inspect the parameters; this is the most direct path to clarifying encryption/validation calls
- Modify values directly in the register window (right-click to change EAX/EFLAGS, etc.)—changing the return register (
-
Anti-debugging bypass:
- Right-click the register window to modify flags such as EFlags/ZF
- Break at
IsDebuggerPresent/NtQueryInformationProcess→ modify the return register (EAX=0) thenF9 - Timing/execution-count types: at the breakpoint comparison instruction, modify the comparison register
- First statically locate the detection points (use [[re-ida]] / [[re-format-pe]] to find detection API references and signature strings), then choose a bypass method: single-point modification of the return value/flags, ScyllaHide for batch hiding, or directly statically patch the detection point—the order is "point first, then surface"; running the whole toolkit will not produce a targeted result
- Anti-debugging plugin ScyllaHide (installed via the x64dbg plugin manager) hides debugging traces in batch; for boundaries and cases that cannot be bypassed, see [[gotchas]]
-
Scylla repairs the IAT (after unpacking):
Plugins > Scylla(Ctrl+I)→ 填 OEP → IAT Autosearch → Get Imports → Dump → Fix Dump- Workflow: run inside the packer until OEP (look for features of stack/memory that have been decrypted, or set a hardware breakpoint on OEP) →
Ctrl+Iopen Scylla → fill the OEP field with the full VA (usually auto-filled as entry point + ImageBase; if filling manually, also fill in the VA, not the RVA) →IAT Autosearch(both normal and advanced modes; if results differ, try both) →Get Importsvalidate imports →Dumpdump the process image →Fix Dumpselect the dump file from earlier, and output the repaired clean exe (*_SCY.exe) - Failure form: the log shows
IAT not found at OEP ...= OEP was filled in incorrectly; return to the debugger to confirm the real OEP and start over; after Get Imports, red invalid entries can be deleted with Cut thunk; it is normal for the dump file to not run directly—without Fix Dump there is no IAT - Preserve the repaired file's sha256 for comparison with the original as evidence (see [[re-triage]])
- Workflow: run inside the packer until OEP (look for features of stack/memory that have been decrypted, or set a hardware breakpoint on OEP) →
-
Patching and saving (persisting the validation bypass):
Ctrl+Emodify bytes orSpaceassemble in place →View > Patches(Ctrl+P) view the list of modifications →Save filewrite back to disk as a new exe /Save patchexport a.1337patch file (distributable and reusable)- Before patching, record the original bytes; use
Undo selection(Ctrl+Backspace) for rollback; for patch localization methodology, see [[re-patching]]
-
Evidence verification (wrap-up): breakpoint hit records/register and memory evidence (
Ctrl+Eview and archive),savedata/minidumpexport artifacts, Scylla repaired file sha256—all filed against the [[re-triage]] initial survey values; write conclusions to [[re-analyze/analysis-contract]]
Cross-domain combinations
- [[re-binary-core]]: workflow step 6 (Windows debugger)
- [[re-anti-analysis]]: core tool for unpacking (run to OEP + Scylla repair)
- [[re-cracking]]: locating registration code/validation logic
- [[re-imports]]: comparing IAT integrity after Scylla repair
- [[re-patching]]: making a persistent patch after debugging confirms the validation point
- [[re-triage]]: sample hashes/initial survey come first; compare debugging conclusions against them
- Complementary to [[re-memdump]] (procdump fallback on the Windows side); see [[re-analyze/platform-tips]]
Common pitfalls and traps
- Requires administrator privileges: attach to a high-privilege process/service failed—start x64dbg as administrator; if it still fails, check for a protected process
- Anti-debugging/anti-attach:
ThreadHideFromDebugger/NtSetInformationThreador offline detection—use the ScyllaHide plugin to hide debugging traces, or statically patch the self-check points first - Cannot attach to a PPL process(Protected Process Light, such as some EDR/system processes)—x64dbg has no driver and cannot attach; switch to kernel debugging or give up on that target
- Bitness matching: a 64-bit target must use x64dbg (x32dbg only supports 32-bit); mixing them causes load failure/crash
- When attach fails, first distinguish permissions from PPL/protected processes: Symptom—running x64dbg as administrator still fails to attach; Cause—ordinary privilege restrictions can be solved by administrator, while PPL (Protected Process Light) depends on the Signer Level (EDR commonly uses PPL-Windows TCB/Antimalware), and you cannot attach without the corresponding level; Countermeasure—first confirm whether the target is PPL (the Protection column in Process Explorer) and its Signer Level, then prepare the corresponding debugging capability for that level (same-level driver/kernel debugging), see the Windows branch of [[re-analyze/platform-tips]]
- Program crashes only under x64dbg → check for debugger fingerprint detection: Symptom—the sample works normally in its native environment and also works normally under other debuggers, but crashes or changes behavior after being loaded/attached by x64dbg; Cause—the sample detects debugger fingerprints (x64dbg modules/window classes/DLL names/memory characteristics) and deliberately crashes or switches logic after recognizing x64dbg; Countermeasure—first statically find the fingerprint strings/window class names/module names ([[re-ida]] / [[re-format-pe]]), patch the fingerprint detection points or hide x64dbg traces (ScyllaHide), then reload (see AD31 in the [[re-anti-analysis]] anti-debugging methodology)
- Hardware breakpoints detected (DR registers): Symptom—the process exits immediately after setting a hardware breakpoint/memory breakpoint, or the breakpoint does not trigger; Cause—the sample reads the debug registers (DR0-DR3/DR6/DR7) to detect hardware breakpoints; Countermeasure—hide via ScyllaHide injection (HookLibrary/InjectorCLI), or switch to logical breakpoints to avoid DR traces; if necessary, first statically patch the DR detection points and then attach (see AD15 in the [[re-anti-analysis]] anti-debugging methodology)
- Breakpoint set but not hit: first
Alt+Econfirm that the module is loaded and the address falls on the post-load base address; if the code section has been rewritten (packer decryption), it will overwrite INT3—set the breakpoint again after decryption completes - Analysis blind spots in attach mode: pre-entry logic (TLS callbacks, constructors, decryption initialization) has already executed when attaching—to inspect registration/initialization-type logic, you must choose launch mode + Events breakpoints; do not look for processes that do not exist in attach mode
- Do not treat a Scylla dump output that "cannot run" as a failure: a dump file without Fix Dump has no IAT and will inevitably crash if run directly; if it still crashes after fixing, then check invalid import entries and whether the OEP is correct
- For version differences, Scylla details, and the boundaries of anti-debugging bypasses (including cases where "it cannot be bypassed"), see [[gotchas]]