SuperAPI AI Directory

re-windbg

General & other

View repository

Updated 10-16 05:06

About this skill

WinDbg dynamic debugging (Windows user mode + kernel)

When to use / when not to use

  • Use: Windows user-mode process debugging (launch/attach, breakpoints, single-stepping, registers); crash/exception analysis (!analyze -v); kernel debugging (two-machine/VM/local kd); driver and kernel module analysis (together with [[re-kernel]]); crash dump (minidump/full dump) analysis
  • Use: Time Travel Debugging (TTD) —ttd.exe after recording a .run trace, replay at any point, suitable for verification/decryption logic where "reproduce once and investigate slowly" (see [[commands]] TTD section)
  • Don't use: Linux targets (use [[re-gdb]]); macOS targets ([[re-lldb]]); when you only need lightweight GUI debugging ([[re-x64dbg]] is faster)
  • Don't use: when only doing static analysis/decompilation ([[re-ida]] / [[re-ghidra]] / [[re-binaryninja]]); purely static workflows that don't need to interact with the running state don't need a debugger
  • Don't use: attaching across the boundary to Windows processes inside WSL ([[re-analyze/platform-tips]] WSL branch: for cross-boundary use Windows-side tools)

Tool preparation

Refer to [[re-analyze/platform-tips]] Windows branch — attaching requires administrator privileges; debugging is dynamic execution and is performed inside a sandbox by default ([[re-analyze/platform-tips]] highest principle).

WinDbg (Microsoft Store version / Windows SDK / WDK)

  • Store version (new UI WinDbg):winget install Microsoft.WinDbg(or search "WinDbg" in the Microsoft Store)
  • Classic version: in the Windows SDK installer, check "Debugging Tools for Windows";choco install windbg
  • WDK (includes kernel debugging tools kd.exe/kdnet.exe):winget install Microsoft.WindowsWDK or check WDK in the Visual Studio installer
  • Verify: open WinDbg,File > Open Executable loading any exe should stop at the initial breakpoint; in the command window ver outputs the version number
  • Version differences: the Store version (WinDbg 1.x, Chromium UI) and the classic version (WinDbg 10.0.x) are command-compatible, but the UI and attach workflow differ; dump analysis works the same for both (see [[gotchas]])

Windows symbols (Windows SDK symbols / public symbol server)

  • Symbol path: .sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols(or set the environment variable _NT_SYMBOL_PATH)
  • Kernel module symbols: under kernel debugging .reload /f nt(force pulling from the symbol server)
  • Verify: !analyze -v function names appear in the output instead of +0x1a bare offsets

Two-machine/virtual machine kernel debugging environment

  • Target machine (being debugged): bcdedit /debug on + bcdedit /dbgsettings serial debugport:1 baudrate:115200(serial port) or bcdedit /dbgsettings net hostip:<宿主机IP> port:50000 key:<kdnet.exe生成的key>(NET network card, recommended for Windows 10+)
  • VM scenario: VMware/Hyper-V add a serial device to the target VM (Named Pipe \\.\pipe\com_1 / -vmconnect), on the host WinDbg File > Kernel Debug > COM fill in the pipe name
  • Local kernel debugging (test machines only, requires test signing): bcdedit /set testsigning on after restart, WinDbg File > Kernel Debug > Local
  • Verify: after the target machine restarts and stops at "Waiting to reconnect" or enters the debug wait, the host WinDbg attaches successfully,g after Ctrl+Break can break in,lm lists modules

TTD (Time Travel Debugging, Windows 10 1903+)

  • Recording: ttd.exe -out C:\traces target.exe(or -attach <pid> attach and record;-monitor <进程名> monitor launch)
  • Open: WinDbg File > Open select .run trace file (or Open Trace File)
  • Verification: ttd.exe -help there is output; after recording a session, open it with WinDbg,!tt you can jump to any position,g- and you can run backwards (see the [[commands]] TTD section)

