14 Mar 2021

WinDBG Notes

// This post will be updated regularily. Don’t rely on it, i’m learning.

Working through a new course that encourages WinDBG over other debuggers. I love WinDBG, but i find i forget even the basics because it is so long between drinks.

The unassemble commands:

If you do u on it’s own the debugger will assume you want to unassemble from EIP. If you have a memory address in mind u {address}. If that’s not what you want, and you have a function in mind use:

u Kernel32!GetCurrentThread

The display commands:

If it’s bytes you want:

db esp
db Kernel32!WriteFile

80 bytes is the default amount you’ll get if you don’t specify.

Substitute in w to display words.

For ASCII representations use the dW or dc.

For unicode: du

As an example of dealing with pointers - consider that you are interested in a parameter on the stack esp+4 but you know that it is a pointer. It’d be tempting to do:

0:007> dd esp+4
0:007> u 777be222

But if we already know we’re dealing with the pointer, probably because we are looking at the documents for the function, we can tell the debugger to do the steps for us. Use

u poi(ebp+4)

Breakpoint:

bp Comdlg32!GetOpenFileNameA

Structures:

We use the display type dt commands.

For example:

dt ntdll._teb

You can also pass the r parameter to be recursive since the structure might have child structures inside.

The example command will show the example structure:

0:007> dt ntdll!_teb
   +0x000 NtTib            : _NT_TIB
   +0x038 EnvironmentPointer : Ptr64 Void
   +0x040 ClientId         : _CLIENT_ID
   +0x050 ActiveRpcHandle  : Ptr64 Void
   +0x058 ThreadLocalStoragePointer : Ptr64 Void
   +0x060 ProcessEnvironmentBlock : Ptr64 _PEB
   +0x068 LastErrorValue   : Uint4B
   +0x06c CountOfOwnedCriticalSections : Uint4B
   <snip>

What’s more interesting is to look at the populated structure using a psuedo register like:

