Skip to main content

Windbg useful commands

·5 mins

All windbg commands here #

Link to windgb manual

Add symbol #

Go to File -> Symbol Search Path then add the path below

srv*c:\symbols*https://msdl.microsoft.com/download/symbols 

Load the symbols #

Note.: Attach to a process then run the command to load the symbols

.reload /f 

Run the program #

g

Clear windbg screen #

.cls

Unassemble MNEMONIC instructions #

The u command accepts memory address, range of memory address or symbol names. We can use “ub” command to disassemble by counting backwards.

u module!function 

Read data from memory #

db esp 
db 069fdcc 
db kernel32!WriteFile 
dw 069fdcc 
dd 069fdcc 
dq 069fdcc 
dW  KERNELBASE+0X40 // show ascii value on the right 
dc KERNELBASE // show ascii character 

Control length to be displayed #

The default is 0x80 bytes. The L parameter.

dd esp L4
db esp L10

Display contents of address #

sds (double word), dqs (Qword), dps (Pointer sized 4 byte or 8 byte depending on computer archtecture).

dds esp L10 
dds esp-10 L10 

Derefence memory using poi #

dd poi(esp) 

Dumping Structures from Memory #

Display type the command is dt, the $teb is a pseudo register that provides address of the TEB

dt ntdll!_TEB 
dt ntdll!_TEB @$teb ThreadLocalStoragePointer 

Display nested Structures from Memory #

The -r will display nested structures, the $teb is the pseudo register that provides the address of the TEB

dt -r ntdll!_TEB @$teb

Display Exeption Registration Record #

The !teb get the ExceptionList value and use with the dt command as showing below. Another option is !exchain command

!teb
dt _EXCEPTION_REGISTRATION_RECORD 0014f4a4

Calculate size of structure #

?? sizeof(ntdll!_TEB)

Writing a value to Memory #

We can use the edit command followed by size (similar to the display command).

ed esp 41414141      // we are writing a dword to esp ( 4 bytes ) 
ed esp 41414141 
ea esp "Hello"   // we can modify ascii values using ea, we write Hello to esp 
eu esp  Address "String"  // we can modify to unicode value using eu, we write to esp. 

Searching the memory space #

The -d meanins dword memory address, 0 means beginning of address the L? Length to search, we enter 80000000 to search and followed by value 41414141. we can search for ascii string using the -a flag as well.

 s -d 0 L?80000000 41414141 
 s -a 0 L?80000000 "This program cannot be run in DOS mode" // this earch for the ascii string via -a flag 

Inspecting and Editing CPU Register in WinDbg #

We can use “r” command to display all register or individual register. We can use “r” to modify register values

r   // list all register  
r ecx  // list only ecx 
r ecx=41414141   // This edit ecx with value of 41414141 

Software BreakPoints #

bp kernel32!WriteFile 
bl    // list the breakpoints 
g  // let execution run 

Disable/Enable BreakPoints #

bd <number> // Disable Breakpoints, get the number with bl 
be <number>  // Enable Breakpoints, get the number with bl 

Clear/Delete BreakPoints #

bc <number>  // clear specific breakpoints
bc * to clear all breakpoints 

Unresolved Function Breakpoints #

Function not loaded in process memory and it has not been resolved.

bu ole32!WriteStringStream 

Breakpoint-Based Actions #

The command below break and print number of bytes from WriteFile function, %p display given value as a pointer.

bp kernel32!WriteFile ".printf \"The number of bytes written is: %p\", poi(esp + 0x0C); .echo;g" 

Conditional Breakpoints Actions #

Command below breaks if number of bytes written is 4 otherwise continue execution.

bp kernel32!WriteFile ".if (poi(esp + 0x0C) != 4) {gc} .else { .printf \"The number of bytes written is 4\"; .echo;}" 

Hardware Breakpoints #

Hardware breakpoints are performed on processor level in the register, x86/x64 have only 4 registers reserved for hardware breakpoints.
The access can be: e (execute), r (read), w (write)
Example: ba <size_bytes_in_memory> <memory_address>

ba e 1 kernel32!WriteFile 
ba w 2 00c56330    // we are set hardware breakpoint write access of first 2 bytes on memory address 00c56330   

Stepping through the code #

We can use p (step over the calls) and t (step into the calls) and pt (go end of the function) and ph ( execute code until branching instruction is reached),
This includes conditional or unconditional branches, functions calls and return instructions.

The pa <adddress> (step to Address) executes until reaches the specified memory address. 

Listing Modules and Symbols #

We can use lm command do display loaded modules start/end addresses. The deferred for specific modules means no symbols are loaded and .reaload /f can be used to load the symbols.

lm 
lm f 

We can also filter modules with the command below

lm m kernel*

We can learn more about the symbols using the x command, example

x kernelbase!CreateProc* 

Windbg as a calculator #

Mathematical evaluation is performed using the ? Command. The input is assumed to be in hex format.

? 77269bc0 - 77231430  // substraction of memory address 
? 77269bc0 >> 18  // shifting a address by 18 bytes 

Data Output Format #

by default windbg display result in hexdecimal format. We can conver hex to decimal with 0n prefix or binary to hex with 0xy prefix

? 0n41414141  // converts 41414141 from hex to decimal format 
? 0y1110100110111   // convert binary value to hex and decimal

The .formats allow us to convert to all representation at once

.formats 41414141  // converts 41414141 to all formats 

Pseudo Registers #

windbg has a series of pseudo registers, there are variables pre-defined.

Example of pseudo registers are $teb contains address of TEB, $t0…$t19 used for mathematical calculation

When using pseudo registers or registers its recommend to prefix them @ character, example @$teb this tells windbg to treat the content as a register or pseudo registers. It speeds the evaluation process because windbg won’t try to resolve it as symbols first.

r @$t0 = (41414141 - 414141) * 0n10  // store the result into pseudo register 
r @$t0  // display the result 
? @$t0 >> 8  // right shift the result to 8 bits 

Check memory permission #

We can check memory permission under Protect field.

!vprot esp 
!vprot eip 
!vprot 00d13000

List stack frame #

Using the k command to list the stack frame

k
k2
k3
k4