Programmatic Inspection of Device Driver Stack

I am trying to programmatically enumerate all of the IRP handlers that will be called when an IRP is sent to a particular device. I know that I can get a driver object related to a particular device through a call to IoGetDeviceObjectPointer and from there can inspect the Driver Object’s MajorFunction table. However, if I am clear about how the driver stack works in Windows there could be filter drivers attached lower in the device stack and references to the IRP handlers they register would not appear in this “top layer” MajorFunction table referenced by the Driver/Device Object returned by IoGetDeviceObjectPointer. Thus what I am really trying to do is enumerate all of the DriverObject’s and their respective MajorFunction tables that will be referenced when an IRP is sent to a particular device.

My searching for a solution to this problem has suggested I investigate the SetupDI API. I have, and have looked at the Devcon example in the DDK but it wasn’t immediately clear to me that this API could yield the actual kernel objects associated with a device stack that I am interested in (DeviceObject/DriverObject/MajorFunction). It seems to me that I should be able to use other Windows IO Manager calls like IoGetDeviceObjectPointer to enumerate these objects I want, but perhaps not since I have looked pretty hard yet have not found them.

What is the best way to do what I am trying to accomplish? Can I do it with Windows IO Manager calls, or is there some way to use SetupDI in a similar way to get access to the relevant kernel objects?

Thanks a bunch for any help you can give me!

>What is the best way to do what I am trying to accomplish? Can I do it with

Windows IO Manager calls, or is there some >way to use SetupDI in a similar
way to get access to the relevant kernel objects?

Well, there’s a few things here to sort out for you. I’ll start by saying
that SetupDi isn’t really suited for what you’re asking. All you can really
get out of SetupDi is the, “Devices by Connection” view in Device Manager.
It doesn’t so much deal with device objects and what the dispatch entry
points in the driver objects would be, that’s strictly in the realm of
kernel mode.

With that out of the way…You have to realize that there are two concepts
in Windows. There are device stacks, which are sets of attached devices, and
device branches, which are *logical* groupings of device objects and device
stacks. So, for example, when an I/O request gets sent to the storage
branch, it first flows through the file system stack, then the volume stack,
then the disk stack, etc. Even if you know all of the devices in a
particular stack that won’t give you, “all of the IRP handlers that will be
called when an IRP is sent to a particular device” because those might not
all be in the same stack. Which brings me to my next point…

Even worse, the flow of an I/O request is never pre-determined. Any device
could send the request to any other device in the system at any point, so
there’s no way to know a priori where an IRP is going to go. This is why we
created IRPTracker, which tracks the IRPs at runtime and logs an entry for
each device object they touch. This relies on hacks though that aren’t
really suitable for production code.

That all makes your problem as stated pretty intractable. If you can scope
it or redefine it better we might be able to help.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
> I am trying to programmatically enumerate all of the IRP handlers that
> will be called when an IRP is sent to a particular device. I know that I
> can get a driver object related to a particular device through a call to
> IoGetDeviceObjectPointer and from there can inspect the Driver Object’s
> MajorFunction table. However, if I am clear about how the driver stack
> works in Windows there could be filter drivers attached lower in the
> device stack and references to the IRP handlers they register would not
> appear in this “top layer” MajorFunction table referenced by the
> Driver/Device Object returned by IoGetDeviceObjectPointer. Thus what I am
> really trying to do is enumerate all of the DriverObject’s and their
> respective MajorFunction tables that will be referenced when an IRP is
> sent to a particular device.
>
> My searching for a solution to this problem has suggested I investigate
> the SetupDI API. I have, and have looked at the Devcon example in the DDK
> but it wasn’t immediately clear to me that this API could yield the actual
> kernel objects associated with a device stack that I am interested in
> (DeviceObject/DriverObject/MajorFunction). It seems to me that I should
> be able to use other Windows IO Manager calls like
> IoGetDeviceObjectPointer to enumerate these objects I want, but perhaps
> not since I have looked pretty hard yet have not found them.
>
> What is the best way to do what I am trying to accomplish? Can I do it
> with Windows IO Manager calls, or is there some way to use SetupDI in a
> similar way to get access to the relevant kernel objects?
>
> Thanks a bunch for any help you can give me!
>
>