Steps

  1. Attach/launch a user-mode target:

    • Launch: File > Open Executable select the target exe, stop at the initial breakpoint (where ntdll has finished loading)
    • Attach: File > Attach to Process select the target by PID/process name (administrator privilegesstart WinDbg to attach to a high-privilege process)
    • Command line: windbg -p <pid> / windbg 目标.exe;-g skip the initial breakpoint and run directly
  2. Breakpoints / stepping / registers:

    • Symbol breakpoint: bp kernel32!CreateFileW; address breakpoint: bp 0x401000;bl list,bd/be disable/enable,bc * clear
    • For symbols in modules that are not loaded, use bu(unresolved, automatically bound after the module loads) — when the target DLL is loaded on demand, bu is the right answer
    • Command breakpoint: bp 地址 "r rax; k; gc"— when hit, print the state and automatically continue, observing log-style without interrupting the flow
    • Stepping: g continue,p step over,t step into,gu execute until the current function returns
    • Registers: r all,r rax view,r eax=0 modify (commonly used to bypass validation)
    • Memory/disassembly: u 0x401000 disassemble,dd/db read memory,dps rsp view stack contents
    • Search: s -d 0x0 L?10000000 0xdeadbeef(value),s -a 0x0 L?10000000 "text"(ASCII string) — used to find hardcoded constants/keys
    • Symbol search: x 模块!*关键字*(such as x kernel32!*Virtual*) — fuzzy matching when you are unsure of the exact symbol name
  3. Exception analysis !analyze -v:

    • After the target crashes and stops: !analyze -v → read EXCEPTION_CODE、FAULTING_IP、STACK_TEXT、PROCESS_NAME
    • Kernel blue screen corresponds to the bugcheck code (BUGCHECK_CODE, such as 0xD1 for a driver accessing invalid memory) — write down the code first, then investigate; the meaning of common codes should match the fault direction
    • Context recovery: from STACK_TEXT get the EXCEPTION_RECORD address .exr <addr>(exception record), then get the CONTEXT address .cxr <addr> to restore the register context, and then k output the real call stack (the only reliable stack unwinding method when the stack is corrupted)
    • Dump context is simpler: after opening the dump, directly .ecxr(automatically set the register context using the exception context) → k— the standard opening for minidump analysis
    • Dump analysis: File > Open Crash Dump open .dmp(for user mode use .dump /ma to generate; for kernel blue screens use %SystemRoot%\Minidump\*.dmp or a complete dump), and similarly !analyze -v output the bugcheck code and faulty module
  4. Kernel debugging (two-machine / VM / local kd):

    • See "Tool preparation" for target machine configuration; after configuring, restart, and the host File > Kernel Debug connects using the transport used (COM/NET)
    • VM pipe serial port procedure: add a serial port Named Pipe to the target VM → target machine bcdedit /dbgsettings serial → host File > Kernel Debug > COM Fill in the pipe name (\\.\pipe\com_1) → target machine restarts, etc., connect
    • After connecting: g Let the target keep running;Ctrl+Break interrupt back to the debugger at any time;!process 0 0 confirm the session is alive
    • Local debugging: bcdedit /set testsigning on After restart File > Kernel Debug > Local(test machine only, does not affect production machine usage)
  5. Extended commands:

    • !process 0 0(full process list),!process <EPROCESS> 1(single-process details + threads);.process /p <EPROCESS> after switching to the target process context, then k/!thread
    • !teb(current thread TEB),!peb(current process PEB — command line, loaded modules, environment block)
    • lm(module list, line end (deferred)=symbols not loaded,(no symbols)=no symbols),lmv m <模块>(version + path),lmi <模块>(image headers)
    • kv(full stack backtrace with symbols, commonly used in driver analysis),!analyze -v then press STACK_TEXT to verify frame by frame
    • Driver-specific: lmv m 驱动名 get the base address → .reload /f 驱动名 load symbols → dig deeper by turning to [[re-kernel]]
  6. TTD replay (slow investigation of validation/decryption logic):

    ttd.exe -out C:\traces target.exe     # 录制
    WinDbg 打开 .run → g- / t- / p-       # 往回跑
    !tt 50                                 # 跳到轨迹 50% 处
    !tt 7213:36                            # 跳指定位置(事件序号:步数)
    
    • Move breakpoint backward/forward: !tt br stop where a register value changes;!tt bm stop at a memory access
    • First time opening a trace, first !tt.index build the index (subsequent opens skip it); during replay you can also breakpoint bp(work on the trace)
    • Query API: dx @$cursession.TTD.Calls("模块!函数") count calls/parameters (e.g. ...Calls("ntdll!mem*"))
    • TTD limitations: requires running as administrator, user-mode only, trace files are very large (several GB), replay is read-only and cannot write memory (see [[gotchas]])
  7. Pseudo-registers and scripting (simple automation):

    • Pseudo-registers: r $t0 = 0 to create temporary variables;$$ > <文件> redirect command output to a file (e.g. $$ > c:\log.txt)
    • Conditional execution: .if (rax==0) { ... } .else { ... }— combined with gc to do logic inside breakpoints
    • !runaway view thread CPU time (find busy-waiting/infinite-loop threads);!locks check lock status (hang troubleshooting)

