SRB_FLAGS_BYPASS_LOCKED_QUEUE Question

Let’s say I want to lock the SCSI port device’s queue for exclusive access by sending SRB_FUNCTION_LOCK_QUEUE, what exactly happens if I then send multiple requests with SRB_FLAGS_BYPASS_LOCKED_QUEUE? Does the IRP still get queued using IoStartPacket, or am I responsible for ensuring DriverStartIo is called synchronously?

Bypass locked queue will cause the request to run despite the lock. Generally the queue lock is for power or recovery operations - it’s quite possible that only one request at a time is allowed (I can’t remember offhand)

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Saturday, March 14, 2015 5:39 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question

Let’s say I want to lock the SCSI port device’s queue for exclusive access by sending SRB_FUNCTION_LOCK_QUEUE, what exactly happens if I then send multiple requests with SRB_FLAGS_BYPASS_LOCKED_QUEUE? Does the IRP still get queued using IoStartPacket, or am I responsible for ensuring DriverStartIo is called synchronously?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

So, theoretically I could lock the queue and set up my own queuing system
to execute the requests one at a time? Assuming DriverStartIo blocks until
the I/O is done?

On Sun, Mar 15, 2015 at 1:29 AM, Peter Wieland
wrote:

> Bypass locked queue will cause the request to run despite the lock.
> Generally the queue lock is for power or recovery operations - it’s quite
> possible that only one request at a time is allowed (I can’t remember
> offhand)
>
> -p
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> Sent: Saturday, March 14, 2015 5:39 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question
>
> Let’s say I want to lock the SCSI port device’s queue for exclusive access
> by sending SRB_FUNCTION_LOCK_QUEUE, what exactly happens if I then send
> multiple requests with SRB_FLAGS_BYPASS_LOCKED_QUEUE? Does the IRP still
> get queued using IoStartPacket, or am I responsible for ensuring
> DriverStartIo is called synchronously?
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>

Other driver can (and do) set the flag which will result in requests being intermingled. You are not understanding what this lock is all about–it’s intended for cleaning out pending requests so the class driver can get back in a good state after a check condition has occurred. If you want to suspend SRBs from all others, you may need a filter driver to do that.

Note that this stuff - at least in some old times - was used to lock the queue on low-power Dx states.

wrote in message news:xxxxx@ntdev…
> Let’s say I want to lock the SCSI port device’s queue for exclusive access by sending SRB_FUNCTION_LOCK_QUEUE, what exactly happens if I then send multiple requests with SRB_FLAGS_BYPASS_LOCKED_QUEUE? Does the IRP still get queued using IoStartPacket, or am I responsible for ensuring DriverStartIo is called synchronously?
>

Well basically, I have 2 devices accessing the same shared port (via
IoStartPacket), but I believe that because the devices have their own
individual queues, it will still mess with the serialization of
DriverStartIo? So my assumption is I need to implement my own serialization
so that both devices don’t call DriverStartIo at the same time? Am I
correct and if so, any suggestions on how to do this? Filter driver is out
of the question, because this is a miniport.

On Sun, Mar 15, 2015 at 2:13 PM, wrote:

> Other driver can (and do) set the flag which will result in requests being
> intermingled. You are not understanding what this lock is all about–it’s
> intended for cleaning out pending requests so the class driver can get back
> in a good state after a check condition has occurred. If you want to
> suspend SRBs from all others, you may need a filter driver to do that.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>

SCSIPort, specifically, Mr. Hallard? Or are we really talking about StorPort?

Lots has changed in the land of storage… even in the past couple of OS releases StorPort has changed dramatically to meet the needs of technologies such as NVMe.

It’s not clear to me HOW… or even if… queue locking works these days. You’d have to play with it and determine its efficacy through experimentation.

To your base question:

Why is that? Could the filter not be instantiated below disk and above the device PDO?

Peter
OSR
@OSRDrivers

I think it would help you get a better answer if you take a step back and explain what type of device driver you’re building and what you’re trying to do. I’ve tried to parse the last couple of questions and they don’t make tons of sense to me. It seems like you’re probably trying to ask too narrow of a question.

For example, I don’t know if you’re trying to write a storage controller driver (like a storport or scsciport miniport) or a storage device driver (e.g. a disk). You mention there’s a miniport here but I don’t know if you’re writing that, or a driver above it.

