IoGetDeviceObjectPointer BSoD

Hello
I’m using IoGetDeviceObjectPointer to find a driver pointer by enumerating the device directory: Ex: searching \Driver\atapi

status = IoGetDeviceObjectPointer(&device_name, FILE_READ_DATA, &pFile, &pDev); <– Crash here
if ( !NT_SUCCESS( status ) || pDev == NULL || pDev->DriverObject == NULL )
goto next;

if ( pFile ) ObDereferenceObject( pFile );

//Pseudo code here
PDRIVER_OBJECT pDrv = pDev->DriverObject;
if ( pDrv->DriverName == L" \Driver\atapi") return pDrv;

Here’s the call stack:
It look like the IoGetDeviceObjectPointer is calling a USBSTOR driver, that crashed.
Minidump can be found here: https://trello-attachments.s3.amazonaws.com/52dfc2009f4fb4ad1fd6d6a5/541313380d7c6bf6a735bfdd/b7cbe5749a1deb19279ce07605c9936b/Mini091214-01.dmp

TrueSight is my driver.

b8509004 806ea5f3 8ac553f4 8b14805c 80546bec nt!KeInsertDeviceQueue+0x8
b8509028 804eef4c 8ac553d0 8b14805c 00000001 hal!HalAllocateAdapterChannel+0x31
b8509040 b66256a3 8ac553d0 8b148028 00000001 nt!IoAllocateAdapterChannel+0x2a
b8509084 b662649d 8b148028 8aa45880 80546bec USBPORT!USBPORT_FlushMapTransferList+0x1b1
b85090e0 b662738a 02eecdb0 ffffffff 80546bec USBPORT!USBPORT_FlushPendingList+0x5b1
b8509110 b662e334 8ae9eab8 b8509148 b662def8 USBPORT!USBPORT_QueueTransferUrb+0x248
b850911c b662def8 8b148028 8aa45880 8aea5434 USBPORT!USBPORT_AsyncTransfer+0x30
b8509148 b6633106 8ac01030 8b148028 00000090 USBPORT!USBPORT_ProcessURB+0x3f4
b8509168 b661c3b2 8ac01030 8aa45880 8aa45880 USBPORT!USBPORT_PdoInternalDeviceControlIrp+0x7e
b850918c 804ef1f9 8aa4595c 8ac01188 8aea5434 USBPORT!USBPORT_Dispatch+0x148
b850919c b714859c b85091c4 b714c82d 8aa45880 nt!IopfCallDriver+0x31
b85091a4 b714c82d 8aa45880 8ac01030 8aa45880 usbhub!USBH_PassIrp+0x18
b85091c4 b714d0ae 8ac64d50 8aa45880 8aa45880 usbhub!USBH_PdoUrbFilter+0xbd
b85091e0 b714a5e4 8aea5434 8aa45880 b8509214 usbhub!USBH_PdoDispatch+0x202
b85091f0 804ef1f9 8b090318 8aa45880 8aea5398 usbhub!USBH_HubDispatch+0x48
b8509200 b840070c 8aea54b7 8b09bb9c 8b09bb0a nt!IopfCallDriver+0x31
b8509214 b840165f 8aea52e0 8aa45880 8b1e0f14 USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+0x9c
b850924c b8402061 8aea52e0 8aa45880 8aea52e0 USBSTOR!USBSTOR_CbwTransfer+0x79
b8509274 804f0277 8aea52e0 00a45880 8b0a4f58 USBSTOR!USBSTOR_StartIo+0x13b
b8509294 b8400aee 8aea52e0 8aa45880 8b09bb88 nt!IoStartPacket+0x7d
b85092b8 804ef1f9 8b0a4ea0 8aa45880 8b09bab0 USBSTOR!USBSTOR_Scsi+0x108
b85092c8 b8108fdd 804fa218 8abe4430 00000000 nt!IopfCallDriver+0x31
b85092dc b810a7ed 8b09bab0 8abe4378 8ab22200 CLASSPNP!SubmitTransferPacket+0x82
b850938c b80fa02b 8abe4378 8ab220e8 b85093b8 CLASSPNP!ClassReadDriveCapacity+0xa2
b850939c b80fbc33 8abe4378 00070407 8ab220e8 disk!DiskReadDriveCapacity+0x25
b85093b8 b80f8af7 8abe46f8 89af7b90 89af7b90 disk!DiskIoctlGetPartitionInfo+0x39
b850944c b81093ed 8ab22030 89af7b90 00000000 disk!DiskDeviceControl+0x4c3
b8509468 804ef1f9 8ab22030 89af7b90 00000000 CLASSPNP!ClassDeviceControlDispatch+0x48
b8509478 b2c8f83e b2ce7eb0 b8049400 00000000 nt!IopfCallDriver+0x31
WARNING: Stack unwind information not available. Following frames may be wrong.
b850949c b2c8bb9e 8ab22030 00074004 00000000 sonypvt3+0xc83e
b850a37c b2c90ed0 b2ce7eb0 b850a410 b850a414 sonypvt3+0x8b9e
b850a3a0 b2c85c3a b2ce7eb0 b850a410 b850a414 sonypvt3+0xded0
b850a448 b2c85ba4 8a8dffd8 8963e500 b2c85520 sonypvt3+0x2c3a
b850a484 804ef1f9 8b043168 8963e500 8963e6ac sonypvt3+0x2ba4
b850a4d0 805359ab 00000000 89a78b10 8b11305c nt!IopfCallDriver+0x31
b850a4f0 b78922bf b7892189 00000000 8978a8c8 nt!ExReleaseResourceLite+0x8d
b850a4f4 b7892189 00000000 8978a8c8 8963e500 fltmgr!FltpPerformPreMountCallbacks+0x227
b850a560 8963e500 8963e6d0 b78963a8 8af313c8 fltmgr!FltpPerformPreMountCallbacks+0xf1
b850a5dc b78967ba 8af313c8 8963e500 8ab22030 0x8963e500
b850a60c 804ef1f9 8af313c8 8963e500 8963e500 fltmgr!FltpFsControl+0x5a
b850a61c 80581bff 00000000 8ab22030 806e7a4c nt!IopfCallDriver+0x31
b850a66c 804f5452 c0000013 88ee2901 00000000 nt!IopMountVolume+0x1b9
b850a69c 80582bf8 88ee29b0 8ab22030 b850a7d0 nt!IopCheckVpbMounted+0x5e
b850a78c 805bf4bc 8ab22030 00000000 8a071618 nt!IopParseDevice+0x3d8
b850a804 805bba48 00000000 b850a844 00000240 nt!ObpLookupObjectName+0x53c
b850a858 80576051 00000000 00000000 50a91800 nt!ObOpenObjectByName+0xea
b850a8d4 805769c8 b850aa50 00000001 b850aa28 nt!IopCreateFile+0x407
b850a930 8057a1c7 b850aa50 00000001 b850aa28 nt!IoCreateFile+0x8e
b850a970 805417e8 b850aa50 00000001 b850aa28 nt!NtOpenFile+0x27
b850a970 805006a9 b850aa50 00000001 b850aa28 nt!KiSystemServicePostCall
b850aa00 80576200 b850aa50 00000001 b850aa28 nt!ZwOpenFile+0x11
b850aa48 b21374b5 b850ae64 00000001 b850b270 nt!IoGetDeviceObjectPointer+0x40
b850b33c b2137444 b2139bd0 b850b75c 00000001 TrueSight!GetDriverByDeviceDirectory+0x2e5 [c:\tools\drvutils\device.cpp @ 381]
b850bc2c b21371a6 b2139bd0 b2139cb0 00000000 TrueSight!GetDriverByDeviceDirectory+0x274 [c:\tools\drvutils\device.cpp @ 366]
b850bc44 b2135922 b2139bd0 b850bc5c b213588a TrueSight!GetDriverByDriverName+0x16 [c:\tools\drvutils\device.cpp @ 302]
b850bc50 b213588a b213a3a4 b850bc84 b213a58f TrueSight!InitDevicesData+0x52 [c:\tools\roguekillerv8\driver\driver\core.cpp @ 34]
b850bc5c b213a58f b213a380 0000001c 00000000 TrueSight!InitData+0x1a [c:\tools\roguekillerv8\driver\driver\core.cpp @ 18]
b850bc84 805813af 89ed9468 88a15000 00000000 TrueSight!DriverEntry+0xff [c:\tools\roguekillerv8\driver\driver\driver.cpp @ 64]
b850bd54 805814bf 80001944 00000001 00000000 nt!IopLoadDriver+0x66d
b850bd7c 80538923 80001944 00000000 8b674b20 nt!IopLoadUnloadDriver+0x45
b850bdac 805cffee ae417bb8 00000000 00000000 nt!ExpWorkerThread+0xef
b850bddc 8054620e 80538834 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