dt -r ntdll!_teb @teb
0:007> dt -r ntdll!_teb @$teb
<snip>
         +0x050 DllPath          : _UNICODE_STRING ""
         +0x060 ImagePathName    : _UNICODE_STRING "C:\WINDOWS\system32\notepad.exe"
         +0x070 CommandLine      : _UNICODE_STRING ""C:\WINDOWS\system32\notepad.exe" "
         +0x080 Environment      : 0x00000259`1dc60fe0 Void
         +0x088 StartingX        : 0
         +0x08c StartingY        : 0
         +0x090 CountX           : 0
         +0x094 CountY           : 0
         +0x098 CountCharsX      : 0
         +0x09c CountCharsY      : 0
         +0x0a0 FillAttribute    : 0
         +0x0a4 WindowFlags      : 0xc01
         +0x0a8 ShowWindowFlags  : 1
         +0x0b0 WindowTitle      : _UNICODE_STRING "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Notepad.lnk"
         +0x0c0 DesktopInfo      : _UNICODE_STRING "Winsta0\Default"
</snip>

Size of Structures:

To inspect the size of a structure (which will often be a parameter passed to a function):

0:000> ?? sizeof(ntdll!_PEB)
unsigned int 0x468

Writing memory:

We use the e (edit?) commands. For example:

0:000> r
eax=00000000 ebx=00000000 ecx=029ff258 edx=77791670 esi=02b5a000 edi=777136cc
eip=777cbb62 esp=029ff274 ebp=029ff2a0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
777cbb62 cc              int     3

0:000> dd esp L1
029ff274  f136b9fa

0:000> ed esp 41414141

0:000> dd esp L1
029ff274  41414141

The size modifiers are the same as with the display commands.

We can work with Ascii using the a version of the e command, or the u version for unicode.

0:000> da esp L5
029ff274  "Yikes"

0:000> ea esp "Rainy"

0:000> da esp L5
029ff274  "Rainy"

While writing exploits we can drop the ascii version straight into memory, and then pull it back out with the db command, giving us the bytes we need for shellcode.

0:000> ea esp "c:\\users\\chad\\payload.exe"

0:000> da esp L19
029ff274  "c:\users\chad\payload.exe"

0:000> db esp L19
029ff274  63 3a 5c 75 73 65 72 73-5c 63 68 61 64 5c 70 61  c:\users\chad\pa
029ff284  79 6c 6f 61 64 2e 65 78-65                       yload.exe

Searching Memory:

The search commands are s -

As an example, we’ll put a unique pattern in the process address space, then search:

0:000> ed esp 41424344

0:000> s -d 0 L?80000000 41424344
0229f994  41424344 777136cc 024b0000 00000000  DCBA.6qw..K.....

The example uses a DWORD -d as the type we want to search; it starts at address 0 and goes up 8000000 - we use the L? modifer for the top of the range.

To search for ascii we use -a instead:

0:000> s -a 0 L?80000000 "Microsoft Corporation"
0005357c  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
6b75bb78  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
6bd2b6fc  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
7094322c  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
70945412  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
74b4224c  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
754f6ecc  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
76b470ec  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
772611cc  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor
776abf9c  4d 69 63 72 6f 73 6f 66-74 20 43 6f 72 70 6f 72  Microsoft Corpor

The example above shows us that many of the binaries loaded by notepad.exe contain the ascii string “Microsoft Corporation”

Or unicode - u

0:000> s -u 0 L?80000000 "Microsoft Corporation"
0006c8d8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
0006ca00  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
689d97e8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
689d9934  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6b8cb168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6b8cb2dc  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6bd2ba60  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6bd2bbb8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6fec11c8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
6fec131c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
70943738  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
70943888  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
738fd168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
738fd2a8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
73c88118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
73c88274  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
73d591c8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
73d5933c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7417a7f8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7417a948  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
741c2118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
741c2268  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
741ec118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
741ec26c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
743a0168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
743a02d0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74455118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74455270  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7456b118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7456b278  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
745d4118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
745d42a0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74b42760  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74b428c0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74de8118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74de8240  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74f381b8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74f382ec  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74fd6118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
74fd6278  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
754f73d0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
754f751c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
765311c8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7653131c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7665f168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7665f2c4  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76b47878  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76b479cc  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76bd9778  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76bd98e0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76d4b168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76d4b2a8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76d4b428  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
76d4b540  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
770921a8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
77092308  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
772616d0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
77261830  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
772df168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
772df2cc  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7736f118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7736f24c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
773fe168  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
773fe290  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
77528118  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
7752825c  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
775eb1c8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
775eb324  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
776eb030  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
776eb174  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
778201a8  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.
778202e0  004d 0069 0063 0072 006f 0073 006f 0066  M.i.c.r.o.s.o.f.

Registers:

We can inspect registers with r

We can manipulate them by passing the register we are interested in, with the assignment operator:

0:000> r edi
edi=777136cc

0:000> r edi=00000001

0:000> r edi
edi=00000001

0:000> r
eax=00000000 ebx=00000000 ecx=0229f978 edx=77791670 esi=024b0000 edi=00000001
eip=777cbb62 esp=0229f994 ebp=0229f9c0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
777cbb62 cc              int     3

Breakpoints:

b family :)

bp kernel32!WriteFile for example. But you might have an unresolved symbol you want to nab: bu ole32!WriteStringStream.

bl to list, bd to disable one, be to re-enable, bc to clear.

The really powerful stuff is the automated actions:

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

or, with a conditional (like, only tell me if it’s an 8 byte write):

bp kernel32!WriteFile ".if (poi(esp + 0x0C) != 8) {gc} .else {.printf \"WriteFile just did the 8 byte write\";.echo;}"

Hardware breakpoints don’t need to software breakpoint (INT 3) inserted: ba e 1 Kernel32!WriteFile where e is execute access (could have been read or write) and 1 is the number of bytes.

Stepping:

p steps over a function. t steps into a function pt will step to the next return instruction. ph will continue to the next branch.

Examine Symbols:

x KernelBase!CreateNamed*

Formats:

Handy, it’ll show you the formated values of an input (decimal, hex etc).

.formats 41414141
Thanks!
Chad Duffey

Security Engineer