Generally the storage controller drivers have two layers of queue within the controller driver. Each LUN has its own queue of requests, and the controller has a queue of requests. The controller decides how many requests to issue from each LUN queue into the controller queue at any given time. Generally that count is either 0 or 1. Once the active request for the LUN has been sent to the controller, the controller driver may decide to admit another request from that LUN.

In the case of SCSIPORT (which is when I last had my hands actively in this code) the LUNs issue one request at a time to the controller queue. Once the miniport has received the request, the LUN will issue another request if the previous request was a tagged command and the next request is also a tagged command, and the number of active tagged requests on the device didn’t exceed what we thought was the LUN’s limit on active tagged commands, and none of the various internal and/or SRB flags which tell us we can’t do tagged commands right now aren’t set.

SRB_FUNCTION_LOCK (or lock_queue – can’t quite remember) is intended to lock the top-level per-LUN queue. It’s used primarily during power or PNP transitions so that the disk driver can stop the flow of requests to the LUN without maintaining its own gate (adding a gate at the disk layer would introduce more interlocked instructions or spinlocks, and they’re going to be done again in the controller driver – why take the extra cost). The expectation was that the drivers in the device stack would only send these command during things like power/PNP transitions, where we could use the transition IRP as the talking-stick. Whoever owns the power IRP is allowed to decide to LOCK, then issue their bypass commands, then they hand the talking-stick to the next driver in the stack. As the talking-stick goes back up, each driver might send more commands (for power-up you do it as the Power IRP completes) and then every driver which sent a LOCK does an UNLOCK.

The purpose of the LOCK is to resolve the inherent race between steady-state IO (read/write) and the transition out of that state without introducing more kernel locks at every layer in the stack. It is not to resolve race conditions between multiple drivers trying to do some sort of state transition – you need another request to serve as the talking-stick there.

If you have multiple drivers in the stack, both sending reads and writes concurrently to the same LUN the queues in the controller driver will be fine. If you need to introduce some specific ordering between read and write requests coming through the driver stack, you will need a per-LUN lower filter driver to impose that ordering.

-p

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mike Hallard
Sent: Sunday, March 15, 2015 3:51 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question

Well basically, I have 2 devices accessing the same shared port (via IoStartPacket), but I believe that because the devices have their own individual queues, it will still mess with the serialization of DriverStartIo? So my assumption is I need to implement my own serialization so that both devices don’t call DriverStartIo at the same time? Am I correct and if so, any suggestions on how to do this? Filter driver is out of the question, because this is a miniport.

On Sun, Mar 15, 2015 at 2:13 PM, > wrote:
Other driver can (and do) set the flag which will result in requests being intermingled. You are not understanding what this lock is all about–it’s intended for cleaning out pending requests so the class driver can get back in a good state after a check condition has occurred. If you want to suspend SRBs from all others, you may need a filter driver to do that.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

— NTDEV is sponsored by OSR Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See http://www.osr.com/careers 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 did want to refrain from going into details, as what I’m doing is
probably considered bad juju, but I’ll give it a try anyway. On windows 7 I
have found a way to bypass any malicious filter drivers, object hijacking,
and inline hooks that would prevent reading of infected boot sectors: I’m
basically implementing my own storage class driver and setting up a
parallel miniport instead of risking unhooking the real one (This seems to
work flawlessly with ataport & scsiport due to their internal queuing
mechanism).

My problem here is Windows XP (Yay, backwards compatibility), which uses
IoStartPacket for queuing to the device queue. Having 2 parallel miniport
device objects on XP would mean 2 separate device queues, which would
violate the serialization of DriverStartIo; and if I queue the request to
the original miniport with IoStartPacket (passing my clean miniport’s
device object), it will work if the request is sent directly to
DriverStartIo (the queue is empty), but if it gets queued, the request is
then later processed using the original device object (which results in any
miniport hooks getting control of the request).

I know this kind of thing is usually frowned upon, but it’s just a research
tool similar to the Hidden FS Readers, aimed at easier dumping of infected
boot sectors when performing dynamic malware analysis.

On Mon, Mar 16, 2015 at 7:11 PM, Peter Wieland
wrote:

