Archive for July, 2009

What is the NET tab in the Kernel Debugging dialog for?

Tuesday, July 28th, 2009

In the last version or so of WinDBG an intriguing tab appeared in the Kernel Debugging dialog alongside the usual COM, 1394, USB, and Local options:

netkdbg1

Using the network as a debug transport is certainly intriguing. With lots of machines shipping nowadays without COM ports or 1394 adapters and the insane limitations of USB debug support, debugging over the network would definitely be a great addition. Of course, that would require significant effort on the target machine side to control a dedicated NIC from the limited environment of the KD stub. So, it was interesting to see this tab show up because I wasn’t aware of any shipping O/S supporting the network as a KD protocol.

Fortunately (or unfortunately, as the case may be) the question of what this tab does was answered by Brycej of the Debugging Tools for Windows team in this thread http://tinyurl.com/kry8qw:

While the assertion that the tab was due to WinCE was a reasonable one, it is actually a remnant of some prototyping code we’re working on.

It may not be out right away, but at least you know what’s coming…

-Brycej

Guess we’ll have to wait and see what the future holds.

Finding a paged out buffer when you need one

Sunday, July 26th, 2009

One day I wanted to demonstrate the !pte command on a page that had been paged out to a paging file. The platform in question was an XP SP3 dump and I was slightly on the spot, so I had to quickly think of a way to find a page that was actually paged out.

I immediately thought to crawl through the paged pool range in the kernel virtual address space, running !pte on each page. I could do this with something like .for or simply manually walk every 4K until I hit a paged out page.

Because I was feeling lucky (and didn’t want to look up the .for syntax), I decided to try manually walking but quickly found that tedious and I didn’t get the results that I was looking for. Everything I hit was paged in, as indicated by the valid bit being set:

allvalid

So, I needed something else that might provide a quicker solution. Then I thought about paged code sections in a driver image. By default, all driver code (and data) is non-pageable. However, a driver writer is able to use a pragma directive to put code into the PAGE section of its image.

Code in the PAGE section of a driver is subject to being paged out. In addition, the memory manager pages this code to a paging file instead of retrieving it again from the image file (like in most user mode application scenarios). You can see an example of the pragma usage in the FASTFAT source from the WDK:

fatpragma

Being reminded of this, I decided to grab a Microsoft supplied driver and check for a PAGE section in the PE header, since MS supplied drivers often utilize this to decrease their memory footprint in the system. For no particular reason, I went with fltmgr.sys, which is the binary for Filter Manager. This did indeed reveal a code section named PAGE in the image:

pagesect

This gave me a new, smaller space to search for a page paged out to a paging file. So, I gave it a shot and lucked out immediately:

pagedout

PDB Paths and the PE Debug Directory

Sunday, July 26th, 2009

You might have noticed that WinDBG sometimes “knows” where to find the PDB for your driver even if you have never set your Symbol Search Path to point to your object directory. Spooky, and it certainly begs the question of how WinDBG knows where to look for your PDB.

The answer is in the debug directory of your driver’s PE image. The debug directory can contain, well, debug information, or can point off to a file containing debug information. This is how WinDBG can so easily find your PDB, by default the fully qualified path (FQP) to the PDB is found in the debug directory. If you want to see the path, you can do so with the !dh command, which will parse the PE header of the image and show you the intepreted results. Just execute !dh modulename in the debugger and scroll down to the Debug Directories section:

dbgdir

You can even leverage this to find information about drivers that you don’t own. I just checked the loaded module list on my current machine and had a driver loaded that I didn’t recognize: NETw4x32.sys. Doing a !dh on that module tells me that the FQP is:

c:\sandbox\94922\win_driver\miniport\ndis5x\objfre_wxp_x86\i386\NETw4x32.pdb

So, it’s the free build of an NDIS 5.x miniport driver, which isn’t bad for information gleaned from two seconds of effort.

The problem with those FQPs is that they can contain information that you don’t want to share with the world. Build machine names, developer names, etc. may show up in the path and you might not want people outside your company to have access to that info. Luckily, there is a way to strip the path information out of your image files and that is exactly what Microsoft does with their binaries. For example, take the kernel on my system using the info from !dh nt:

dbgnt

The secret to making this work is the binplace tool, which exists mostly to move binary outputs of the build process to various locations. However, it has the added features of generating public PDB files as well as stripping the path infromation from your released image files.

Getting binplace integrated to your build is another post for another day, but details can be found on MSDN if you’re interested: http://msdn.microsoft.com/en-us/library/ms791453.aspx

Owning Process vs Attached Process

Thursday, July 16th, 2009

A change was made to Windows around the Server 2003 timeframe that can make for some confusing information in the !thread output. Specifically, I’m referring to the Owning Process and Attached Process fields:

ownatt

The above output is from an XP machine and indicates that no information is available for the process that currently owns this thread, but the thread is attached to the System process. Let’s compare that with a similar thread from a Win7 machine:

win7ownatt

On the Win7 machine, the information is switched! So, this indicates to us that the owning process is the System process and the thread is not attached to any process. What’s the deal? Are these threads running under different circumstances or is the debugger showing us bogus information?

Well, what happened is that changes have been made to the KTHREAD and WinDBG was modified to reflect the new changes. This ends up making the output a little misleading on older platforms.

