WinDbg uses a command-line interface for most of its functionality. We will cover the more important commands here. You can browse the complete list of commands in the WinDbg Help menu.
WinDbg’s memory window supports memory browsing directly from the command line. The
d
command is used to read locations in memory such as program
data or the stack, with the following basic syntax:
dx addressToRead
where x
is one of several options for
how the data will be displayed. Table 10-1 shows the most common ways
that data can be displayed.
Table 10-1. WinDbg Reading Options
Option | Description |
---|---|
| Reads from memory and displays it as ASCII text |
| Reads from memory and displays it as Unicode text |
| Reads from memory and displays it as 32-bit double words |
For example, to display a string at offset 0x401020, you would use the command da 0x401020
.
The e
command is used in the same way to change memory
values. It uses the following syntax:
ex addressToWrite dataToWrite
The x
values are the same values used
by the d
x
commands. You’ll find many additional options documented in the help files.
You can perform operations on memory and registers directly from the command line using simple
arithmetic operations, such as addition (+
), subtraction
(-
), multiplication (*
), and
division (/
). Command-line options are useful as shortcuts and
when trying to create expressions for conditional breakpoints.
The dwo
command is used to dereference a 32-bit pointer and
see the value at that location. For example, if you are at a breakpoint for a function and the first
argument is a wide character string, you can view the string with this command:
du dwo (esp+4)
The esp+4
is the location of the argument. The dwo
operator identifies the location of the pointer for the string, and
du
tells WinDbg to display the wide character string at that
location.
The bp
command is used to set basic breakpoints in WinDbg.
You can also specify commands to be run automatically when a breakpoint is hit prior to control
being passed to the user. This is used with the go (g
) command,
so that the breakpoint performs an action and then continues without waiting for the user. For
example, the following command will print out the second argument every time the GetProcAddress
function is called without actually stopping the
program’s execution.
bp GetProcAddress "da dwo(esp+8); g"
The example will print the function name being requested for every call to GetProcAddress
. This is a useful feature because the breakpoint will be
executed much faster than if it returned control to the user and waited for the user to issue the
command. The command string can become fairly sophisticated with support for conditional statements,
such as .if
statements and .while
loops. WinDbg supports scripts that use these commands.
Commands sometimes attempt to access invalid memory locations. For example,
the second argument to GetProcAddress
can be
either a string or an ordinal number. If the argument is an ordinal number, WinDbg will try to
dereference an invalid memory location. Luckily, it won’t crash and will simply print
????
as the value at that
address.
WinDbg does not have a feature similar to OllyDbg’s memory map that lays out all the
memory segments and loaded modules. Alternatively, WinDbg’s lm
command will list all the modules loaded into a process, including the executables and
DLLs in user space and the kernel drivers in kernel mode. The starting address and ending address
for each module are listed as well.