> I think it would help you get a better answer if you take a step back
> and explain what type of device driver you’re building and what you’re
> trying to do. I’ve tried to parse the last couple of questions and they
> don’t make tons of sense to me. It seems like you’re probably trying to
> ask too narrow of a question.
>
>
>
> For example, I don’t know if you’re trying to write a storage controller
> driver (like a storport or scsciport miniport) or a storage device driver
> (e.g. a disk). You mention there’s a miniport here but I don’t know if
> you’re writing that, or a driver above it.
>
>
>
> Generally the storage controller drivers have two layers of queue within
> the controller driver
. Each LUN has its own queue of requests, and the
> controller has a queue of requests. The controller decides how many
> requests to issue from each LUN queue into the controller queue at any
> given time. Generally that count is either 0 or 1. Once the active
> request for the LUN has been sent to the controller, the controller driver
> may decide to admit another request from that LUN.
>
>
>
> In the case of SCSIPORT (which is when I last had my hands actively in
> this code) the LUNs issue one request at a time to the controller queue.
> Once the miniport has received the request, the LUN will issue another
> request if the previous request was a tagged command and the next request
> is also a tagged command, and the number of active tagged requests on the
> device didn’t exceed what we thought was the LUN’s limit on active tagged
> commands, and none of the various internal and/or SRB flags which tell us
> we can’t do tagged commands right now aren’t set.
>
>
>
> SRB_FUNCTION_LOCK (or lock_queue – can’t quite remember) is intended to
> lock the top-level per-LUN queue. It’s used primarily during power or PNP
> transitions so that the disk driver can stop the flow of requests to the
> LUN without maintaining its own gate (adding a gate at the disk layer would
> introduce more interlocked instructions or spinlocks, and they’re going to
> be done again in the controller driver – why take the extra cost). The
> expectation was that the drivers in the device stack would only send these
> command during things like power/PNP transitions, where we could use the
> transition IRP as the talking-stick. Whoever owns the power IRP is allowed
> to decide to LOCK, then issue their bypass commands, then they hand the
> talking-stick to the next driver in the stack. As the talking-stick goes
> back up, each driver might send more commands (for power-up you do it as
> the Power IRP completes) and then every driver which sent a LOCK does an
> UNLOCK.
>
>
>
> The purpose of the LOCK is to resolve the inherent race between
> steady-state IO (read/write) and the transition out of that state without
> introducing more kernel locks at every layer in the stack. It is not to
> resolve race conditions between multiple drivers trying to do some sort of
> state transition – you need another request to serve as the talking-stick
> there.
>
>
>
> If you have multiple drivers in the stack, both sending reads and writes
> concurrently to the same LUN the queues in the controller driver will be
> fine. If you need to introduce some specific ordering between read and
> write requests coming through the driver stack, you will need a per-LUN
> lower filter driver to impose that ordering.
>
>
>
> -p
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Mike Hallard
> Sent: Sunday, March 15, 2015 3:51 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question
>
>
>
> Well basically, I have 2 devices accessing the same shared port (via
> IoStartPacket), but I believe that because the devices have their own
> individual queues, it will still mess with the serialization of
> DriverStartIo? So my assumption is I need to implement my own serialization
> so that both devices don’t call DriverStartIo at the same time? Am I
> correct and if so, any suggestions on how to do this? Filter driver is out
> of the question, because this is a miniport.
>
>
>
> On Sun, Mar 15, 2015 at 2:13 PM, wrote:
>
> Other driver can (and do) set the flag which will result in requests being
> intermingled. You are not understanding what this lock is all about–it’s
> intended for cleaning out pending requests so the class driver can get back
> in a good state after a check condition has occurred. If you want to
> suspend SRBs from all others, you may need a filter driver to do that.
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>
>
>
> — NTDEV is sponsored by OSR Visit the list at:
> http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See
> http://www.osr.com/careers 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
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>

LOCK won’t help you here – it works at the LUN level and not at the controller level.

If you can assume that the malware hasn’t infected the controller driver and/or miniport then you could probably achieve your hackery by calling IoCallDriver and giving it a pointer to the PDO for the storage device. IIRC the port drivers don’t allow filters at the controller level (the IRPs are moved directly between LUN and controller queue in SCSIPORT, and I suspect ATAPORT and STORPORT behave the same).

Reaching inside a device driver to poke at its private parts is not going to be stable. That it works is awesome hackery – that it breaks elsewhere is not surprising.

-p

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mike Hallard
Sent: Monday, March 16, 2015 1:09 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question