On what IRQL are you calling the function?

Post !analyze -v output. We can’t be arsed to download your dump.

You’re trying to get the DEVICE object name of something called “\Driver\atapi”?

That’s not the name of a Device Object; It’s the name of a Driver Object. It shouldn’t crash if done correctly, but it won’t work in any case.

Note that a mini-dump is almost certainly going to be useless in trying to diagnose this (or anything). At least get a full Kernel dump.

Fix your code… if you still have problems, post again.

Peter
OSR
@OSRDrivers

P.S. Your pseudo code:

//Pseudo code here
PDRIVER_OBJECT pDrv = pDev->DriverObject;
if ( pDrv->DriverName == L" \Driver\atapi") return pDrv;

You *do* realize that you need to escape those back slashes, right?

@Peter:
“You’re trying to get the DEVICE object name of something called “\Driver\atapi”?”
No, I’m trying to retrieve the DRIVER object

"It shouldn’t crash if done correctly, but it won’t work in any case. "
What would be the proper way to avoid a crash on that call? Even if that doesn’t success anytime, I’d like not having BSoD on that very small count of attempt.

“Note that a mini-dump is almost certainly going to be useless in trying to diagnose this (or anything). At least get a full Kernel dump.”
Quite hard to request that from a customer… What

@Alex, sorry for that, here’s the rest of the information:


