Skip to content

Latest commit

 

History

History
1434 lines (1186 loc) · 68 KB

File metadata and controls

1434 lines (1186 loc) · 68 KB

WinDbg Training Manual

A Complete Entry-Level Guide to Windows Debugging


Table of Contents

  1. Introduction to Windows Debugger
  2. What is a Debugger?
  3. WinDbg Interface
  4. Understanding the Workspace
  5. Debugging Symbols
  6. Accessing and Manipulating Memory from WinDbg
  7. Reading from Memory
  8. Dumping Structures from Memory
  9. Writing to Memory
  10. Searching the Memory Space
  11. Inspecting and Editing CPU Registers in WinDbg
  12. Controlling the Program Execution in WinDbg
  13. Software Breakpoints
  14. Unresolved Function Breakpoint
  15. Breakpoint-Based Actions
  16. Hardware Breakpoints
  17. Stepping Through the Code
  18. Additional WinDbg Features
  19. Listing Modules and Symbols in WinDbg
  20. Using WinDbg as a Calculator
  21. Data Output Format

1. Introduction to Windows Debugger

What is WinDbg?

WinDbg (Windows Debugger) is Microsoft's flagship debugging tool, part of the Windows SDK. It's a powerful, command-line driven debugger capable of analyzing both user-mode applications and kernel-mode components. WinDbg is essential for system administrators, developers, and security researchers working with Windows systems.

Evolution of Windows Debugging Tools

timeline
    title Windows Debugging Tools Evolution
    1990s : Early Windows Debuggers
          : Basic debugging capabilities
          : Limited symbol support
    2000s : WinDbg Classic
          : Command-line interface
          : Symbol server support
    2010s : Enhanced WinDbg
          : 64-bit support
          : JavaScript scripting
    2020s : WinDbg Preview
          : Modern UI
          : Time Travel Debugging
          : Enhanced usability
Loading

WinDbg Capabilities Overview

Feature Category Capabilities Use Cases
Process Analysis Live process debugging, crash dump analysis Application troubleshooting
Memory Analysis Memory dumps, heap analysis, leak detection Performance optimization
Kernel Debugging System crash analysis, driver debugging System administration
Security Analysis Exploit analysis, malware investigation Security research

WinDbg vs Other Debuggers

Debugger Comparison Matrix:
┌─────────────────────────────────────────────────────────────────┐
│                    Feature Comparison                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Feature          │ WinDbg │ Visual Studio │ GDB   │ OllyDbg   │
│  ─────────────────┼────────┼───────────────┼───────┼───────────┤
│  User Mode        │   ✓    │       ✓       │   ✓   │     ✓     │
│  Kernel Mode      │   ✓    │       ✗       │   ✗   │     ✗     │
│  Crash Dumps      │   ✓    │       ✓       │   ✓   │     ✗     │
│  Remote Debug     │   ✓    │       ✓       │   ✓   │     ✗     │
│  Scripting        │   ✓    │       ✓       │   ✓   │     ✗     │
│  Symbol Support   │   ✓    │       ✓       │   ✓   │     ✓     │
│  Learning Curve   │  High  │     Medium    │  High │   Medium  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Why Learn WinDbg?

Professional Applications

Role WinDbg Usage Key Benefits
Software Developer Bug hunting, performance analysis Deep system understanding
System Administrator Crash analysis, troubleshooting System stability
Security Researcher Malware analysis, exploit development Low-level system access
Quality Assurance Test failure analysis, regression testing Comprehensive debugging

2. What is a Debugger?

Fundamental Debugging Concepts

A debugger is a specialized software tool that allows developers and analysts to examine the execution of another program. It provides the ability to pause execution, inspect state, modify behavior, and understand program flow.

Types of Debuggers

Classification by Target

Debugger Classification:
┌─────────────────────────────────────────────────────────────────┐
│                        Debugger Types                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────┐    ┌─────────────────┐                    │
│  │   User Mode     │    │   Kernel Mode   │                    │
│  │   Debuggers     │    │   Debuggers     │                    │
│  │                 │    │                 │                    │
│  │ • Application   │    │ • System level  │                    │
│  │   debugging     │    │   debugging     │                    │
│  │ • Process level │    │ • Driver debug  │                    │
│  │ • Limited scope │    │ • Full system   │                    │
│  └─────────────────┘    └─────────────────┘                    │
│                                                                 │
│  ┌─────────────────┐    ┌─────────────────┐                    │
│  │    Local        │    │     Remote      │                    │
│  │   Debuggers     │    │   Debuggers     │                    │
│  │                 │    │                 │                    │
│  │ • Same machine  │    │ • Network based │                    │
│  │ • Direct access │    │ • Separate host │                    │
│  │ • Fast response │    │ • Isolated env  │                    │
│  └─────────────────┘    └─────────────────┘                    │
└─────────────────────────────────────────────────────────────────┘

Core Debugging Operations

Essential Debugging Functions

Core Debugging Operations:
┌─────────────────────────────────────────┐
│              Execution Control          │
│  ┌─────────────────────────────────────┐ │
│  │ • Start/Stop execution              │ │
│  │ • Step through instructions        │ │
│  │ • Breakpoint management             │ │
│  │ • Program flow control             │ │
│  └─────────────────────────────────────┘ │
├─────────────────────────────────────────┤
│               State Inspection          │
│  ┌─────────────────────────────────────┐ │
│  │ • Register examination              │ │
│  │ • Memory content viewing            │ │
│  │ • Variable value inspection         │ │
│  │ • Call stack analysis              │ │
│  └─────────────────────────────────────┘ │
├─────────────────────────────────────────┤
│              Modification               │
│  ┌─────────────────────────────────────┐ │
│  │ • Memory content changes            │ │
│  │ • Register value updates            │ │
│  │ • Execution path alteration         │ │
│  │ • Conditional execution             │ │
│  └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘

Debugging Workflow

Typical Debugging Session

flowchart TD
    A[Problem Identified] --> B[Attach Debugger]
    B --> C[Load Symbols]
    C --> D[Set Breakpoints]
    D --> E[Execute Program]
    E --> F{Breakpoint Hit?}
    F -->|Yes| G[Examine State]
    F -->|No| H[Check for Issues]
    G --> I[Analyze Data]
    I --> J{Problem Found?}
    J -->|Yes| K[Document Solution]
    J -->|No| L[Continue Debugging]
    L --> E
    H --> M[Program Complete]
    K --> N[End Session]
    M --> N
Loading

3. WinDbg Interface

WinDbg Versions Overview

WinDbg comes in multiple versions, each with distinct interfaces and capabilities:

Version Comparison

Version Interface Type Key Features Best For
WinDbg Classic Command-line driven Powerful commands, scripting Advanced users, automation
WinDbg Preview Modern GUI Visual interface, TTD support New users, interactive debugging
CDB Console-only Lightweight, scriptable Automated testing, CI/CD
KD Kernel debugging Kernel-mode focus System debugging

WinDbg Classic Interface

Main Interface Components

WinDbg Classic Layout:
┌─────────────────────────────────────────────────────────────────┐
│ File  Edit  View  Debug  Options  Window  Help                 │ ← Menu Bar
├─────────────────────────────────────────────────────────────────┤
│ [Open] [Attach] [Go] [Break] [Step] [Trace] [Watch] [Memory]    │ ← Toolbar
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Command Window                     │  Watch Window             │
│  ─────────────────                  │  ──────────────           │
│  Microsoft (R) Windows Debugger    │                           │
│  0:000> !analyze -v                │  Expression: eax          │
│  *****************************     │  Value: 0x00000042       │
│  *     Exception Analysis     *     │                           │
│  *****************************     │  Expression: ebp+8        │
│  FAULTING_IP:                      │  Value: 0x0012ff40       │
│  myapp!main+0x23                   │                           │
│  00401053 8b08    mov ecx,[eax]     │                           │
│                                    │                           │
├─────────────────────────────────────┼───────────────────────────┤
│  Disassembly Window                │  Registers Window         │
│  ──────────────────                │  ────────────────         │
│  myapp!main:                       │  eax=00000000 ebx=7ffdf000│
│  00401030 55       push    ebp     │  ecx=00000001 edx=00322a70│
│  00401031 8bec     mov     ebp,esp │  esi=00000000 edi=00000000│
│  00401033 51       push    ecx     │  esp=0012ff80 ebp=0012ff94│
│ →00401034 8b4508   mov     eax,[ebp+8] │  eip=00401034 efl=00000246│
│  00401037 8945fc   mov     [ebp-4],eax │                           │
│                                    │  cs=001b ss=0023 ds=0023  │
├─────────────────────────────────────┼───────────────────────────┤
│  Call Stack Window                 │  Memory Window            │
│  ─────────────────                 │  ─────────────            │
│  ChildEBP RetAddr                  │  0012ff80  8b 4d 08 89   │
│  0012ff80 004010b2 myapp!main+0x23 │  0012ff84  45 fc 8b 45   │
│  0012ff94 004011f6 myapp!wmain+0x42│  0012ff88  08 89 45 f8   │
│  0012ffc0 7c817067 myapp!__tmain+0x96│ 0012ff8c  8b 4d fc 8b   │
│                                    │  0012ff90  55 08 3b c1   │
└─────────────────────────────────────┴───────────────────────────┘

Key Interface Elements

Window Purpose Common Usage
Command Window Primary interaction Enter commands, view output
Disassembly Window Assembly code view Step through instructions
Registers Window CPU register state Monitor register changes
Memory Window Raw memory content Examine data structures
Call Stack Window Function call hierarchy Trace execution path
Watch Window Expression evaluation Monitor variables

WinDbg Preview Interface

Modern Interface Features

