How to debug missing imports at driver load time
Debugging when your driver fails to load can be exasperating, especially if it is due to a missing import. Windows 2000 would put up a dialog box telling the user which import was missing, but the user can't do anything about it (unless she is the driver developer), so that dialog was removed post Windows 2000. You can run depends.exe against your driver on the OS that you are targeting, but that's no fun ;). Instead, let's see you how can debug unresolved imports at load time.
I added a call to KeEnterGuardedRegion into my test driver wdfrawbusenumtest. This function was added in Windows Server 2003 SP1, so it is a perfect API to import and then try to load on XP. First, you must set your symbols to the public symbol server
0: kd> !symfix
0: kd> .sympath
Symbol search path is: srv*https://msdl.microsoft.com/download/symbols
0: kd> .reload ntoskrnl.exe
Force unload of ntkrnlmp.exe
Loading symbols for 804d7000 ntkrnlmp.exe -> ntkrnlmp.exe
ModLoad: 804d7000 806fd000 ntkrnlmp.exe
0: kd> !lmi nt
...
Symbol Type: PDB - Symbols loaded successfully from symbol server.
ntkrnlmp.pdb\AA1EE1B2A63A4232A379F3EFDDC4CFE82\ntkrnlmp.pdb
Load Report: public symbols , not source indexed
ntkrnlmp.pdb\AA1EE1B2A63A4232A379F3EFDDC4CFE82\ntkrnlmp.pdb
then set a bp on MmLoadSystemImage
0: kd> bp nt!MmLoadSystemImage
0: kd> g
then attempt to load the driver (I used device manager, you can use devcon or net start if you are writing a legacy style driver which does not support PnP). And we hit our breakpoint
Breakpoint 0 hit
nt!MmLoadSystemImage:
805a86ff 6874010000 push 0x174
0: kd> kb
ChildEBP RetAddr Args to Child
f88f2820 805a40d2 f88f28a4 00000000 00000000 nt!MmLoadSystemImage
The first parameter passed to MmLoadSystemImage is a PUNICODE_STRING, so let's make sure that this is our driver we are going to debug
0: kd> dt f88f28a4 _UNICODE_STRING
"\SystemRoot\system32\DRIVERS\wdfrawbusenumtest.sys"
+0x000 Length : 0x64
+0x002 MaximumLength : 0x66
+0x004 Buffer : 0xe1600c78 "\SystemRoot\system32\DRIVERS\wdfrawbusenumtest.sys"
Now, we need to set a breakpoint on MiResolveImageReferences, which will return the unresolved import on failure.
0: kd> bp nt!MiResolveImageReferences
0: kd> g
nt!MiResolveImageReferences:
805a223d 8bff mov edi,edi
0: kd> kb
ChildEBP RetAddr Args to Child
f88f2670 805a3ecf f1e47000 f88f27c4 00000000 nt!MiResolveImageReferences
f88f2820 805a40d2 f88f28a4 00000000 00000000 nt!MmLoadSystemImage+0x8c8
This is an internal function so this can change at anytime, but currently the fourth parameter is a PCHAR* which will be filled with name of the resolved import on failure. First, we will look at the 4th (on Windows 2000 it is the 5th, but we are debugging XP here) parameter by dumping the EBP and then looking at what it points to (since it is a PCHAR*).
0: kd> dp f88f2670
f88f2670 00000246 805a3ecf f1e47000 f88f27c4
f88f2680 00000000 f88f27d4 f88f27d8 f88f27dc
0: kd> dp f88f27d4 l1
f88f27d4 81ffa250
and then we will jump back to the caller and verify failure
0: kd> g 805a3ecf
nt!MmLoadSystemImage+0x8c8:
0: kd> reax
eax=c0000263
0: kd> !error c0000263
Error code: (NTSTATUS) 0xc0000263 (3221226083) - {Driver Entry Point Not Found} The %hs device driver could not locate the entry point %hs in driver %hs.
and now let's see the missing import!
0: kd> dc 81ffa250
81ffa250 6e45654b 47726574 64726175 65526465 KeEnterGuardedRe
81ffa260 6e6f6967 00000000 00000000 00000000 gion............
Comments
Anonymous
March 28, 2006
The comment has been removedAnonymous
March 28, 2006
Bryan, relying on OS symbols is a prerequisite for debugging any driver issue. The fact that they are publicly available on a symbol server and you don't have to search them out or copy them locally removes that issue almost entirely.
As you said, a std user should never see this message. If the user does, that means that the distribution of the driver is busted.
I never said that this was the best method for debugging this issue either ;). I was just showing how to use the OS itself to debug an issue if you are stuck. User mode has much better tools. For instance, you can use depends.exe to map out the import dependencies and flag any missing exports. It has the added benefit of showing all missing imports vs one at a time with the method I demonstrated.Anonymous
March 28, 2006
doron: depends is a VS tool, isn't it? I thought the DDK/WDK was a stand-alone product. Now, I need VS to debug an issue.
Additionally, good look giving this a customer to find out what is missing on his machine, which is not missing on your own one.
For example, I am used to have "customers" which are technically literate. They are used to give bug reports which are very helpful. In most cases, they can tell me what is wrong in much technical details.
"Give a man a fish and he'll eat it for the day. Teach him how to fish and he will eat for the rest of his life." This sentece makes sense, even for computers. Unfortunately, Miccrosoft seems to want to give only the fish to the people. Remember, there are even Windows users ;) who want to learn fishinig, not only to have the fish, but Microsoft seems to be blind to this.
Doron: No, this is NO rant against you, but more against some MS decisions. I am very happy you give us ways around these "limitations"!
Anyway, I don't think we are allowed to give depends.exe to some customer, are we?
- Spiro.Anonymous
March 29, 2006
> I never said that this was the best method for debugging this issue either ;).
I see what you're saying; I was commenting on the part where you mentioned the reason behind removing the dialog in XP and beyond. That likely wasn't your decision to make, though, so I should probably go complain to someone else. ;-)
Anyway, thanks! This blog is quite useful (especially the "debugger commands that make my life easier" series; I've used a few of them while trying to debug a BSOD in winpcap).Anonymous
March 29, 2006
if a user ever sees this, the company/person who distributed the driver did not do due diligence in their quality assurance. this type of error should only show up in house when the driver is in development and test.
yes, you need VS for depends.exe. You can get VS student edition for free if i remember correctly. But it is a good point. I will file a bug against the WDK to include depends.exe post Vista.Anonymous
July 26, 2006
Updated the entry to reflect that on Windows 2000, the parameter which will contain the missing import is 5th, not 4th (thanks to Jake Oshins for pointing that out!).Anonymous
November 02, 2006
I found this one out the hard way today. I was experimenting with the KMDF loader driver (wdfldr.sys).Anonymous
January 21, 2009
PingBack from http://www.keyongtech.com/2547266-wdk-build-environment