UNEXPECTED_KERNEL_MODE_TRAP_M (1000007f)
This means a trap occurred in kernel mode, and it’s a trap of a kind
that the kernel isn’t allowed to have/catch (bound trap) or that
is always instant death (double fault). The first number in the
bugcheck params is the number of the trap (8 = double fault, etc)
Consult an Intel x86 family manual to learn more about what these
traps are. Here is a *portion* of those codes:
If kv shows a taskGate
use .tss on the part before the colon, then kv.
Else if kv shows a trapframe
use .trap on that value
Else
.trap on the appropriate frame will show where the trap was taken
(on x86, this will be the ebp that goes with the procedure KiTrap)
Endif
kb will then show the corrected stack.
Arguments:
Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
Arg2: 80042000
Arg3: 00000000
Arg4: 00000000

Debugging Details:

BUGCHECK_STR: 0x7f_8

CUSTOMER_CRASH_COUNT: 1

DEFAULT_BUCKET_ID: DRIVER_FAULT

PROCESS_NAME: System

LAST_CONTROL_TRANSFER: from 806ea5f3 to 804fc638

<<<<<>>>>>

STACK_COMMAND: kb

FOLLOWUP_IP:
USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+9c
b840070c 5f pop edi

SYMBOL_STACK_INDEX: 10

SYMBOL_NAME: USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+9c

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: USBSTOR

IMAGE_NAME: USBSTOR.SYS

DEBUG_FLR_IMAGE_TIMESTAMP: 480254d1

FAILURE_BUCKET_ID: 0x7f_8_USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+9c

BUCKET_ID: 0x7f_8_USBSTOR!USBSTOR_IssueBulkOrInterruptRequest+9c