WinDbg Preview Layout:
┌─────────────────────────────────────────────────────────────────┐
│ ☰ File  Debug  View  Window  Help                    🔍 Search  │ ← Ribbon Menu
├─────────────────────────────────────────────────────────────────┤
│ 📁 Open dump  🔗 Attach  ▶️ Go  ⏸️ Break  👟 Step  🔄 Restart    │ ← Quick Access
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ ┌─ Command ──────────────────┐ ┌─ Source ─────────────────────┐ │
│ │ 0:000> !analyze -v         │ │ 1: int main(int argc, char* │ │
│ │ FAULTING_IP:               │ │ 2: {                        │ │
│ │ test!main+0x17             │ │ 3:     int* ptr = nullptr;  │ │
│ │ 00000001 8b08  mov ecx,[eax│ │ 4:  ► return *ptr;         │ │ ← Source highlighting
│ │                            │ │ 5: }                        │ │
│ │ 0:000>                     │ │                             │ │
│ └────────────────────────────┘ └─────────────────────────────┘ │
│                                                                 │
│ ┌─ Disassembly ──────────────┐ ┌─ Registers ─────────────────┐ │
│ │ test!main:                 │ │ 📍 General Registers        │ │
│ │ 00000001 55    push   rbp  │ │ rax = 0000000000000000     │ │
│ │ 00000002 48    mov    rbp, │ │ rbx = 00007ff7c2f01000     │ │
│ │ 00000004 48    sub    rsp, │ │ rcx = 0000000000000001     │ │
│ │►00000008 c7    mov    qword│ │ 📍 Flag Register            │ │
│ │ 00000010 48    mov    rax, │ │ IOPL: 0  of: 0  sf: 0      │ │
│ └────────────────────────────┘ └─────────────────────────────┘ │
│                                                                 │
│ ┌─ Memory ───────────────────┐ ┌─ Call Stack ────────────────┐ │
│ │ Address: 0x0012ff80        │ │ 🏠 test!main+0x17          │ │
│ │ 00000000: 8b 4d 08 89 45   │ │    kernel32!BaseThread...   │ │
│ │ 00000004: fc 8b 45 08 89   │ │    ntdll!RtlUserThread...   │ │
│ │ 00000008: 45 f8 8b 4d fc   │ │                             │ │
│ └────────────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Interface Customization

Keyboard Shortcuts

Function Shortcut Description
Break Ctrl+Break Stop execution
Go F5 Continue execution
Step Into F11 Execute one instruction
Step Over F10 Step over function calls
Run to Cursor Ctrl+F10 Execute until cursor position
Toggle Breakpoint F9 Set/clear breakpoint

4. Understanding the Workspace

Workspace Components

A WinDbg workspace consists of multiple interconnected windows that provide different views of the debugging target. Understanding how these components work together is crucial for effective debugging.

Workspace Architecture

WinDbg Workspace Flow:
┌─────────────────────────────────────────────────────────────────┐
│                        Target Process                          │
├─────────────────────────────────────────────────────────────────┤
│                             ↕                                  │
│                    Debugging Engine                            │
│                             ↕                                  │
├─────────────────────────────────────────────────────────────────┤
│                    WinDbg Interface                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │  Command    │  │  Memory     │  │  Registers  │            │
│  │  Window     │  │  Windows    │  │  Window     │            │
│  └─────────────┘  └─────────────┘  └─────────────┘            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐            │
│  │ Disassembly │  │ Call Stack  │  │   Watch     │            │
│  │   Window    │  │   Window    │  │  Window     │            │
│  └─────────────┘  └─────────────┘  └─────────────┘            │
└─────────────────────────────────────────────────────────────────┘

Primary Windows

Command Window

The Command Window is the heart of WinDbg interaction:

Command Window Features:
┌─────────────────────────────────────────┐
│ Microsoft (R) Windows Debugger         │
│ Version 10.0.22621.2428 AMD64          │
│ Copyright (c) Microsoft Corporation.   │
│                                         │
│ CommandLine: "C:\test\myapp.exe"        │
│ Symbol search path is: SRV*C:\symbols* │
│                                         │
│ ModLoad: 00007ff6`12340000 ...         │
│ ModLoad: 00007ffc`d5f10000 ...         │
│                                         │
│ (1234.5678): Break instruction exc...   │
│ Execute '.help' for information         │
│                                         │
│ 0:000> █                               │ ← Command prompt
└─────────────────────────────────────────┘

Workspace Management

Saving and Loading Workspaces

Operation Classic WinDbg WinDbg Preview
Save Workspace File > Save Workspace As Automatic with project
Load Workspace File > Open Workspace Recent workspaces list
Default Workspace Stored in registry User profile folder

5. Debugging Symbols

What are Debugging Symbols?

Debugging symbols are metadata that provide a mapping between compiled binary code and the original source code. They contain information about function names, variable names, data types, and source line numbers.

Symbol File Types

Symbol File Formats

Format Extension Content Use Case
Program Database .pdb Full debug information Development debugging
Debug File .dbg Basic symbol information Legacy support
Symbol File .sym Minimal symbol data Distribution
Map File .map Address mappings Basic debugging

Symbol Path Configuration

Setting Symbol Paths

The symbol path tells WinDbg where to find symbol files:

Symbol Path Components:
┌─────────────────────────────────────────┐
│ Symbol Path Format:                     │
│                                         │
│ cache*localdir*srv*symbolserver         │
│   │      │        │       │             │
│   │      │        │       └─ Symbol server URL
│   │      │        └───────── Server indicator
│   │      └────────────────── Local cache directory
│   └───────────────────────── Cache indicator
│                                         │
│ Example:                                │
│ cache*c:\symbols*srv*                   │
│ https://msdl.microsoft.com/download/symbols
└─────────────────────────────────────────┘

Symbol Path Configuration Methods

Method Command/Location Scope
Environment Variable _NT_SYMBOL_PATH System-wide
WinDbg Command .sympath Session-specific
Command Line -y parameter Launch-specific
Registry WinDbg settings User-specific

Symbol Loading Process

Automatic Symbol Loading

flowchart TD
    A[Module Loaded] --> B[Check Local Path]
    B --> C{Symbol Found?}
    C -->|Yes| D[Load Local Symbol]
    C -->|No| E[Check Cache]
    E --> F{Symbol Found?}
    F -->|Yes| G[Load Cached Symbol]
    F -->|No| H[Download from Server]
    H --> I{Download Success?}
    I -->|Yes| J[Cache Symbol]
    I -->|No| K[Use Export Information]
    J --> L[Load Symbol]
    D --> M[Symbol Ready]
    G --> M
    L --> M
    K --> N[Limited Information]
Loading

Symbol Loading Commands

Command Purpose Example
.sympath Show/set symbol path .sympath srv*c:\symbols*https://msdl.microsoft.com/download/symbols
.reload Reload symbols .reload /f kernel32
.symopt Symbol options .symopt +0x40
ld Load symbols ld kernel32

6. Accessing and Manipulating Memory from WinDbg

Memory Architecture in WinDbg

WinDbg provides comprehensive memory access capabilities, allowing examination and modification of target process memory in various formats and granularities.

Memory Address Types

Virtual vs Physical Addresses

Memory Address Types:
┌─────────────────────────────────────────────────────────────────┐
│                    Virtual Addresses                           │
│  ┌─────────────────────────────────────────────────────────────┐ │
│  │ User Mode (0x00000000 - 0x7FFFFFFF)                        │ │
│  │ • Application memory space                                  │ │
│  │ • Process-specific addressing                               │ │
│  │ • Accessible in user-mode debugging                        │ │
│  └─────────────────────────────────────────────────────────────┘ │
│  ┌─────────────────────────────────────────────────────────────┐ │
│  │ Kernel Mode (0x80000000 - 0xFFFFFFFF)                      │ │
│  │ • System memory space                                       │ │
│  │ • Shared across processes                                   │ │
│  │ • Requires kernel debugging                                 │ │
│  └─────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│                    Physical Addresses                          │
│  • Actual RAM locations                                        │
│  • Hardware-level addressing                                   │
│  • Kernel debugging required                                   │
└─────────────────────────────────────────────────────────────────┘

Memory Access Commands Overview

Basic Memory Commands

Command Purpose Syntax Example
d Display memory d[type] address [length] dd 0x401000 L4
e Edit memory e[type] address value ed 0x401000 12345678
s Search memory s[type] range pattern s -a 0x401000 L1000 "hello"
f Fill memory f address L length value f 0x401000 L100 0x90

7. Reading from Memory

Basic Memory Reading Commands

Memory reading is one of the most fundamental operations in WinDbg. Understanding the various display formats and options is crucial for effective debugging.

Core Display Commands

The d command family provides comprehensive memory display capabilities:

Display Command Syntax:
┌─────────────────────────────────────────┐
│ d[format] [address] [L length]          │
│                                         │
│ Where:                                  │
│ • format  = b,w,d,q,a,u,c,f,D           │
│ • address = memory location             │
│ • length  = number of elements          │
│                                         │
│ Examples:                               │
│ db 401000      - bytes at 401000        │
│ dd 401000 L10  - 10 dwords at 401000    │
│ da @esp+4      - ASCII at ESP+4         │
└─────────────────────────────────────────┘

Detailed Display Formats

Byte Display (db)

Byte Display Example:
0:000> db 0x401000 L20
00401000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
00401010  b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00  ........@.......

Format breakdown:
• Address: 00401000
• Hex bytes: 4d 5a 90 00...
• ASCII: MZ..............
• Dash separator every 8 bytes

String Display Formats

ASCII String Examples:
┌─────────────────────────────────────────┐
│ Single string:                          │
│ 0:000> da 0x402000                      │
│ 00402000  "Hello World"                 │
│                                         │
│ Unicode display:                        │
│ 0:000> du 0x403000                      │
│ 00403000  "Hello World"                 │
│                                         │
│ Raw Unicode bytes:                      │
│ 0:000> db 0x403000 L20                  │
│ 00403000  48 00 65 00 6c 00 6c 00-6f 00 20 00 57 00...
│           H  .  e  .  l  .  l  .  o  .     .  W  .
└─────────────────────────────────────────┘

8. Dumping Structures from Memory

Structure Analysis Overview

Structure dumping is a powerful feature that allows examination of complex data types using their symbolic information. This capability is essential for understanding object layouts, debugging data corruption, and analyzing program state.

The dt Command

The dt (display type) command is the primary tool for structure analysis:

dt Command Syntax:
┌─────────────────────────────────────────┐
│ dt [module!]type [address] [options]    │
│                                         │
│ Parameters:                             │
│ • module  = DLL/EXE name (optional)     │
│ • type    = structure/class name        │
│ • address = memory location             │
│ • options = formatting flags            │
│                                         │
│ Examples:                               │
│ dt _PEB                - show structure │
│ dt _PEB 0x7ffdf000     - dump at addr  │
│ dt ntdll!_TEB @$teb    - specific module│
└─────────────────────────────────────────┘

Windows System Structures

Process Environment Block (PEB)

PEB Structure Analysis:
┌─────────────────────────────────────────┐
│ 0:000> dt _PEB 0x7ffdf000               │
│ ntdll!_PEB                              │
│    +0x000 InheritedAddressSpace : 0y0   │
│    +0x000 ReadImageFileExecOptions : 0y0│
│    +0x000 BeingDebugged         : 0y1   │
│    +0x000 BitField             : 0y00001│
│    +0x000 SpareBits            : 0y00000│
│    +0x004 Mutant               : 0xffffffff
│    +0x008 ImageBaseAddress     : 0x00400000
│    +0x00c Ldr                  : 0x77f42000
│    +0x010 ProcessParameters    : 0x00020000
│    +0x014 SubSystemData        : (null)  │
│    +0x018 ProcessHeap          : 0x00080000
│    ... (additional fields)              │
└─────────────────────────────────────────┘

9. Writing to Memory

Memory Modification Overview

WinDbg provides powerful capabilities for modifying memory contents during debugging sessions. This feature is essential for testing hypotheses, fixing values temporarily, and understanding program behavior under different conditions.

Basic Memory Write Commands

The Edit (e) Command Family

Edit Command Syntax:
┌─────────────────────────────────────────┐
│ e[type] address value [value2] [...]    │
│                                         │
│ Type specifiers:                        │
│ • eb = edit bytes                       │
│ • ew = edit words (16-bit)              │
│ • ed = edit dwords (32-bit)             │
│ • eq = edit qwords (64-bit)             │
│ • ea = edit ASCII string                │
│ • eu = edit Unicode string              │
│                                         │
│ Examples:                               │
│ ed 0x401000 12345678                    │
│ ea 0x402000 "Hello World"               │
│ eb 0x403000 90 90 90                    │
└─────────────────────────────────────────┘

Byte-Level Modifications

Single and Multiple Byte Edits

Byte Editing Examples:
┌─────────────────────────────────────────┐
│ Single byte modification:               │
│ 0:000> eb 0x401000 90                   │
│                                         │
│ Multiple bytes:                         │
│ 0:000> eb 0x401000 90 90 90 90          │
│                                         │
│ Before:                                 │
│ 0:000> db 0x401000 L4                   │
│ 00401000  55 8b ec 83                   │
│                                         │
│ After:                                  │
│ 0:000> db 0x401000 L4                   │
│ 00401000  90 90 90 90                   │
│                                         │
│ NOP instruction (0x90) inserted        │
└─────────────────────────────────────────┘

10. Searching the Memory Space

Memory Search Overview

Memory searching is a critical debugging capability that allows you to locate specific patterns, values, or structures within the target process memory space. WinDbg provides comprehensive search functionality through the s command family.

Basic Search Commands

Search Command Syntax

Search Command Format:
┌─────────────────────────────────────────┐
│ s[type] range pattern                   │
│                                         │
│ Type specifiers:                        │
│ • -b = byte search                      │
│ • -w = word search (16-bit)             │
│ • -d = dword search (32-bit)            │
│ • -q = qword search (64-bit)            │
│ • -a = ASCII string search              │
│ • -u = Unicode string search            │
│                                         │
│ Range formats:                          │
│ • start_addr end_addr                   │
│ • start_addr L length                   │
│ • module_name                           │
└─────────────────────────────────────────┘

String Searching

ASCII String Search

ASCII String Search Examples:
┌─────────────────────────────────────────┐
│ Search for exact string:                │
│ 0:000> s -a 0x400000 L100000 "error"    │
│ 00402104  "error message"               │
│ 00403567  "file error"                  │
│                                         │
│ Case-sensitive search:                  │
│ 0:000> s -a 0x400000 L100000 "Error"    │
│ 00402890  "Error: File not found"       │
│                                         │
│ Search in specific module:              │
│ 0:000> s -a myapp "password"            │
└─────────────────────────────────────────┘

11. Inspecting and Editing CPU Registers in WinDbg

Register Overview

CPU registers are high-speed storage locations directly accessible to the processor. They are the fastest form of memory available and are essential for all CPU operations. Understanding registers is crucial for low-level programming, debugging, and performance optimization.

Register Display Commands

Basic Register Display

Register Display Commands:
┌─────────────────────────────────────────┐
│ Command │ Purpose                       │
├─────────────────────────────────────────┤
│ r       │ Display all general registers │
│ r eax   │ Display specific register     │
│ rf      │ Display floating point regs   │
│ rm      │ Display MMX registers         │
│ rx      │ Display SSE registers         │
│ rM      │ Display all register types    │
└─────────────────────────────────────────┘

General Purpose Register Display

General Register Output:
┌─────────────────────────────────────────┐
│ 0:000> r                                │
│ eax=00000000 ebx=7ffdf000 ecx=00000001  │
│ edx=00322a70 esi=00000000 edi=00000000  │
│ eip=00401030 esp=0012ff80 ebp=0012ff94  │
│ iopl=0       nv up ei pl zr na pe nc    │
│ cs=001b  ss=0023  ds=0023  es=0023      │
│ fs=0053  gs=002b                        │
│                                         │
│ Register breakdown:                     │
│ • General Purpose: EAX, EBX, ECX, EDX   │
│ • Index Registers: ESI, EDI             │
│ • Stack Registers: ESP, EBP             │
│ • Instruction Pointer: EIP              │
│ • Flags Register: EFLAGS (decoded)      │
│ • Segment Registers: CS, DS, ES, etc.   │
└─────────────────────────────────────────┘

Register Modification

Changing Register Values

Register Modification Examples:
┌─────────────────────────────────────────┐
│ Set specific register:                  │
│ 0:000> r eax = 0x12345678               │
│ 0:000> r                                │
│ eax=12345678 ebx=7ffdf000 ...           │
│                                         │
│ Set using expressions:                  │
│ 0:000> r eax = @ebx + 100               │
│ 0:000> r ecx = poi(@esp)                │
│ 0:000> r edx = @eax * 2                 │
│                                         │
│ Set multiple registers:                 │
│ 0:000> r eax=0; r ebx=1; r ecx=2        │
│                                         │
│ Set flags:                              │
│ 0:000> r zf = 1                         │
│ 0:000> r cf = 0                         │
└─────────────────────────────────────────┘

12. Controlling the Program Execution in WinDbg

Execution Control Overview

Program execution control is fundamental to effective debugging. WinDbg provides comprehensive commands for starting, stopping, and stepping through program execution with precise control over the debugging target.

Basic Execution Commands

Primary Control Commands

Execution Control Commands:
┌─────────────────────────────────────────┐
│ Command │ Key │ Action                   │
├─────────────────────────────────────────┤
│ g       │ F5  │ Go (continue execution)  │
│ p       │ F10 │ Step over               │
│ t       │ F11 │ Step into (trace)       │
│ gu      │     │ Go up (step out)        │
│ pc      │     │ Step to next call       │
│ tc      │     │ Trace to next call      │
│ pt      │     │ Step to next return     │
│ tt      │     │ Trace to next return    │
│ pa      │     │ Step to address         │
│ ta      │     │ Trace to address        │
└─────────────────────────────────────────┘

Continue Execution (Go Commands)

Basic Go Command

Go Command Variations:
┌─────────────────────────────────────────┐
│ Simple continue:                        │
│ 0:000> g                                │
│        ; Continue until breakpoint      │
│                                         │
│ Go to specific address:                 │
│ 0:000> g 0x401234                       │
│        ; Continue until EIP = 401234    │
│                                         │
│ Go with temporary breakpoint:           │
│ 0:000> g @eip+0x10                      │
│        ; Continue for 16 bytes          │
│                                         │
│ Go until return:                        │
│ 0:000> g @$ra                           │
│        ; Continue until function returns│
└─────────────────────────────────────────┘

13. Software Breakpoints

Breakpoint Fundamentals

Software breakpoints are the most common debugging tool, allowing you to pause program execution at specific locations. WinDbg implements software breakpoints by temporarily replacing instructions with interrupt instructions (INT 3, opcode 0xCC).

Basic Breakpoint Commands

Core Breakpoint Operations

Breakpoint Command Overview:
┌─────────────────────────────────────────┐
│ Command │ Purpose                       │
├─────────────────────────────────────────┤
│ bp      │ Set breakpoint                │
│ bu      │ Set unresolved breakpoint     │
│ bl      │ List breakpoints              │
│ bc      │ Clear breakpoint              │
│ bd      │ Disable breakpoint            │
│ be      │ Enable breakpoint             │
│ br      │ Rename breakpoint             │
└─────────────────────────────────────────┘

Setting Breakpoints

Address-Based Breakpoints

Address Breakpoint Examples:
┌─────────────────────────────────────────┐
│ Set by absolute address:                │
│ 0:000> bp 0x401234                      │
│                                         │
│ Set by module + offset:                 │
│ 0:000> bp myapp+0x1234                  │
│                                         │
│ Set by symbol name:                     │
│ 0:000> bp myapp!main                    │
│ 0:000> bp kernel32!CreateFileA          │
│                                         │
│ Set by symbol + offset:                 │
│ 0:000> bp myapp!ProcessData+0x23        │
│                                         │
│ Set by register expression:             │
│ 0:000> bp @eip+0x10                     │
└─────────────────────────────────────────┘

14. Unresolved Function Breakpoint

Understanding Unresolved Breakpoints

Unresolved breakpoints are a special type of breakpoint that can be set on functions or symbols that haven't been loaded yet. They become active when the target module is loaded, making them essential for debugging DLL loading scenarios and delayed-load libraries.

The bu Command

Basic Unresolved Breakpoint Syntax

bu Command Syntax:
┌─────────────────────────────────────────┐
│ bu [Options] Address [Commands]         │
│                                         │
│ Key differences from bp:                │
│ • Works with unloaded modules           │
│ • Resolves when symbols become available│
│ • Useful for DLL entry points          │
│ • Handles delayed loading               │
│                                         │
│ Common usage:                           │
│ bu module!function                      │
│ bu /1 module!function                   │
│ bu module!function "commands"           │
└─────────────────────────────────────────┘

Setting Unresolved Breakpoints

DLL Function Breakpoints

DLL Breakpoint Examples:
┌─────────────────────────────────────────┐
│ Set breakpoint on DLL function:         │
│ 0:000> bu user32!MessageBoxA            │
│                                         │
│ Check breakpoint status:                │
│ 0:000> bl                               │
│   0 e u             0001 (0001)  0:**** user32!MessageBoxA
│                     ^                   │
│                     └─ 'u' = unresolved │
│                                         │
│ After DLL loads:                        │
│ ModLoad: 77d40000 77dd0000   user32.dll │
│ 0:000> bl                               │
│   0 e 77d4a567     0001 (0001)  0:**** user32!MessageBoxA
│                     ^                   │
│                     └─ Now resolved     │
└─────────────────────────────────────────┘

15. Breakpoint-Based Actions

Advanced Breakpoint Actions

Breakpoint actions extend the functionality of breakpoints beyond simple execution stopping. They allow for automated data collection, conditional execution, logging, and complex debugging workflows without manual intervention.

Action Command Syntax

Basic Action Structure

Breakpoint Action Syntax:
┌─────────────────────────────────────────┐
│ bp address "action_commands"            │
│                                         │
│ Action Command Categories:              │
│ • Display commands (r, dd, da, dt)      │
│ • Control flow (g, gc, p, t)            │
│ • Conditional logic (.if, .while)       │
│ • Logging (.echo, .printf)              │
│ • File operations (.logopen, .writemem) │
│ • Script execution ($<, .script)       │
│                                         │
│ Command separators:                     │
│ • ; = sequential execution              │
│ • {} = command grouping                 │
└─────────────────────────────────────────┘

Data Collection Actions

Register and Memory Logging

Data Collection Examples:
┌─────────────────────────────────────────┐
│ Log register state:                     │
│ 0:000> bp myapp!CriticalFunc "r; g"     │
│                                         │
│ Log specific registers:                 │
│ 0:000> bp myapp!ProcessData "r eax, ebx, ecx; g"
│                                         │
│ Log memory contents:                    │
│ 0:000> bp myapp!ProcessBuffer "dd poi(@esp+4) L8; g"
│        ; Dump buffer parameter          │
│                                         │
│ Log call parameters:                    │
│ 0:000> bp myapp!FileOperation "dd @esp L4; da poi(@esp+4); g"
│        ; Show stack and filename        │
│                                         │
│ Log structure contents:                 │
│ 0:000> bp myapp!ProcessStruct "dt MyStruct poi(@esp+4); g"
└─────────────────────────────────────────┘

16. Hardware Breakpoints

Hardware Breakpoint Fundamentals

Hardware breakpoints utilize the CPU's built-in debugging facilities rather than modifying program code. They are implemented using the processor's debug registers and offer unique capabilities not available with software breakpoints.

Hardware vs Software Breakpoints

Comparison Table

Feature Software Breakpoints Hardware Breakpoints
Implementation Replaces instruction with INT 3 Uses CPU debug registers
Quantity Limit Unlimited (memory limited) 4 breakpoints maximum
Detection Can be detected by program Invisible to target program
Memory Access Execution only Read, write, execute access
Code Modification Modifies target code No code modification
Performance Minimal overhead No runtime overhead

Hardware Breakpoint Commands

Basic ba Command Syntax

ba Command Syntax:
┌─────────────────────────────────────────┐
│ ba access size address [options]        │
│                                         │
│ Access types:                           │
│ • e = execute (instruction fetch)       │
│ • r = read (memory read)                │
│ • w = write (memory write)              │
│ • i = I/O access (port access)          │
│                                         │
│ Size specifiers:                        │
│ • 1 = 1 byte                            │
│ • 2 = 2 bytes (word)                    │
│ • 4 = 4 bytes (dword)                   │
│ • 8 = 8 bytes (qword, x64 only)         │
│                                         │
│ Examples:                               │
│ ba w4 0x401000     ; Write 4 bytes      │
│ ba r1 @eax         ; Read 1 byte at EAX │
│ ba e1 0x401234     ; Execute at address │
└─────────────────────────────────────────┘

Memory Access Breakpoints

Write Access Monitoring

Write Access Examples:
┌─────────────────────────────────────────┐
│ Monitor variable modification:          │
│ 0:000> ba w4 global_variable            │
│                                         │
│ When variable is written:               │
│ Hardware breakpoint 0 hit              │
│ 00401234 mov [global_variable], eax     │
│ 0:000> r eax                            │
│ eax=12345678                            │ ← New value
│                                         │
│ Monitor buffer overflow:                │
│ 0:000> ba w1 buffer_end                 │
│                                         │
│ Monitor structure field:                │
│ 0:000> ba w4 mystruct+0x8               │ ← Specific field
└─────────────────────────────────────────┘

17. Stepping Through the Code

Single-Step Debugging Overview

Single-step debugging allows precise execution control by executing one instruction at a time. This granular control is essential for understanding program flow, analyzing algorithms, and tracking down subtle bugs.

Basic Stepping Commands

Core Stepping Operations

Stepping Command Reference:
┌─────────────────────────────────────────┐
│ Command │ Key  │ Action                 │
├─────────────────────────────────────────┤
│ t       │ F11  │ Trace into            │
│ p       │ F10  │ Step over             │
│ gu      │ -    │ Go up (step out)      │
│ tc      │ -    │ Trace to call         │
│ pc      │ -    │ Step to call          │
│ tt      │ -    │ Trace to return       │
│ pt      │ -    │ Step to return        │
│ ta      │ -    │ Trace to address      │
│ pa      │ -    │ Step to address       │
└─────────────────────────────────────────┘

Trace Into (t command)

Single Instruction Execution

Trace Into Examples:
┌─────────────────────────────────────────┐
│ Current instruction:                    │
│ 0:000> u @eip L3                        │
│ 00401030 55          push   ebp         │ ← Current (EIP)
│ 00401031 8bec        mov    ebp,esp     │
│ 00401033 83ec18      sub    esp,18h     │
│                                         │
│ Execute one instruction:                │
│ 0:000> t                                │
│ 0:000> u @eip L3                        │
│ 00401031 8bec        mov    ebp,esp     │ ← Now here
│ 00401033 83ec18      sub    esp,18h     │
│ 00401036 c745f80000  mov    dword ptr[...]│
│                                         │
│ Register state after step:              │
│ 0:000> r esp, ebp                       │
│ esp=0012ff7c ebp=0012ff80               │ ← EBP saved
└─────────────────────────────────────────┘

Step Over (p command)

Skipping Function Calls

Step Over Examples:
┌─────────────────────────────────────────┐
│ Before function call:                   │
│ 0:000> u @eip L3                        │
│ 00401050 68001040    push   offset str  │
│ 00401055 e8a6ffffff  call   00401000    │ ← Function call
│ 0040105a 83c404      add    esp,4       │
│                                         │
│ Step over the call:                     │
│ 0:000> p                                │ ← Execute entire function
│ 0:000> u @eip L3                        │
│ 0040105a 83c404      add    esp,4       │ ← After function
│ 0040105d 85c0        test   eax,eax     │
│ 0040105f 7405        je     00401066    │
│                                         │
│ Function executed but not traced        │
│ 0:000> r eax                            │
│ eax=00000001                            │ ← Function return value
└─────────────────────────────────────────┘

18. Additional WinDbg Features

Extended WinDbg Capabilities

Beyond basic debugging operations, WinDbg offers numerous advanced features that enhance debugging productivity and provide specialized analysis capabilities.

Extension Commands Overview

Built-in Extensions

WinDbg Extension Categories:
┌─────────────────────────────────────────┐
│ Heap Analysis Extensions:               │
│ • !heap - Heap analysis and validation │
│ • !gflag - Global flags manipulation   │
│ • !locks - Lock analysis               │
│                                         │
│ Process/Thread Extensions:              │
│ • !process - Process information       │
│ • !thread - Thread details             │
│ • !handle - Handle enumeration          │
│                                         │
│ Memory Extensions:                      │
│ • !address - Virtual memory info       │
│ • !vprot - Memory protection           │
│ • !pool - Pool memory analysis         │
│                                         │
│ Analysis Extensions:                    │
│ • !analyze - Automated crash analysis  │
│ • !stack - Stack analysis              │
│ • !uniqstack - Unique stack traces     │
└─────────────────────────────────────────┘

Heap Analysis Features

Heap Debugging Commands

Heap Analysis Examples:
┌─────────────────────────────────────────┐
│ Show heap summary:                      │
│ 0:000> !heap -s                         │
│ Heap at 00080000                        │
│ Group-by: TOTSIZE max-display: 20        │
│     size     #blocks     total     (%)  │
│     4c0 -          1       4c0  ( 6.05) │
│     2f8 -          2       5f0  ( 7.71) │
│     50 -          32      1000  (20.25) │
│                                         │
│ Detailed heap analysis:                 │
│ 0:000> !heap -a 0x00080000             │
│                                         │
│ Find heap corruption:                   │
│ 0:000> !heap -x                        │
│                                         │
│ Heap entry details:                     │
│ 0:000> !heap -p -a 0x00081234          │
│     address 00081234 found in         │
│     _HEAP @ 80000                      │
│         HEAP_ENTRY Size Prev Flags    UserPtr UserSize
│         00081228   0008 0000   [00]   00081234    00000034
└─────────────────────────────────────────┘

19. Listing Modules and Symbols in WinDbg

Module Information Overview

Understanding loaded modules and their symbols is crucial for effective debugging. WinDbg provides comprehensive commands for examining module layouts, symbol status, and debugging information.

Basic Module Commands

Core Module Listing Commands

Module Command Reference:
┌─────────────────────────────────────────┐
│ Command │ Purpose                       │
├─────────────────────────────────────────┤
│ lm      │ List modules (basic)          │
│ lmf     │ List modules (full info)      │
│ lmv     │ List modules (verbose)        │
│ lmt     │ List modules (terse)          │
│ lma     │ List modules (addresses)      │
│ lmu     │ List unloaded modules         │
│ lmi     │ Module information            │
└─────────────────────────────────────────┘

Basic Module Listing

Standard Module Display

Basic Module Listing:
┌─────────────────────────────────────────┐
│ 0:000> lm                               │
│ start    end        module name         │
│ 00400000 0040f000   myapp       (pdb symbols)  c:\symbols\myapp.pdb
│ 77f50000 77feb000   ntdll       (pdb symbols)  c:\symbols\ntdll.pdb
│ 77e60000 77f46000   kernel32    (export symbols) kernel32.dll
│ 77dd0000 77e5e000   advapi32    (no symbols)    │
│ 77c10000 77c68000   msvcrt      (deferred)      │
│ 76390000 763ad000   imm32       (deferred)      │
│                                         │
│ Symbol Status Legend:                   │
│ • (pdb symbols)    - Full debug info   │
│ • (export symbols) - Exports only      │
│ • (no symbols)     - No symbol info    │
│ • (deferred)       - Not loaded yet    │
└─────────────────────────────────────────┘

Symbol Enumeration

Symbol Search Examples

Symbol Search Examples:
┌─────────────────────────────────────────┐
│ List all symbols in module:             │
│ 0:000> x myapp!*                        │
│ 00401000 myapp!main                     │
│ 00401234 myapp!ProcessData              │
│ 00401567 myapp!CalculateSum             │
│ 00401890 myapp!PrintResult              │
│                                         │
│ Search for specific function:           │
│ 0:000> x *!CreateFile*                  │
│ 77e612a4 kernel32!CreateFileA           │
│ 77e61567 kernel32!CreateFileW           │
│ 77e61890 kernelbase!CreateFileA         │
│                                         │
│ Search with wildcards:                  │
│ 0:000> x myapp!Process*                 │
│ 00401234 myapp!ProcessData              │
│ 00401567 myapp!ProcessFile              │
│ 00401890 myapp!ProcessMessage           │
└─────────────────────────────────────────┘

20. Using WinDbg as a Calculator

Calculator Functionality Overview

WinDbg includes a powerful expression evaluator that can perform complex calculations, making it an excellent debugging calculator for address arithmetic, size calculations, and data analysis.

Basic Calculator Operations

Expression Evaluation Syntax

Calculator Command Syntax:
┌─────────────────────────────────────────┐
│ ? expression        - Evaluate expression│
│ ?? expression       - C++ expression   │
│ .expr               - Expression options│
│                                         │
│ Basic operators:                        │
│ + - * /            - Arithmetic        │
│ % mod              - Modulo            │
│ << >>              - Bit shifts        │
│ & | ^              - Bitwise ops       │
│ && ||              - Logical ops       │
│ == != < > <= >=    - Comparisons       │
│                                         │
│ Number formats:                         │
│ 0x1234, 1234h      - Hexadecimal      │
│ 1234, 1234n        - Decimal          │
│ 1234y              - Binary           │
│ 1234t              - Octal            │
└─────────────────────────────────────────┘

Basic Arithmetic Operations

Fundamental Calculations

Basic Arithmetic Examples:
┌─────────────────────────────────────────┐
│ Simple addition:                        │
│ 0:000> ? 0x1000 + 0x234                 │
│ Evaluate expression: 4660 = 00001234    │
│                                         │
│ Mixed number formats:                   │
│ 0:000> ? 100 + 0x64                     │
│ Evaluate expression: 200 = 000000c8     │
│                                         │
│ Address arithmetic:                     │
│ 0:000> ? @eip + 0x10                    │
│ Evaluate expression: 4198448 = 00401030 │
│                                         │
│ Size calculations:                      │
│ 0:000> ? 1024 * 1024                    │
│ Evaluate expression: 1048576 = 00100000 │
│                                         │
│ Percentage calculations:                │
│ 0:000> ? (50 * 100) / 200               │
│ Evaluate expression: 25 = 00000019      │
└─────────────────────────────────────────┘

21. Data Output Format

Output Formatting Overview

WinDbg provides extensive control over how data is displayed, allowing customization of numeric formats, string representations, and structured data presentation. Understanding these formatting options is crucial for effective data analysis.

Basic Format Specifiers

Numeric Display Formats

Numeric Format Specifiers:
┌─────────────────────────────────────────┐
│ Format │ Description        │ Example   │
├─────────────────────────────────────────┤
│   %d   │ Signed decimal     │ -123      │
│   %u   │ Unsigned decimal   │ 4294967173│
│   %x   │ Hexadecimal (lower)│ 7b        │
│   %X   │ Hexadecimal (upper)│ 7B        │
│   %o   │ Octal              │ 173       │
│   %c   │ Character          │ A         │
│   %s   │ String             │ "hello"   │
│   %p   │ Pointer            │ 0x401000  │
│   %f   │ Float              │ 3.14159   │
│   %e   │ Scientific notation│ 3.14e+00  │
│   %g   │ Compact float      │ 3.14159   │
└─────────────────────────────────────────┘