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:\pubsym\cache\ndis.pdb\40D6C85AC9F74887A652601839A1F56D2\ndis.pdb Load Report: public symbols , not source indexed c:\pubsym\cache\ndis.pdb\40D6C85AC9F74887A652601839A1F56D2\ndis.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.