Followup: MachineOwner
---------

@Alex, it’s initiated starting at DriverEntry, so PASSIVE_LEVEL.

You have a customer running a driver with full symbols?

In any case, it’s not that hard to ask for a full dump from a customer. We do it every day of the week. You tell them “Please set your machine to take a proper dump , and the next time this happens please send it to us.”

Do you have a repro case for this or is it a single customer problem you’re trying to debug. If it’s a single customer problem with no repro case, I’d suggest it’s not worth analysing further at this point. It doesn’t look related to the filter.

Peter
OSR
@OSRDrivers

“You have a customer running a driver with full symbols?”
Yes, that’s the debug version, easier for me if it crashed. I think that’s a very big file right? 4GB or so?

“Do you have a repro case for this or is it a single customer problem you’re trying to debug.”
That happens for a few customers, I can just bother them otherwise I can’t reproduce. I think that’s related to the drivers they have, and their hardware then.

“If it’s a single customer problem with no repro case, I’d suggest it’s not worth analysing further at this point. It doesn’t look related to the filter.”
Yes, and that’s the problem. But since that happens when my driver is loaded in memory, they blame me (that sounds logical for many people). There is no way to avoid this with a try catch for example?

UNEXPECTED_KERNEL_MODE_TRAP_M - kernel stack overflow

[b8509000,b850c000) 3 pages in kernel stack
exception at very begin of function - nt!KeInsertDeviceQueue+0x8 - just on push instruction

also in your src

if ( pFile ) ObDereferenceObject( pFile );

after this pDev already not correct use, because you release holding reference to it. in concrete case \Driver\atapi not disappear, but in general this is serious error

I still have no idea what the OP is trying to do.

\Driver\atapi is not the name of a Device Object. If the call DID work, what in the world would you do next with that pointer? You can’t do IoCallDriver with it, that’s for sure.

The root cause here is that calling IoGetDeviceObjectPointer for a name that’s not a Device Object is broken… regardless of some other side-effect or other. It can’t *ever* work, so it needs to be fixed regardless of this crash.

Peter
OSR
@OSRDrivers

harald

“after this pDev already not correct use, because you release holding reference to it. in concrete case \Driver\atapi not disappear, but in general this is serious error”
I’m not sure to understand that part, is that because of that?

http://msdn.microsoft.com/en-us/library/windows/hardware/ff549198(v=vs.85).aspx
MSDN: However, drivers that close the file object before the unload process must take out an extra reference on the device object before dereferencing the file object. Otherwise, dereferencing the file object can lead to a premature deletion of the device object.

=> Does this means I need to increment pDev ref count before?

Peter
“\Driver\atapi is not the name of a Device Object”
Yes you’re right, looks at my first and second message :slight_smile: I’m trying to get a DRIVER object.
What for? I want to check for IRP hooks, so I do need that pointer.

>I’m trying to get a DRIVER object.

The function is called IoGetDeviceObjectPointer.

Io Get *Device* Object Pointer

Does that ring a bell?

Alex
You are not going far enough in the code:

PDRIVER_OBJECT pDrv = pDev->DriverObject;

I have another method iterating the Driver directory instead and using ObOpenObjectByName, but it’s used only if the previous failed.

To get a DEVICE object you need to supply a DEVICE object name, not DRIVER object name.

xxxxx@hotmail.fr wrote:

@Peter:
“You’re trying to get the DEVICE object name of something called “\Driver\atapi”?”
No, I’m trying to retrieve the DRIVER object

Why? You can’t issue requests to a driver. You can only issue requests
to a device.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

OP: IoGetDeviceObjectPounter only works for device objects. That’s why it has the name it has. It can NOT. be used to find a driver object. Ever. It. Will. Not. Work.

Fix your code.

With all due respect, it scares me that you’re writing kernel mode code and don’t understand why IoGetDeviceObjectPointer can’t be used to locate a driver object. How do ypu suppose this function works?

Peter
OSR
@OSRDrivers