let’s say you get this info, what are you going to do with it? What are you ultimately trying to do? Anytime i see someone asking to look at another driver’s dispatch table, it is usually with the idea to verify the driver is not being hooked, but many port drivers and kmdf set the dispatch table to their own pointers outside of the driver image range.

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@gmail.com
Sent: November 04, 2010 4:45 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Programmatic Inspection of Device Driver Stack

I am trying to programmatically enumerate all of the IRP handlers that will be called when an IRP is sent to a particular device. I know that I can get a driver object related to a particular device through a call to IoGetDeviceObjectPointer and from there can inspect the Driver Object’s MajorFunction table. However, if I am clear about how the driver stack works in Windows there could be filter drivers attached lower in the device stack and references to the IRP handlers they register would not appear in this “top layer” MajorFunction table referenced by the Driver/Device Object returned by IoGetDeviceObjectPointer. Thus what I am really trying to do is enumerate all of the DriverObject’s and their respective MajorFunction tables that will be referenced when an IRP is sent to a particular device.

My searching for a solution to this problem has suggested I investigate the SetupDI API. I have, and have looked at the Devcon example in the DDK but it wasn’t immediately clear to me that this API could yield the actual kernel objects associated with a device stack that I am interested in (DeviceObject/DriverObject/MajorFunction). It seems to me that I should be able to use other Windows IO Manager calls like IoGetDeviceObjectPointer to enumerate these objects I want, but perhaps not since I have looked pretty hard yet have not found them.

What is the best way to do what I am trying to accomplish? Can I do it with Windows IO Manager calls, or is there some way to use SetupDI in a similar way to get access to the relevant kernel objects?

Thanks a bunch for any help you can give me!


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> I am trying to programmatically enumerate all of the IRP handlers that will be called when an IRP

is sent to a particular device.

Can I do it with indows IO Manager calls

Correct - IoGetDeviceObjectPointer() and IoGetLowerDeviceObject() are your friends here …

or is there some way to use SetupDI in a similar way to get access to the relevant kernel objects?

SetupDI’ s relevance in this context is comparable to that of a kitchen sink…

In any case, pay a special attention to Doron’s question - unless you are able to give a reasonable answer to it there is a good chance that I am just helping you to stick wings to a pig that you want to make fly…

Anton Bassov

>IoGetDeviceObjectPointer. Thus what I am really trying to do is enumerate all of the DriverObject’s

and their respective MajorFunction tables that will be referenced when an IRP is sent to a particular
device.

IoGetAttachedDeviceReference, then walk the ->AttachedDevice chain, then ObDereferenceObject.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

let’s say you get this info, what are you going to do with it? What are you ultimately trying to do? Anytime i see someone asking to look at another driver’s dispatch table, it is usually with the idea to verify the driver is not being hooked, but many port drivers and kmdf set the dispatch table to their own pointers outside of the driver image range.

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@gmail.com
Sent: November 04, 2010 4:45 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Programmatic Inspection of Device Driver Stack

I am trying to programmatically enumerate all of the IRP handlers that will be called when an IRP is sent to a particular device. I know that I can get a driver object related to a particular device through a call to IoGetDeviceObjectPointer and from there can inspect the Driver Object’s MajorFunction table. However, if I am clear about how the driver stack works in Windows there could be filter drivers attached lower in the device stack and references to the IRP handlers they register would not appear in this “top layer” MajorFunction table referenced by the Driver/Device Object returned by IoGetDeviceObjectPointer. Thus what I am really trying to do is enumerate all of the DriverObject’s and their respective MajorFunction tables that will be referenced when an IRP is sent to a particular device.