I did want to refrain from going into details, as what I’m doing is probably considered bad juju, but I’ll give it a try anyway. On windows 7 I have found a way to bypass any malicious filter drivers, object hijacking, and inline hooks that would prevent reading of infected boot sectors: I’m basically implementing my own storage class driver and setting up a parallel miniport instead of risking unhooking the real one (This seems to work flawlessly with ataport & scsiport due to their internal queuing mechanism).

My problem here is Windows XP (Yay, backwards compatibility), which uses IoStartPacket for queuing to the device queue. Having 2 parallel miniport device objects on XP would mean 2 separate device queues, which would violate the serialization of DriverStartIo; and if I queue the request to the original miniport with IoStartPacket (passing my clean miniport’s device object), it will work if the request is sent directly to DriverStartIo (the queue is empty), but if it gets queued, the request is then later processed using the original device object (which results in any miniport hooks getting control of the request).

I know this kind of thing is usually frowned upon, but it’s just a research tool similar to the Hidden FS Readers, aimed at easier dumping of infected boot sectors when performing dynamic malware analysis.

On Mon, Mar 16, 2015 at 7:11 PM, Peter Wieland > wrote:
I think it would help you get a better answer if you take a step back and explain what type of device driver you’re building and what you’re trying to do. I’ve tried to parse the last couple of questions and they don’t make tons of sense to me. It seems like you’re probably trying to ask too narrow of a question.

For example, I don’t know if you’re trying to write a storage controller driver (like a storport or scsciport miniport) or a storage device driver (e.g. a disk). You mention there’s a miniport here but I don’t know if you’re writing that, or a driver above it.

Generally the storage controller drivers have two layers of queue within the controller driver. Each LUN has its own queue of requests, and the controller has a queue of requests. The controller decides how many requests to issue from each LUN queue into the controller queue at any given time. Generally that count is either 0 or 1. Once the active request for the LUN has been sent to the controller, the controller driver may decide to admit another request from that LUN.

In the case of SCSIPORT (which is when I last had my hands actively in this code) the LUNs issue one request at a time to the controller queue. Once the miniport has received the request, the LUN will issue another request if the previous request was a tagged command and the next request is also a tagged command, and the number of active tagged requests on the device didn’t exceed what we thought was the LUN’s limit on active tagged commands, and none of the various internal and/or SRB flags which tell us we can’t do tagged commands right now aren’t set.

SRB_FUNCTION_LOCK (or lock_queue – can’t quite remember) is intended to lock the top-level per-LUN queue. It’s used primarily during power or PNP transitions so that the disk driver can stop the flow of requests to the LUN without maintaining its own gate (adding a gate at the disk layer would introduce more interlocked instructions or spinlocks, and they’re going to be done again in the controller driver – why take the extra cost). The expectation was that the drivers in the device stack would only send these command during things like power/PNP transitions, where we could use the transition IRP as the talking-stick. Whoever owns the power IRP is allowed to decide to LOCK, then issue their bypass commands, then they hand the talking-stick to the next driver in the stack. As the talking-stick goes back up, each driver might send more commands (for power-up you do it as the Power IRP completes) and then every driver which sent a LOCK does an UNLOCK.

The purpose of the LOCK is to resolve the inherent race between steady-state IO (read/write) and the transition out of that state without introducing more kernel locks at every layer in the stack. It is not to resolve race conditions between multiple drivers trying to do some sort of state transition – you need another request to serve as the talking-stick there.

If you have multiple drivers in the stack, both sending reads and writes concurrently to the same LUN the queues in the controller driver will be fine. If you need to introduce some specific ordering between read and write requests coming through the driver stack, you will need a per-LUN lower filter driver to impose that ordering.

-p

From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.commailto:xxxxx] On Behalf Of Mike Hallard
Sent: Sunday, March 15, 2015 3:51 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question

Well basically, I have 2 devices accessing the same shared port (via IoStartPacket), but I believe that because the devices have their own individual queues, it will still mess with the serialization of DriverStartIo? So my assumption is I need to implement my own serialization so that both devices don’t call DriverStartIo at the same time? Am I correct and if so, any suggestions on how to do this? Filter driver is out of the question, because this is a miniport.