Cross-domain combinations

  • [[re-binary-core]]: workflow step 6 Windows debugger (user mode + kernel)
  • [[re-kernel]]: kernel debugging and driver/rootkit runtime verification always invoke this skill
  • [[re-anti-analysis]]: anti-debugging countermeasures (kernel-level detection points), post-unpacking verification
  • [[re-malware]]: malicious sample crash dump analysis and kernel components
  • [[re-cracking]]: locating authorization check crashes (!analyze -v quickly find the crash cause)
  • Complements [[re-x64dbg]]: use x64dbg for lightweight GUI breakpoint debugging, use WinDbg for kernel/exception scene recovery/trace replay

Common pitfalls and traps

  • Symbols not configured → all raw offsets without function names: symptom —lm line end (no symbols),k output ntdll!+0x1a; cause — symbol path is empty or not _NT_SYMBOL_PATH; countermeasure —.sympath srv*C:\symbols*https://msdl.microsoft.com/download/symbols after .reload /f, same for kernel modules (first confirm the symbol server is reachable)
  • Kernel debugging misconfigured → target machine bluescreens, waits forever, or cannot connect: Symptom — after the target machine restarts, it stays at the debug wait or boots straight into the system without breaking; Cause — the bcdedit transport type/port does not match the host, or local debugging on a standalone physical machine is restricted (PatchGuard); Countermeasure — a VM serial pipe is the most reliable (both sides must \\.\pipe\com_1),bcdedit /dbgsettings recheck the configuration; for physical machine scenarios, prefer KDNET
  • 32/64-bit command and register differences: Symptom — under a 64-bit target, r eax changes the wrong value,!teb fields do not match; Cause — the x64 context uses rax/rbx...(the low 32 bits are eax , etc.), and in wow64 the target thread stack is at the x86 layer; Countermeasure — first confirm the target bitness; in wow64 scenarios, .load wow64exts + !wow64exts.sw switch to the x86 context
  • When the stack is corrupted, k is an illusion: Symptom — the call stack is garbled (addresses do not look like code); Cause — the stack pointer has been corrupted/memory has been trampled, so a normal backtrace is unreliable; Countermeasure — use .exr to get the exception record,.cxr restore the CONTEXT and then k, and if necessary !analyze -v in STACK_TEXT to retrieve the scene directly
  • The blue screen dump cannot be opened: Symptom —Open Crash Dump reports a format error; Cause — the minidump is incomplete (disk full) or a 32-bit WinDbg is being used to read a 64-bit dump; Countermeasure — confirm on the target machine that the kernel page swap file (crash dump requires a pagefile) is large enough, and switch to a WinDbg of the same bitness
  • Unified entry point for RPC calls NdrStubCall3 (svchost feature reverse engineering): Symptom — you want to intercept/analyze a system feature (such as Toast notifications) but do not know through which channel it enters svchost; Cause — the feature is implemented via RPC to the svchost process, and the entry point is hard to find; Countermeasure — use Process Monitor to see the target process load rpcrt4.dll + RpcView to confirm the RPC target process;All RPC server stubs uniformly go through rpcrt4's NdrStubCall3(x64; NdrStubCall2 is the old x86 version, as can be corroborated by the ReactOS/Wine source) — set a breakpoint on it kvn to see the call source; filter the target call: the third parameter (r8) points to RPC_MESSAGE (+0x1C is ProcNum method number, +0x28 is the interface description pointer RpcInterfaceInformation → RPC_SERVER_INTERFACE's InterfaceId at +0x04);opnum is numbered from 0 by MIDL according to the method declaration order(for example, PostNotification3 is at position 0x29 → opnum=0x29), and in ObjectStublessClientN, rax=N means ProcNum; Pitfall: NdrStubCall3 handles all RPC interfaces within svchost,you must filter by both InterfaceId + ProcNum, and intercept only the target method (intercepting the wrong one will break other features such as Edge)
  • For TTD limitations, version differences, and symbol server details, see [[gotchas]]