My searching for a solution to this problem has suggested I investigate the SetupDI API. I have, and have looked at the Devcon example in the DDK but it wasn’t immediately clear to me that this API could yield the actual kernel objects associated with a device stack that I am interested in (DeviceObject/DriverObject/MajorFunction). It seems to me that I should be able to use other Windows IO Manager calls like IoGetDeviceObjectPointer to enumerate these objects I want, but perhaps not since I have looked pretty hard yet have not found them.

What is the best way to do what I am trying to accomplish? Can I do it with Windows IO Manager calls, or is there some way to use SetupDI in a similar way to get access to the relevant kernel objects?

Thanks a bunch for any help you can give me!


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> IoGetAttachedDeviceReference, then walk the ->AttachedDevice chain, then ObDereferenceObject.

This is how you do things if you are interested in the devices that are located above the target one
on the stack. However, the OP needs exactly the opposite - he wants to enumerate devices starting from the topmost one downwards…

Anton Bassov

> IoGetAttachedDeviceReference, then walk the ->AttachedDevice chain, then

ObDereferenceObject.

IoGetAttachedDeviceReference returns the top device in the stack, so walking
AttachedDevice won’t get you anything. IoGetDeviceAttachmentBaseRef gives
you the bottom device in the stack, though you still can’t touch the
AttachedDevice field. It’s an internal I/O manager field and you don’t have
the lock necessary to protect it, so you can’t protect against someone
attaching or detaching in the middle of your walk (and, yes, the lock is
exported indirectly on some versions of the O/S though that doesn’t mean you
should acquire it).

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>>IoGetDeviceObjectPointer. Thus what I am really trying to do is enumerate
>>all of the DriverObject’s
>>and their respective MajorFunction tables that will be referenced when an
>>IRP is sent to a particular
>>device.
>
> IoGetAttachedDeviceReference, then walk the ->AttachedDevice chain, then
> ObDereferenceObject.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>

>he wants to enumerate devices starting from the topmost one

You can use IoGetLowerDeviceObject for this. Though, again, the OP’s idea is
flawed so this doesn’t really help in the end.

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

wrote in message news:xxxxx@ntdev…
>> IoGetAttachedDeviceReference, then walk the ->AttachedDevice chain, then
>> ObDereferenceObject.
>
> This is how you do things if you are interested in the devices that are
> located above the target one
> on the stack. However, the OP needs exactly the opposite - he wants to
> enumerate devices starting from the topmost one downwards…
>
> Anton Bassov
>
>
>
>

> AttachedDevice field. It’s an internal I/O manager field and you don’t have

the lock necessary to protect it

Yes, but am I wrong that IoGetAttachedDeviceReference will lock the attachment chain so no sane driver wil be able to change it?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> am I wrong that IoGetAttachedDeviceReference will lock the attachment chain so no sane driver wil

be able to change it?

Just think of a situation when a new device has to be attached to the top of the stack. Do you really think IoAttachDEvice() and friends must have to wait until you release your reference??? The purpose of referencing an object is keeping it in RAM as long as someone has a reference to it. Therefore, the only thing
you can be sure about is that the target DO will stay valid, without any implications to the state of its fields, its position on the stack,etc…

Anton Bassov

>Yes, but am I wrong that IoGetAttachedDeviceReference will lock the

attachment chain so no sane driver wil be able to >change it?

As Anton noted, all that routine does is bump the Object Manager reference
count on the device object at the top of the stack *at the time of the call*
in a thread safe manner. It doesn’t prevent future operations from happening
(i.e. IoAttachDevice/IoDetachDevice don’t block until the reference count
drops to zero).

-scott


Scott Noone
Consulting Associate
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>> AttachedDevice field. It’s an internal I/O manager field and you don’t
>> have
>> the lock necessary to protect it
>
> Yes, but am I wrong that IoGetAttachedDeviceReference will lock the
> attachment chain so no sane driver wil be able to change it?
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>