On Sun, Mar 15, 2015 at 2:13 PM, > wrote:
Other driver can (and do) set the flag which will result in requests being intermingled. You are not understanding what this lock is all about–it’s intended for cleaning out pending requests so the class driver can get back in a good state after a check condition has occurred. If you want to suspend SRBs from all others, you may need a filter driver to do that.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

— NTDEV is sponsored by OSR Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See http://www.osr.com/careers 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


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

— NTDEV is sponsored by OSR Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See http://www.osr.com/careers 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</mailto:xxxxx></mailto:xxxxx>

>Is backwards compatibility a major issue for a research tool?
Not major, but I quite enjoy the challenge. It’s also still common for
researchers to use XP virtual machines as they’re a little easier on
resources. I’m not to sure about how the request is handled at the
controller level, but I’ll do some tests to see if it’s possible to
disregard miniport level serialization.

LOCK won’t help you here – it works at the LUN level and not at the
controller level.

If you can assume that the malware hasn’t infected the controller driver
and/or miniport then you could probably achieve your hackery by calling
IoCallDriver and giving it a pointer to the PDO for the storage device.
IIRC the port drivers don’t allow filters at the controller level (the IRPs
are moved directly between LUN and controller queue in SCSIPORT, and I
suspect ATAPORT and STORPORT behave the same).

Reaching inside a device driver to poke at its private parts is not going
to be stable. That it works is awesome hackery – that it breaks elsewhere
is not surprising.

I don’t need to assume the miniport isn’t hooked as I have ways to bypass
hooking on both the miniport and port drivers (this was the primary goal
because lots of modern malware hooks those), the controller is a whole
different story, but because it’s hardware specific, I doubt anyone is
going to go to the effort of coming up with a hardware independent way to
hook that.

What I’m doing is similar to what you suggested, except I’m copying the PDO
for the storage device and replacing the driver object pointer with one
which bypasses IRP_MJ inline/pointer hooks. It’s a major hack, but it
appears to be incredibly reliable as long as the system makes use of the
system supplied port drives (I’m only supporting these systems anyway).

I know it’s hacks, hacks, and more hacks, but I’ve worked on making it as
robust as possible and so far so good (Windows Vista+). I know the
controller does a lot of synchronization, but XP uses atapi.sys as both the
port and miniport driver, and I’m not sure if can send non-serialized
requests to the port PDO without the system imploding.

On Tue, Mar 17, 2015 at 12:49 AM, Peter Wieland
wrote:

> LOCK won’t help you here – it works at the LUN level and not at the
> controller level.
>
>
>
> If you can assume that the malware hasn’t infected the controller driver
> and/or miniport then you could probably achieve your hackery by calling
> IoCallDriver and giving it a pointer to the PDO for the storage device.
> IIRC the port drivers don’t allow filters at the controller level (the IRPs
> are moved directly between LUN and controller queue in SCSIPORT, and I
> suspect ATAPORT and STORPORT behave the same).
>
>
>
> Reaching inside a device driver to poke at its private parts is not going
> to be stable. That it works is awesome hackery – that it breaks elsewhere
> is not surprising.
>
>
>
> -p
>
>
>
>
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Mike Hallard
> Sent: Monday, March 16, 2015 1:09 PM
>
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question
>
>
>
> I did want to refrain from going into details, as what I’m doing is
> probably considered bad juju, but I’ll give it a try anyway. On windows 7 I
> have found a way to bypass any malicious filter drivers, object hijacking,
> and inline hooks that would prevent reading of infected boot sectors: I’m
> basically implementing my own storage class driver and setting up a
> parallel miniport instead of risking unhooking the real one (This seems to
> work flawlessly with ataport & scsiport due to their internal queuing
> mechanism).
>
>
>
> My problem here is Windows XP (Yay, backwards compatibility), which uses
> IoStartPacket for queuing to the device queue. Having 2 parallel miniport
> device objects on XP would mean 2 separate device queues, which would
> violate the serialization of DriverStartIo; and if I queue the request to
> the original miniport with IoStartPacket (passing my clean miniport’s
> device object), it will work if the request is sent directly to
> DriverStartIo (the queue is empty), but if it gets queued, the request is
> then later processed using the original device object (which results in any
> miniport hooks getting control of the request).
>
>
>
> I know this kind of thing is usually frowned upon, but it’s just a
> research tool similar to the Hidden FS Readers, aimed at easier dumping of
> infected boot sectors when performing dynamic malware analysis.
>
>
>
> On Mon, Mar 16, 2015 at 7:11 PM, Peter Wieland
> wrote:
>
> I think it would help you get a better answer if you take a step back
> and explain what type of device driver you’re building and what you’re
> trying to do. I’ve tried to parse the last couple of questions and they
> don’t make tons of sense to me. It seems like you’re probably trying to
> ask too narrow of a question.
>
>
>
> For example, I don’t know if you’re trying to write a storage controller
> driver (like a storport or scsciport miniport) or a storage device driver
> (e.g. a disk). You mention there’s a miniport here but I don’t know if
> you’re writing that, or a driver above it.
>
>
>
> Generally the storage controller drivers have two layers of queue within
> the controller driver
. Each LUN has its own queue of requests, and the
> controller has a queue of requests. The controller decides how many
> requests to issue from each LUN queue into the controller queue at any
> given time. Generally that count is either 0 or 1. Once the active
> request for the LUN has been sent to the controller, the controller driver
> may decide to admit another request from that LUN.
>
>
>
> In the case of SCSIPORT (which is when I last had my hands actively in
> this code) the LUNs issue one request at a time to the controller queue.
> Once the miniport has received the request, the LUN will issue another
> request if the previous request was a tagged command and the next request
> is also a tagged command, and the number of active tagged requests on the
> device didn’t exceed what we thought was the LUN’s limit on active tagged
> commands, and none of the various internal and/or SRB flags which tell us
> we can’t do tagged commands right now aren’t set.
>
>
>
> SRB_FUNCTION_LOCK (or lock_queue – can’t quite remember) is intended to
> lock the top-level per-LUN queue. It’s used primarily during power or PNP
> transitions so that the disk driver can stop the flow of requests to the
> LUN without maintaining its own gate (adding a gate at the disk layer would
> introduce more interlocked instructions or spinlocks, and they’re going to
> be done again in the controller driver – why take the extra cost). The
> expectation was that the drivers in the device stack would only send these
> command during things like power/PNP transitions, where we could use the
> transition IRP as the talking-stick. Whoever owns the power IRP is allowed
> to decide to LOCK, then issue their bypass commands, then they hand the
> talking-stick to the next driver in the stack. As the talking-stick goes
> back up, each driver might send more commands (for power-up you do it as
> the Power IRP completes) and then every driver which sent a LOCK does an
> UNLOCK.
>
>
>
> The purpose of the LOCK is to resolve the inherent race between
> steady-state IO (read/write) and the transition out of that state without
> introducing more kernel locks at every layer in the stack. It is not to
> resolve race conditions between multiple drivers trying to do some sort of
> state transition – you need another request to serve as the talking-stick
> there.
>
>
>
> If you have multiple drivers in the stack, both sending reads and writes
> concurrently to the same LUN the queues in the controller driver will be
> fine. If you need to introduce some specific ordering between read and
> write requests coming through the driver stack, you will need a per-LUN
> lower filter driver to impose that ordering.
>
>
>
> -p
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Mike Hallard
> Sent: Sunday, March 15, 2015 3:51 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] SRB_FLAGS_BYPASS_LOCKED_QUEUE Question
>
>
>
> Well basically, I have 2 devices accessing the same shared port (via
> IoStartPacket), but I believe that because the devices have their own
> individual queues, it will still mess with the serialization of
> DriverStartIo? So my assumption is I need to implement my own serialization
> so that both devices don’t call DriverStartIo at the same time? Am I
> correct and if so, any suggestions on how to do this? Filter driver is out
> of the question, because this is a miniport.
>
>
>
> On Sun, Mar 15, 2015 at 2:13 PM, wrote:
>
> Other driver can (and do) set the flag which will result in requests being
> intermingled. You are not understanding what this lock is all about–it’s
> intended for cleaning out pending requests so the class driver can get back
> in a good state after a check condition has occurred. If you want to
> suspend SRBs from all others, you may need a filter driver to do that.
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>
>
>
> — NTDEV is sponsored by OSR Visit the list at:
> http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See
> http://www.osr.com/careers 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
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>
>
>
> — NTDEV is sponsored by OSR Visit the list at:
> http://www.osronline.com/showlists.cfm?list=ntdev OSR is HIRING!! See
> http://www.osr.com/careers 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
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>