Prior to Server 2003, the kernel only tracked the attached processes of the thread. Threads start out attached to the process that they were created for, but the O/S and drivers are able to temporarily attach  a thread to another process with KeStackAttachProcess. While attached to another process, a thread runs under the context of that process and is able to reference that process’ handles, virtual address space, etc. Because the KTHREAD didn’t have a field that pointed directly to the process that the thread was originally created for, there was only one process to show in the !thread output. This is reflected in the example output shown in the !thread documentation, which was clearly captured from an older debugger version that made no mention of the Attached Process:

2kownt

On Server 2003 and later, the KTHREAD keeps track of the original process that the thread was created for. This is what !thread is trying to leverage, showing both the Owning Process (process that the thread was originally created for) and Attached Process (the process under which the thread is currently running).

If you run !thread on a Server 2003 and later target, the Owning Process will show the process that the thread was created for and Attached Process will be NULL if the thread isn’t currently running under a different process context.

However, if you run !thread on XP, the extension will get an error when trying to get the owning process field from the KTHREAD. The way that !thread reports this to you is by showing <Unknown> in the output. The extension will then check the attached process info and get a valid result (since that’s all XP tracks). The output will then show the Attached Process information as being valid.

It’s also interesting to note that, as the name implies, KeStackAttachProcess calls can be nested. Unfortunately, on no version of Windows does the !thread output try to traverse the “stack” of processes that this thread is currently attached to, they all just show the current one.

MmMapLockedPagesSpecifyCache and WOW64

Sunday, July 12th, 2009

I’ve talked about MmMapLockedPagesSpecifyCache before, but this time I wanted to focus on the AccessMode parameter. If you specify an AccessMode of UserMode, the buffer returned will be a user virtual address. Thus, it will be visible to the user and will only be valid in the context of the process in which the call to MmMapLockedPagesSpecifyCache was made.

That’s all fine and good, but it brings up an interesting question when dealing with the x64 (as I’m wont to do, I’m ignoring the IA64 because I have no practical experience with it). When running Windows x64 editions, all kernel mode code is 64bit but user mode code can be either 32bit or 64bit. This great for app compat, but as a driver writer this can make your life more difficult.

Imagine that you have an IOCTL that has a data structure with an embedded HANDLE in it. HANDLEs are pointer precision, so if a 32bit application sends this IOCTL to you the buffer is going to have a different layout than if a 64bit application sends it to you. To fix this, you need to have multiple definitions of the IOCTL in your driver and use IoIs32bitProcess to determine which structure you should use.

But,  what if part of the IOCTL processing involves mapping a buffer into the virtual address space of the application with MmMapLockedPagesSpecifyCache? Do you need to do anything special to make sure that the returned address is only 32bits wide if the caller is 32bit? The answer, thankfully, is no, you don’t need to do anything special. The Mm will make sure to return you an appropriately sized pointer for the current process’ user virtual address space.

Caveat emptor: It’s generally not considered best practice to map buffers into the user virtual address space. If it seems like a good idea to you and you can’t imagine what the problems with it might be, then you probably should think about another way to accomplish your task.

Pseudo registers and r?

Thursday, July 9th, 2009

WinDBG supports a set of pseudo registers, which are registers that don’t actually exist on the platform but contain interesting values during debugging.

For example, there is a $peb pseudo register that holds the address of the PEB for the current process. So, I can execute or script:

!peb @$peb

And know that I’ll always view the PEB of the current process. See the Pseudo-Register Syntax section of the WinDBG docs for a full list of all pseudo registers.

In addition to the debugger supplied pseudo registers, there are 20 user defined pseudo registers. The names of these user defined registers are $t0-$t19 and they can be used to hold any value you want. As a trivial example, I can store an integer value in there and recall it later:

t03Very useful in scripting situations, which hopefully I’ll get around to posting later…

That’s cool and all, but there’s another interesting feature to pseudo registers that is worth mentioning. Pseudo registers can be used with the r? command, which allows you to assign a type to the register along with the value. So, let’s set the $t0 register to be an EPROCESS this time:

t0procWith the above syntax the $t0 register is now an EPROCESS pointer at address 0×89635850.

Important note: r? uses the C++ expression evaluator, which treats all addresses as decimal by default! So the 0x prefix in the above is mandatory!

Now that $t0 is an EPROCESS pointer, what can we do? Well, we can start to dereference fields of it as if we were programming in C or C++.  The only trick is that we need to make sure we’re using the C++ evaluator, since WinDBG defaults to the MASM evaluator. We can do this in one of two ways, we can either do an explicit override for our commands:

cppeval

Or, we can change the current evaluator and omit the override:

chgexp

Build environment macros

Friday, July 3rd, 2009

The WDK build environment has some handy built in macros. For example:

..

Go up one directory

Go up two directories

bcz

build -cZMg

You can get the entire list of available macros by checking the generic.mac file in the \bin subdirectory. You can also add your own macros or augment the existing ones.

For example, I always add the W flag to the build command of the bcz macro so that my warnings show up in the build output instead of just being sent to a .wrn file:

bldwrn

(Note that that warning doesn’t actually exist in the sample, I added it myself for illustrative purposes)

Driver and Kernel Development MVP

Wednesday, July 1st, 2009

After eight years in the community, this is my first year being nominated and selected as a Microsoft MVP. Hope this year is as good as the last eight and thanks to those who nominated me!