From the beginning it was easy to understand that you were trying to use IoGetDeviceObjectPointer as a (much too long) detour to the undocumented ObOpenObjectByName. Much too long because it seems you get a double fault trap probably as a result of a kernel stack overflow. So you know now you are on the wrong path. But it was a clever mean of listing the \Driver directory.

So you probably list the \Device directory with the ZwQueryDirectoryObject API which is not present in the ZwXxx Routines section and then call ObOpenObjectByName to open a DEVICE_OBJECT and consequently obtain a DRIVER_OBJECT pointer.

What is the purpose of this work ? Are you hunting rootkits ? Rootkits now hide their DRIVER_OBJECT, they can easily hide their DEVICE_OBJECT too. Don’t you agree ?

Please, please, please guys; READ THE ENTIRE CODE!

status = IoGetDeviceObjectPointer(&device_name, FILE_READ_DATA, &pFile, &pDev); <– Device name, Device object right? It’s gotten by enumerating \Device directory.

if ( !NT_SUCCESS( status ) || pDev == NULL || pDev->DriverObject == NULL )
goto next;

if ( pFile ) ObDereferenceObject( pFile );
PDRIVER_OBJECT pDrv = pDev->DriverObject; <— Driver object now, that’s magic!
Maybe some help for you: http://msdn.microsoft.com/en-us/library/windows/hardware/ff543147(v=vs.85).aspx

if ( pDrv->DriverName == L" \Driver\atapi") return pDrv; <---- Still DRIVER_OBJECT, in the end.


Guys, I’m tired to say that again and again. My code is working fine in 99.99% of the cases. Only a very small amount of people are reporting a BSoD, crashing on that IoGetDeviceObjectPointer call.

Yes, I’m getting a DEVICE_OBJECT by name, and yes, it turns into a DRIVER_OBJECT by using the pointer of the struct. And NO, I’m not trying to get a DRIVER_OBJECT with IoGetDeviceObjectPointer. Is that clear enough now?

Looks like only Ntdev Geek is reading the posts…
Thanks mate!

Yes I’m trying to get a DRIVER_OBJECT on a particular one, to check if it’s major functions are hooked. I’m trying to get a regular DRIVER_OBJECT, not the one of a rootkit

Do you know an alternative way to get a DRIVER_OBJECT by its name?

Have you tried to attach a filesystem minifilter to the different volumes and use IoGetDiskDeviceObject to obtain a pointer to a disk device object ?

Have you heard about the GMER tool ? It’s an anti-rootkit tool that watches the IRP_MJ_WRITE of the disk drivers to see if any rootkit is able to write malicious boot code.

So debug it in a virtual machine to see how it performs.

Note: the kernel binary is stored in the GMER.EXE as a binary resource. It is extracted and then loaded by the program. The kernel binary is deleted once loaded but it is quite easy to extract it from the executable resource tree with the WIN32 API.

http://www.gmer.net/

Good luck.

Looks like a good idea, yeah I know Gmer quite a bit for been using it for a couple year.
I’m using that method to get driver pointer of the Keyboard stack as well, that method works pretty well so far (as I said 99.99% of cases) so it’s deceiving to go another route because of that :confused:
But still it’s interesting idea that deserves experimenting.
Thanks.

The problem is, you didn’t PROVIDE “the entire code”… you provided a jumble of pseudo-code and a poorly phrased question:

The above LEAVES OUT the detail that you’re trying to find a *device* and from the *device* you’re trying to find its *driver*.

And you failed to clarify this on any of the follow-ups to your post. And, yes, it matters.

FINALLY. Yes.

It is unwise to insult the people who are trying to help you. I *get* that your first language isn’t English, but don’t get all irritated and frustrated when we quite reasonably fail to understand WTF you’re trying to do.

Aside from all that side show…

Have you considered calling ObReferenceObjectByName? That’s how I would do it. You’ll have to provide the prototype yourself, but that function hasn’t changed in 20 years… so even though it’s undocumented, I’d consider it pretty stable.

Peter
OSR
@OSRDrivers