Getting started with NDISKD
Part 1 of a beginner’s guide to debugging with NDISKD
If you haven’t already, grab the updated WDK with its new ndiskd debugger extension. You’ll need it for today’s laboratory exercise: getting started with ndiskd.
If you are new to Windows kernel debugging, check out Ilias’s thorough tutorial. You should follow that tutorial to get your kernel debugger attached to another computer. While you can use either Windbg.exe or Kd.exe, I highly suggest using Windbg—in just a moment, you’ll see why Windbg is much easier than Kd.
When I start debugging network problems, my first step is always to double-check that the NDIS symbols are correctly loaded. Use .reload /f ndis.sys to force the debugger to download the ndis.pdb symbol file. Then use the !lmi ndis extension and look for the magic phrase “Symbols loaded successfully”. If everything went according to plan, you should get output similar to this:
kd> .reload /f ndis.sys
kd> !lmi ndis
Loaded Module Info: [ndis]
Module: ndis
Base Address: fffff880014bf000
Image Name: ndis.sys
Machine Type: 34404 (X64)
Time Stamp: 4a5bc184 Mon Jul 13 16:21:40 2009
Size: f2000
CheckSum: f0209
Characteristics: 22 perf
Debug Data Dirs: Type Size VA Pointer
CODEVIEW 21, 54920, 53f20 RSDS - GUID: {40D6C85A-C9F7-4887-A652-601839A1F56D}
Age: 2, Pdb: ndis.pdb
CLSID 4, 5491c, 53f1c [Data not mapped]
Image Type: MEMORY - Image read successfully from loaded memory.
Symbol Type: PDB - Symbols loaded successfully from symbol server.
c:pubsymcachendis.pdb40D6C85AC9F74887A652601839A1F56D2ndis.pdb
Load Report: public symbols , not source indexed
c:pubsymcachendis.pdb40D6C85AC9F74887A652601839A1F56D2ndis.pdb
Now that your debugger is set up correctly, we can start using ndiskd. The first command we’ll try is !ndiskd.help.
kd> !ndiskd.help
NDIS KD EXTENSIONS
ndis Show NDIS.sys build info
help This help and lots more
miniport Show miniports (this is a good starting place)
protocol Show protocol drivers
mopen Show open bindings between miniport and protocol
filter Show light-weight filters
nbl Show information about an NET_BUFFER_LIST
oid Show pending OID Requests
→ Show more extensions
If you are using Windbg.exe (as opposed to Kd.exe), you probably immediately noticed the clickable hyperlinks that allow you to drill down into more detail. The hyperlinks are (in my opinion!) a major time-saver, since they save me the effort of typing and they save memorizing a bunch of the ndiskd syntax. In fact, with windbg, you can exercise all the functionality of !ndiskd just by following links from the output of !ndiskd.help. That’s a good reason to prefer windbg!
The help message offers smart advice: !ndiskd.miniport is indeed a good starting place. After double-checking the symbols, !ndiskd.miniport is almost always the next command I use. You can read ndiskd’s built-in help by clicking on the word “miniport” in Windbg (or by running !ndiskd.help miniport).
After reading the built-in help, we’re getting anxious to try it out. Let’s take a look at what it shows on my computer:
kd> !ndiskd.miniport
MiniDriver Miniport Name _
fffffa800acf4640 fffffa800ad051a0 WAN Miniport (SSTP)
fffffa800acf0530 fffffa800ad031a0 WAN Miniport (PPTP)
fffffa800acec0a0 fffffa800ad011a0 WAN Miniport (PPPOE)
fffffa800ace8640 fffffa800acff1a0 WAN Miniport (IPv6)
fffffa800ace8640 fffffa800acfd1a0 WAN Miniport (IP)
fffffa800ace8640 fffffa800acb71a0 WAN Miniport (Network Monitor)
fffffa800acd76e0 fffffa800acb41a0 WAN Miniport (L2TP)
fffffa800acc76e0 fffffa800acfb1a0 MAC Bridge Miniport
fffffa800acabb90 fffffa800acac1a0 WAN Miniport (IKEv2)
fffffa800ac8f020 fffffa800ac911a0 Microsoft Virtual Machine Bus Network Adapter
fffffa800ac57020 fffffa800ac731a0 Teredo Tunneling Pseudo-Interface
fffffa800ac57020 fffffa800ac711a0 Microsoft ISATAP Adapter #6
fffffa800ac57020 fffffa800ac6f1a0 Microsoft ISATAP Adapter #5
fffffa800ac57020 fffffa800ac681a0 Microsoft ISATAP Adapter #2
fffffa800ac57020 fffffa800ac5d1a0 Microsoft ISATAP Adapter
fffffa800ac57020 fffffa800ac5b1a0 Microsoft 6to4 Adapter #2
fffffa800ac57020 fffffa800ac581a0 Microsoft 6to4 Adapter
Because we ran !ndiskd.miniport without any parameters, it prints a table of all the active miniport adapters in the system. The first column contains the NDIS handle of the Miniport Driver (what we imaginatively call the MiniDriver), the second column contains the NDIS handle of the Miniport Adapter instance (what we call the Miniport), and the third column is the instance name.
What’s the difference between a MiniDriver and a Miniport? Find out the answer here. As an example, you can see that all the instances of “Microsoft ISATAP Adapter” have the same MiniDriver, but correspond to different Miniport instances. That means that one driver (tunnel.sys, in this case) has created multiple miniport instances.
Most of the time, I would continue debugging by clicking on the Miniport instance in question (2nd column). But it looks like we’ve already used up all our time this week. In a future laboratory, we will discuss the !ndiskd.miniport command in more detail. However, you don’t have to wait for us before you start exploring—get out Windbg and try the hyperlinks for yourself! If you want a challenge, see if you can use the hyperlinks to set a breakpoint on your miniport's MiniportSendNetBufferLists handler and catch each packet before it is transmitted.