WinDbg Kernel

Kernel exploration

CheatSheet

Symbols and types

Command
Usage
Examples
Description

lm lm <PATTERN>

lm nt*

Displays all or the specified loaded modules.

x <MODULE>!* x <MODULE>!<PATTERN>

x nt!* x nt!*process*

Displays the symbols in the specified module.

ln <ADDRESS>

ln fffff80705d4c9d4

Displays the symbol(s) at or near the specified address.

dt <STRUCT> dt nt!*<PATTERN>*

dt nt!_EPROCESS

Displays information about a local variable, global variable or data type.

.printf [<OPTIONS>] <FORMAT_STRING> <ARGUMENT | ARGUMENT_LIST>

.printf "%y", <ADDRESS> displays the eventual symbol associated with the given address.

C printf-like function.

Memory exploration

Command
Usage
Examples
Description

d*s <ADDRESS | ADDRESS_RANGE>

dqs fffff80705d1a410 dqs fffff80705d1a410 fffff80705d1a418

Displays the contents of memory in the given range. The dds command displays DWORD (4 byte) values. The dqs command displays QWORD (8 byte) values. The dps command displays pointer-sized values (4 byte or 8 byte depending on the system architecture) values.

ds <ADDRESS> dS <ADDRESS>

Display a STRING / ANSI_STRING (ds) or UNICODE_STRING (dS) strings.

u <ADDRESS | ADDRESS_RANGE>

u 0xfffff8015be478d0 u nt!NtOpenProcessToken

Displays an assembly translation of the code at the specified memory address or range.

u <ADDRESS>

uf fffff80705685060 uf nt!NtOpenProcessTokenEx

Displays an assembly translation of the function at the specified memory address.

!address <ADDRESS>

!address fffff80705d1a410 !address nt!NtOpenProcessTokenEx

Displays information on the module to which the specified address belong (module name, path and base start / end ADDRESSs).

!process [/s <SESSION>] [/m <MODULE>] <0 | PROCESS_ADDRESS | PROCESS_PID> <INFORMATION_LEVEL_FLAG>]

!process 0 0 display all the process of the system, with a minimum level of information.

Displays information about all or the specified processes, including the EPROCESS block.

!thread [-p] [-t] <ADDRESS>

!thread 0xffffcb088f0d6840 display all the process of the system, with a minimum level of information.

Displays summary information about a thread, including the ETHREAD block.

!acl <HEXA_ADDRESS>

Displays the contents of an Access Control List (ACL).

poi(<ADDRESS>)

Dereference pointer

Display Debugger Object Model Expression (dx)

dx <CPP_EXPRESSION>

// Displays information about the specified variable (using the variable address directly or the variable eventual symbol).
dx (<TYPE> *) <ADDRESS>
dx (<TYPE> *) &<VARIABLE>
// If the variable is a pointer to an object.
dx (<TYPE> **) &<VARIABLE>

// Examples:
dx -r1 (ntkrnlmp!_EPROCESS *) 0xffffa10d10c37080
dx (nt!_EPROCESS *) &nt!PsIdleProcess
dx *(nt!_OBJECT_TYPE **) &nt!AlpcPortObjectType

// Displays the first debugging session processes as a grid view.
dx -g Debugger.Sessions.First().Processes

// Displays the first debugging session processes as a grid view.
dx -g Debugger.Sessions.First().Processes

// Displays information about the process PID in the first debugging session.
dx Debugger.Sessions.First().Processes[<DECIMAL_PID>]

// Displays the threads of the first or specified process in the first debugging session processes as a grid view.
dx -g Debugger.Sessions.First().Processes.First().Threads
dx -g Debugger.Sessions.First().Processes[<DECIMAL_PID>].Threads

// Displays the loaded module of the first or specified process in the first debugging session processes as a grid view.
dx -g Debugger.Sessions.First().Processes.First().Modules
dx -g Debugger.Sessions.First().Processes[<DECIMAL_PID>].Modules

// Retrieve the first or specified thread of the specified process in the first debugging session.
dx -r1 Debugger.Sessions.First().Processes[<DECIMAL_PID>].Threads.First()
dx -r1 Debugger.Sessions.First().Processes[<DECIMAL_PID>].Threads[<DECIMAL_THREAD_ID>]

// Stores the specified process as a variable, allowing later reference to the process properties.
dx @$process = Debugger.Sessions.First().Processes[<DECIMAL_PID>]
dx @$process->Name
dx @$process->Threads
// Get process Ldr.
dx -r2 (_PEB_LDR_DATA *) @$process.Environment.EnvironmentBlock.Ldr

// Stores the specified process handles in a variable and display all or selected information about each handle.
dx @$processHandles = Debugger.Sessions.First().Processes[<DECIMAL_PID>].Io.Handles
// Display all available information.
dx -g @$processHandles
// Displays selected information.
dx -g @$processHandles->Select(o => new { Handle = o->Handle, Type = o->Type, ObjectName = o->ObjectName})
// Filters handles of type "Directory" and displays selected information.
dx -g @$processHandles->Where(o => (o.Type == "Directory"))->Select(o => new { Handle = o->Handle, Type = o->Type, ObjectName = o->ObjectName})

// Get process Ldr first entry (in memory order).
dx -r1 @$process.Environment.EnvironmentBlock.Ldr->InMemoryOrderModuleList.Flink

Execution control flow

Command
Usage
Examples
Description

Userland process crashdump / dump analysis

Command
Description

!analyze -v

Provides an overview of the dump: process name, error code, stack trace, etc. More useful for crashdump, limited use for voluntarily taken process dump.

!peb

Parses the Process Environment Block (PEB) of the process, notably retrieving: the process image file and command line, current directory, loaded DLLs, windows title, environment variables.

lm f

Lists the loaded DLLs, with the possibility to click on any DLL to retrieve more information on a specific DLL: size, file / product version, metadata, etc.

lmDv

Prints verbose information (as mentioned on lm f) for all loaded DLLs.

!address

Lists the address pages and associated information: - Page type (MEM_IMAGE, MEM_MAPPED, MEM_PRIVATE) - Page state (MEM_COMMIT, MEM_RESERVE, MEM_FREE) - Page protection (PAGE_READWRITE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, etc.) - Eventual associated file on disk Can be useful to detect a number of suspicious indicators / anomalies: - In memory PE (MZ header) not backed by an on-disk file. - Suspicious PAGE_EXECUTE_READWRITE protection. - Modification of modules usually patched to bypass security mechanism (such as the patching of the amsi.dll to bypass AMSI). Indeed a modification of a module memory will result in the page to change from MEM_IMAGE to MEM_PRIVATE.

!address -f:<FILTER> Examples: !address -f:PAGE_EXECUTE_READWRITE !address -f:MEM_PRIVATE,MEM_COMMIT

Filters memory pages based on the specified filter. All filters in the list are AND-combined.


References

  • Microsoft Windows Debugging Tools official documentation

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/

  • "Modern Debugging with WinDbg Preview" DEFCON 27 workshop by hugsy and 0vercl0k"

    https://github.com/hugsy/defcon_27_windbg_workshop

  • "WinDbg — the Fun Way: Part 1 / 2" by Yarden Shafir

    https://medium.com/@yardenshafir2/windbg-the-fun-way-part-1-2e4978791f9b

    https://medium.com/@yardenshafir2/windbg-the-fun-way-part-2-7a904cba5435

Last updated